Go to the documentation of this file.00001 #include <string>
00002 #include <ros/ros.h>
00003 #include <tf/transform_broadcaster.h>
00004 #include <rflex/atrvjr_driver.h>
00005 #include <std_msgs/Bool.h>
00006 #include <std_msgs/Float32.h>
00007 #include <sensor_msgs/JointState.h>
00008 #include <geometry_msgs/Twist.h>
00009 #include <sensor_msgs/PointCloud.h>
00010 #include <nav_msgs/Odometry.h>
00011 #include <angles/angles.h>
00012
00033 class ATRVJRNode {
00034 private:
00035 ATRVJR driver;
00036
00037 ros::Subscriber subs[4];
00038 ros::Publisher base_sonar_pub;
00039 ros::Publisher body_sonar_pub;
00040 ros::Publisher voltage_pub;
00041 ros::Publisher brake_power_pub;
00042 ros::Publisher sonar_power_pub;
00043 ros::Publisher odom_pub;
00044 ros::Publisher plugged_pub;
00045 ros::Publisher joint_pub;
00046 ros::Publisher bump_pub;
00047 tf::TransformBroadcaster broadcaster;
00048
00049 bool isSonarOn, isBrakeOn;
00050 float acceleration;
00051 float last_distance, last_bearing;
00052 float x_odo, y_odo, a_odo;
00053 float cmdTranslation, cmdRotation;
00054 bool brake_dirty, sonar_dirty;
00055 bool initialized;
00056 float first_bearing;
00057 int updateTimer;
00058 int prev_bumps;
00059 bool sonar_just_on;
00060
00061 void publishOdometry();
00062 void publishSonar();
00063 void publishBumps();
00064
00065 public:
00066 ros::NodeHandle n;
00067 ATRVJRNode();
00068 ~ATRVJRNode();
00069 int initialize(const char* port);
00070 void spinOnce();
00071
00072
00073 void NewCommand (const geometry_msgs::Twist::ConstPtr& msg);
00074 void SetAcceleration (const std_msgs::Float32 ::ConstPtr& msg);
00075 void ToggleSonarPower(const std_msgs::Bool ::ConstPtr& msg);
00076 void ToggleBrakePower(const std_msgs::Bool ::ConstPtr& msg);
00077 };
00078
00079 ATRVJRNode::ATRVJRNode() : n ("~") {
00080 isSonarOn = isBrakeOn = false;
00081 brake_dirty = sonar_dirty = false;
00082 sonar_just_on = false;
00083 cmdTranslation = cmdRotation = 0.0;
00084 updateTimer = 99;
00085 initialized = false;
00086 prev_bumps = 0;
00087 subs[0] = n.subscribe<geometry_msgs::Twist>("cmd_vel", 1, &ATRVJRNode::NewCommand, this);
00088 subs[1] = n.subscribe<std_msgs::Float32>("cmd_accel", 1, &ATRVJRNode::SetAcceleration, this);
00089 subs[2] = n.subscribe<std_msgs::Bool>("cmd_sonar_power", 1, &ATRVJRNode::ToggleSonarPower, this);
00090 subs[3] = n.subscribe<std_msgs::Bool>("cmd_brake_power", 1, &ATRVJRNode::ToggleBrakePower, this);
00091 acceleration = 0.7;
00092
00093 base_sonar_pub = n.advertise<sensor_msgs::PointCloud>("sonar_cloud_base", 50);
00094 body_sonar_pub = n.advertise<sensor_msgs::PointCloud>("sonar_cloud_body", 50);
00095 sonar_power_pub = n.advertise<std_msgs::Bool>("sonar_power", 1);
00096 brake_power_pub = n.advertise<std_msgs::Bool>("brake_power", 1);
00097 voltage_pub = n.advertise<std_msgs::Float32>("voltage", 1);
00098 odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
00099 plugged_pub = n.advertise<std_msgs::Bool>("plugged_in", 1);
00100 joint_pub = n.advertise<sensor_msgs::JointState>("state", 1);
00101 bump_pub = n.advertise<sensor_msgs::PointCloud>("bump", 5);
00102 }
00103
00104 int ATRVJRNode::initialize(const char* port) {
00105 int ret = driver.initialize(port);
00106 if (ret < 0)
00107 return ret;
00108
00109 driver.setOdometryPeriod (100000);
00110 driver.setDigitalIoPeriod(100000);
00111 driver.motionSetDefaults();
00112 return 0;
00113 }
00114
00115 ATRVJRNode::~ATRVJRNode() {
00116 driver.motionSetDefaults();
00117 driver.setOdometryPeriod(0);
00118 driver.setDigitalIoPeriod(0);
00119 driver.setSonarPower(false);
00120 driver.setIrPower(false);
00121 }
00122
00124 void ATRVJRNode::NewCommand(const geometry_msgs::Twist::ConstPtr& msg) {
00125 cmdTranslation = msg->linear.x;
00126 cmdRotation = msg->angular.z;
00127 }
00128
00130 void ATRVJRNode::SetAcceleration (const std_msgs::Float32::ConstPtr& msg) {
00131 acceleration = msg->data;
00132 }
00133
00135 void ATRVJRNode::ToggleSonarPower(const std_msgs::Bool::ConstPtr& msg) {
00136 isSonarOn=msg->data;
00137 sonar_dirty = true;
00138 }
00139
00141 void ATRVJRNode::ToggleBrakePower(const std_msgs::Bool::ConstPtr& msg) {
00142 isBrakeOn = msg->data;
00143 brake_dirty = true;
00144 }
00145
00146 void ATRVJRNode::spinOnce() {
00147
00148 if (updateTimer>=100) {
00149 driver.sendSystemStatusCommand();
00150 updateTimer = 0;
00151 }
00152 updateTimer++;
00153
00154 if (cmdTranslation != 0 || cmdRotation != 0)
00155 driver.setMovement(cmdTranslation, cmdRotation, acceleration);
00156
00157 if (sonar_dirty) {
00158 driver.setSonarPower(isSonarOn);
00159 sonar_dirty = false;
00160 driver.sendSystemStatusCommand();
00161 }
00162 if (brake_dirty) {
00163 driver.setBrakePower(isBrakeOn);
00164 brake_dirty = false;
00165 updateTimer = 99;
00166 }
00167
00168 std_msgs::Bool bmsg;
00169 bmsg.data = isSonarOn;
00170 sonar_power_pub.publish(bmsg);
00171 bmsg.data = driver.getBrakePower();
00172 brake_power_pub.publish(bmsg);
00173 bmsg.data = driver.isPluggedIn();
00174 plugged_pub.publish(bmsg);
00175 std_msgs::Float32 vmsg;
00176 vmsg.data = driver.getVoltage();
00177 voltage_pub.publish(vmsg);
00178
00179 publishOdometry();
00180 publishSonar();
00181 publishBumps();
00182 }
00183
00186 void ATRVJRNode::publishOdometry() {
00187 if (!driver.isOdomReady()) {
00188 return;
00189 }
00190
00191 float distance = driver.getDistance();
00192 float true_bearing = angles::normalize_angle(driver.getBearing());
00193
00194 if (!initialized) {
00195 initialized = true;
00196 first_bearing = true_bearing;
00197 x_odo = 0;
00198 y_odo = 0;
00199 a_odo = 0*true_bearing;
00200 } else {
00201 float bearing = true_bearing - first_bearing;
00202 float d_dist = distance-last_distance;
00203 float d_bearing = bearing - last_bearing;
00204
00205 if (d_dist > 50 || d_dist < -50)
00206 return;
00207
00208 a_odo += d_bearing;
00209 a_odo = angles::normalize_angle(a_odo);
00210
00211
00212 x_odo += d_dist * cos(a_odo);
00213 y_odo += d_dist * sin(a_odo);
00214 }
00215 last_distance = distance;
00216 last_bearing = true_bearing - first_bearing;
00217
00218
00219 geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(last_bearing);
00220
00221
00222 geometry_msgs::TransformStamped odom_trans;
00223 odom_trans.header.stamp = ros::Time::now();
00224 odom_trans.header.frame_id = "odom";
00225 odom_trans.child_frame_id = "base_link";
00226
00227 odom_trans.transform.translation.x = x_odo;
00228 odom_trans.transform.translation.y = y_odo;
00229 odom_trans.transform.rotation = odom_quat;
00230
00231
00232 broadcaster.sendTransform(odom_trans);
00233
00234
00235 nav_msgs::Odometry odom;
00236 odom.header.stamp = ros::Time::now();
00237 odom.header.frame_id = "odom";
00238
00239
00240 odom.pose.pose.position.x = x_odo;
00241 odom.pose.pose.position.y = y_odo;
00242 odom.pose.pose.orientation = odom_quat;
00243
00244
00245 odom.child_frame_id = "base_link";
00246 float tvel = driver.getTranslationalVelocity();
00247 odom.twist.twist.linear.x = tvel*cos(a_odo);
00248 odom.twist.twist.linear.y = tvel*sin(a_odo);
00249 odom.twist.twist.angular.z = driver.getRotationalVelocity();
00250
00251
00252 odom_pub.publish(odom);
00253
00254
00255 sensor_msgs::JointState joint_state;
00256 joint_state.header.stamp = ros::Time::now();
00257 joint_state.name.resize(1);
00258 joint_state.position.resize(1);
00259 joint_state.name[0] = "lewis_twist";
00260 joint_state.position[0] = true_bearing;
00261
00262 joint_pub.publish(joint_state);
00263
00264 }
00265
00266 void ATRVJRNode::publishSonar() {
00267 sensor_msgs::PointCloud cloud;
00268 cloud.header.stamp = ros::Time::now();
00269 cloud.header.frame_id = "base_link";
00270
00271 if (isSonarOn) {
00272 driver.getBaseSonarPoints(&cloud);
00273 base_sonar_pub.publish(cloud);
00274
00275 driver.getBodySonarPoints(&cloud);
00276 cloud.header.frame_id = "body";
00277 body_sonar_pub.publish(cloud);
00278
00279 } else if (sonar_just_on) {
00280 base_sonar_pub.publish(cloud);
00281 cloud.header.frame_id = "body";
00282 body_sonar_pub.publish(cloud);
00283 }
00284 }
00285
00286 void ATRVJRNode::publishBumps() {
00287 sensor_msgs::PointCloud cloud1, cloud2;
00288 cloud1.header.stamp = ros::Time::now();
00289 cloud2.header.stamp = ros::Time::now();
00290 cloud1.header.frame_id = "base_link";
00291 cloud2.header.frame_id = "body";
00292 int bumps = driver.getBaseBumps(&cloud1) +
00293 driver.getBodyBumps(&cloud2);
00294
00295 if (bumps>0 || prev_bumps>0) {
00296 bump_pub.publish(cloud1);
00297 bump_pub.publish(cloud2);
00298 }
00299 prev_bumps = bumps;
00300 }
00301
00302 int main(int argc, char** argv) {
00303 ros::init(argc, argv, "atrvjr");
00304 ATRVJRNode node;
00305 std::string port;
00306 node.n.param<std::string>("port", port, "/dev/ttyUSB0");
00307 ROS_INFO("Attempting to connect to %s", port.c_str());
00308 if (node.initialize(port.c_str())<0) {
00309 ROS_ERROR("Could not initialize RFLEX driver!\n");
00310 return 0;
00311 }
00312 ROS_INFO("Connected!");
00313
00314
00315 int hz;
00316 node.n.param("rate", hz, 10);
00317 ros::Rate loop_rate(hz);
00318
00319 while (ros::ok()) {
00320 node.spinOnce();
00321
00322 ros::spinOnce();
00323
00324 loop_rate.sleep();
00325 }
00326
00327 return 0;
00328 }