Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define NODE_VERSION 2.01
00038
00039 #include <ros/ros.h>
00040 #include <tf/transform_broadcaster.h>
00041 #include <nav_msgs/Odometry.h>
00042 #include <geometry_msgs/Twist.h>
00043
00044 #include "roomba_500_series/OpenInterface.h"
00045
00046 #include <string>
00047
00048 std::string port;
00049 irobot::OpenInterface * roomba;
00050
00051
00052 std::string prefixTopic(std::string prefix, char * name)
00053 {
00054 std::string topic_name = prefix;
00055 topic_name.append(name);
00056
00057 return topic_name;
00058 }
00059
00060 void cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
00061 {
00062 roomba->drive(cmd_vel->linear.x, cmd_vel->angular.z);
00063 }
00064
00065
00066 int main(int argc, char** argv)
00067 {
00068 ros::init(argc, argv, "roomba560_light_node");
00069
00070 ROS_INFO("Roomba for ROS %.2f", NODE_VERSION);
00071
00072 double last_x, last_y, last_yaw;
00073 double vel_x, vel_y, vel_yaw;
00074 double dt;
00075
00076 ros::NodeHandle n;
00077
00078 n.param<std::string>("roomba/port", port, "/dev/ttyUSB0");
00079
00080 roomba = new irobot::OpenInterface(port.c_str());
00081
00082 ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("/odom", 50);
00083 tf::TransformBroadcaster odom_broadcaster;
00084 ros::Subscriber cmd_vel_sub = n.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, cmdVelReceived);
00085
00086 if( roomba->openSerialPort(true) == 0) ROS_INFO("Connected to Roomba.");
00087 else
00088 {
00089 ROS_FATAL("Could not connect to Roomba.");
00090 ROS_BREAK();
00091 }
00092
00093 ros::Time current_time, last_time;
00094 current_time = ros::Time::now();
00095 last_time = ros::Time::now();
00096
00097
00098
00099
00100 ros::Rate r(10.0);
00101 while(n.ok())
00102 {
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 current_time = ros::Time::now();
00118
00119 last_x = roomba->odometry_x_;
00120 last_y = roomba->odometry_y_;
00121 last_yaw = roomba->odometry_yaw_;
00122
00123 if( roomba->getSensorPackets(100) == -1) ROS_ERROR("Could not retrieve sensor packets.");
00124 else roomba->calculateOdometry();
00125
00126 dt = (current_time - last_time).toSec();
00127 vel_x = (roomba->odometry_x_ - last_x)/dt;
00128 vel_y = (roomba->odometry_y_ - last_y)/dt;
00129 vel_yaw = (roomba->odometry_yaw_ - last_yaw)/dt;
00130
00131
00132 geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(roomba->odometry_yaw_);
00133
00134
00135 geometry_msgs::TransformStamped odom_trans;
00136 odom_trans.header.stamp = current_time;
00137 odom_trans.header.frame_id = "odom";
00138 odom_trans.child_frame_id = "base_link";
00139
00140 odom_trans.transform.translation.x = roomba->odometry_x_;
00141 odom_trans.transform.translation.y = roomba->odometry_y_;
00142 odom_trans.transform.translation.z = 0.0;
00143 odom_trans.transform.rotation = odom_quat;
00144
00145
00146 odom_broadcaster.sendTransform(odom_trans);
00147
00148
00149 nav_msgs::Odometry odom;
00150 odom.header.stamp = current_time;
00151 odom.header.frame_id = "odom";
00152
00153
00154 odom.pose.pose.position.x = roomba->odometry_x_;
00155 odom.pose.pose.position.y = roomba->odometry_y_;
00156 odom.pose.pose.position.z = 0.0;
00157 odom.pose.pose.orientation = odom_quat;
00158
00159
00160 odom.child_frame_id = "base_link";
00161 odom.twist.twist.linear.x = vel_x;
00162 odom.twist.twist.linear.y = vel_y;
00163 odom.twist.twist.angular.z = vel_yaw;
00164
00165
00166 odom_pub.publish(odom);
00167
00168 ros::spinOnce();
00169 r.sleep();
00170 }
00171
00172 roomba->powerDown();
00173 roomba->closeSerialPort();
00174 }
00175
00176