├── README.md ├── arduino_encoder └── arduino_encoder.ino └── encoder_odometry ├── CMakeLists.txt ├── README.md ├── launch ├── display.launch └── final.launch ├── package.xml ├── robot1.urdf └── src └── odometry.cpp /README.md: -------------------------------------------------------------------------------- 1 | # encoder-odometry 2 | Pose calculation using wheel encoder data, 3 | -------------------------------------------------------------------------------- /arduino_encoder/arduino_encoder.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ros::NodeHandle nh; 5 | geometry_msgs::Vector3 data; 6 | ros::Publisher pos("pos",&data); 7 | 8 | long left_count=0, right_count=0; 9 | 10 | void setup() 11 | { 12 | Serial.begin(57600); 13 | nh.initNode(); 14 | nh.advertise(pos); 15 | attachInterrupt(0,isr_right,FALLING); 16 | attachInterrupt(1,isr_left,FALLING); 17 | pinMode(11,OUTPUT); 18 | } 19 | 20 | 21 | void loop() 22 | { 23 | digitalWrite(11,HIGH); 24 | data.x=left_count; 25 | data.y=right_count; 26 | Serial.print("right: "); Serial.print(right_count); Serial.print("left: "); Serial.println(left_count); 27 | pos.publish(&data); 28 | nh.spinOnce(); 29 | delay(2); 30 | } 31 | 32 | void isr_right() 33 | { 34 | right_count++; 35 | } 36 | 37 | void isr_left() 38 | { 39 | left_count++; 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /encoder_odometry/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(encoder_odometry) 3 | 4 | find_package(catkin REQUIRED COMPONENTS 5 | tf 6 | geometry_msgs 7 | nav_msgs 8 | roscpp 9 | rospy 10 | std_msgs 11 | ) 12 | 13 | 14 | catkin_package() 15 | 16 | ########### 17 | ## Build ## 18 | ########### 19 | 20 | ## Specify additional locations of header files 21 | ## Your package locations should be listed before other locations 22 | # include_directories(include) 23 | include_directories( 24 | ${catkin_INCLUDE_DIRS} 25 | ) 26 | 27 | ## Declare a C++ library 28 | # add_library(encoder_odometry 29 | # src/${PROJECT_NAME}/encoder_odometry.cpp 30 | # ) 31 | 32 | ## Add cmake target dependencies of the library 33 | ## as an example, code may need to be generated before libraries 34 | ## either from message generation or dynamic reconfigure 35 | # add_dependencies(encoder_odometry ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 36 | 37 | ## Declare a C++ executable 38 | add_executable(odometry src/odometry.cpp) 39 | target_link_libraries(odometry 40 | ${catkin_LIBRARIES} 41 | ) 42 | 43 | -------------------------------------------------------------------------------- /encoder_odometry/README.md: -------------------------------------------------------------------------------- 1 | ROS node to calculate pose of the robot. 2 | 3 | Subscribes to the 'pos' topic published by the arduino. 4 | -------------------------------------------------------------------------------- /encoder_odometry/launch/display.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /encoder_odometry/launch/final.launch: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /encoder_odometry/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | encoder_odometry 4 | 0.0.0 5 | The encoder_odometry package 6 | 7 | 8 | 9 | 10 | rohan 11 | 12 | 13 | 14 | 15 | 16 | TODO 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | catkin 43 | roscpp 44 | rospy 45 | std_msgs 46 | roscpp 47 | rospy 48 | std_msgs 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /encoder_odometry/robot1.urdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /encoder_odometry/src/odometry.cpp: -------------------------------------------------------------------------------- 1 | #include "ros/ros.h" 2 | #include 3 | #include 4 | #include 5 | 6 | long _PreviousLeftEncoderCounts = 0; 7 | long _PreviousRightEncoderCounts = 0; 8 | ros::Time current_time, last_time; 9 | double DistancePerCount = (3.14159265 * 0.1)/30; //the wheel diameter is 0.1m 10 | //final odometric datas 11 | double x; 12 | double y; 13 | double th; 14 | double v_left;//left motor speed 15 | double v_right;//right motor speed 16 | double vth;//angular velocity of robot 17 | double deltaLeft;//no of ticks in left encoder since last update 18 | double deltaRight;//no of ticks in right encoder since last update 19 | double dt; 20 | double delta_distance;//distance moved by robot since last update 21 | double delta_th;//corresponging change in heading 22 | double delta_x ;//corresponding change in x direction 23 | double delta_y;//corresponding change in y direction 24 | #define PI 3.14159265 25 | #define TwoPI 6.28318531 26 | 27 | 28 | void WheelCallback(const geometry_msgs::Vector3::ConstPtr& ticks) 29 | { 30 | current_time = ros::Time::now(); 31 | deltaLeft = ticks->x - _PreviousLeftEncoderCounts; 32 | deltaRight = ticks->y - _PreviousRightEncoderCounts; 33 | dt = (current_time - last_time).toSec(); 34 | v_left = deltaLeft * DistancePerCount/dt; 35 | v_right = deltaRight * DistancePerCount/dt; 36 | delta_distance=0.5f*(double)(deltaLeft+deltaRight)*DistancePerCount; 37 | delta_th = (double)(deltaRight-deltaLeft)*DistancePerCount/0.36f; //Distance between the two wheels is 0.36m 38 | delta_x = delta_distance*(double)cos(th); 39 | delta_y = delta_distance*(double)sin(th); 40 | x += delta_x; 41 | y += delta_y; 42 | th += delta_th; 43 | if (th > PI) 44 | th -= TwoPI; 45 | else 46 | if ( th <= -PI) 47 | th += TwoPI; 48 | _PreviousLeftEncoderCounts = ticks->x; 49 | _PreviousRightEncoderCounts = ticks->y; 50 | last_time = current_time; 51 | } 52 | 53 | 54 | int main(int argc, char **argv) 55 | { 56 | ros::init(argc, argv, "odometry_publisher"); 57 | ros::NodeHandle n; 58 | ros::Subscriber sub = n.subscribe("pos", 100, WheelCallback); 59 | ros::Publisher odom_pub = n.advertise("odom", 50); 60 | tf::TransformBroadcaster odom_broadcaster; 61 | ros::Rate r(40); 62 | 63 | while(n.ok()){ 64 | //since all odometry is 6DOF we'll need a quaternion created from yaw 65 | geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th); 66 | //first, we'll publish the transform over tf 67 | geometry_msgs::TransformStamped odom_trans; 68 | odom_trans.header.stamp = current_time; 69 | odom_trans.header.frame_id = "odom"; 70 | odom_trans.child_frame_id = "base_link"; 71 | odom_trans.transform.translation.x = x; 72 | odom_trans.transform.translation.y = y; 73 | odom_trans.transform.translation.z = 0.0; 74 | odom_trans.transform.rotation = odom_quat; 75 | //send the transform 76 | odom_broadcaster.sendTransform(odom_trans); 77 | //next, we'll publish the odometry message over ROS 78 | nav_msgs::Odometry odom; 79 | odom.header.stamp = current_time; 80 | odom.header.frame_id = "odom"; 81 | //set the position 82 | odom.pose.pose.position.x = x; 83 | odom.pose.pose.position.y = y; 84 | odom.pose.pose.position.z = 0.0; 85 | odom.pose.pose.orientation = odom_quat; 86 | //set the velocity 87 | odom.child_frame_id = "base_link"; 88 | odom.twist.twist.linear.x=delta_x/dt; 89 | odom.twist.twist.linear.y=delta_y/dt; 90 | odom.twist.twist.angular.z = delta_th/dt; 91 | 92 | ROS_INFO("Position x = %d and Position y = %d ",x,y); 93 | 94 | //publish the message 95 | odom_pub.publish(odom); 96 | last_time = current_time; 97 | ros::spinOnce(); 98 | r.sleep(); 99 | } 100 | } 101 | --------------------------------------------------------------------------------