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 0.02
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 #include <lse_sensor_msgs/Range.h>
00044
00045 #include "Nclient.h"
00046
00047 #define INCH_TO_METER 0.0254
00048 #define DEGREE_TO_RADIAN 0.0174532925
00049
00050 #define SCOUT_BAUD_RATE 38400
00051 #define BRIDGE_BAUD_RATE 19200
00052
00053 #define BATTERY_LOW 0
00054 #define BATTERY_MED 1
00055 #define BATTERY_HIGH 2
00056
00057 long State[NUM_STATE];
00058
00059 void cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
00060 {
00061 scout_vm((int)(cmd_vel->linear.x/(INCH_TO_METER)*10), (int)(cmd_vel->angular.z/(DEGREE_TO_RADIAN)*10));
00062 }
00063
00064
00065 int main(int argc, char** argv)
00066 {
00067 ros::init(argc, argv, "scout_node");
00068
00069 ROS_INFO("Scout for ROS %.2f", NODE_VERSION);
00070
00071 ros::NodeHandle n("~");
00072
00073 tf::TransformBroadcaster odom_broadcaster;
00074
00075 ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("/odom", 50);
00076 ros::Publisher sonar_pub = n.advertise<lse_sensor_msgs::Range>("/sonar", 50);
00077
00078 ros::Subscriber cmd_vel_sub = n.subscribe<geometry_msgs::Twist>("/cmd_vel", 1, cmdVelReceived);
00079
00080 std::string port;
00081 n.param<std::string>("port", port, "/dev/ttyUSB0");
00082
00083 std::string model;
00084 n.param<std::string>("model", model, "Scout2");
00085
00086 int robot_model;
00087 if(model.compare("N200")==0) robot_model = MODEL_N200;
00088 else if(model.compare("N150")==0) robot_model = MODEL_N150;
00089 else if(model.compare("Scout")==0) robot_model = MODEL_SCOUT;
00090 else if(model.compare("Scout2")==0) robot_model = MODEL_SCOUT2;
00091 else
00092 {
00093 ROS_FATAL("Scout -- Unknown robot model: %s! Options are N200, N150, Scout and Scout2", model.c_str());
00094 ROS_BREAK();
00095 }
00096
00097
00098 connect_robot(1, robot_model, port.c_str(), SCOUT_BAUD_RATE);
00099
00100 dp(0,0);
00101 da(0,0);
00102 zr();
00103
00104
00105
00106
00107 int sn_order[16] = {0, 2, 15, 1, 14, 3, 13, 4, 12, 5, 11, 6, 10, 7, 9, 8};
00108 conf_sn(15, sn_order);
00109
00110 ros::Time current_time;
00111
00112 ros::Rate r(10.0);
00113 while(n.ok())
00114 {
00115
00116 gs();
00117
00118 current_time = ros::Time::now();
00119
00120
00121
00122 float odom_x = State[STATE_CONF_X]*INCH_TO_METER/10.0;
00123 float odom_y = State[STATE_CONF_Y]*INCH_TO_METER/10.0;
00124 float odom_yaw = State[STATE_CONF_STEER]*DEGREE_TO_RADIAN/10.0;
00125
00126
00127 geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(odom_yaw);
00128
00129
00130 geometry_msgs::TransformStamped odom_trans;
00131 odom_trans.header.stamp = current_time;
00132 odom_trans.header.frame_id = "/odom";
00133 odom_trans.child_frame_id = "/base_link";
00134
00135 odom_trans.transform.translation.x = odom_x;
00136 odom_trans.transform.translation.y = odom_y;
00137 odom_trans.transform.translation.z = 0.0;
00138 odom_trans.transform.rotation = odom_quat;
00139
00140
00141 odom_broadcaster.sendTransform(odom_trans);
00142
00143
00144 nav_msgs::Odometry odom;
00145 odom.header.stamp = current_time;
00146 odom.header.frame_id = "/odom";
00147
00148
00149 odom.pose.pose.position.x = odom_x;
00150 odom.pose.pose.position.y = odom_y;
00151 odom.pose.pose.position.z = 0.0;
00152 odom.pose.pose.orientation = odom_quat;
00153
00154
00155 odom.child_frame_id = "/base_link";
00156 odom.twist.twist.linear.x = State[STATE_VEL_TRANS]*INCH_TO_METER/10;
00157 odom.twist.twist.linear.y = 0.0;
00158 odom.twist.twist.angular.z = State[STATE_VEL_STEER]*DEGREE_TO_RADIAN/10;
00159
00160
00161 odom_pub.publish(odom);
00162
00163
00164 for(int STATE_SONAR_i=STATE_SONAR_0 ; STATE_SONAR_i<=STATE_SONAR_15 ; STATE_SONAR_i++)
00165 {
00166 lse_sensor_msgs::Range sonar;
00167 sonar.header.stamp = current_time;
00168 char frame_id[32];
00169 sprintf(frame_id, "/base_sonar_%d", STATE_SONAR_i-STATE_SONAR_0);
00170 sonar.header.frame_id = frame_id;
00171 sonar.field_of_view = 0.34906585;
00172 sonar.min_range = 0.50;
00173 sonar.max_range = 5.00;
00174 sonar.range = (float)(State[STATE_SONAR_i]*INCH_TO_METER);
00175 sonar_pub.publish(sonar);
00176 }
00177
00178 char status = State[STATE_MOTOR_STATUS];
00179
00180 bool left_wheel_moving = status & 0x01;
00181 bool right_wheel_moving = (status>>1) & 0x01;
00182
00183 int battery_state;
00184 bool b0 = (status>>2) & 0x01;
00185 bool b1 = (status>>3) & 0x01;
00186 if(!b0 && !b1) battery_state = BATTERY_LOW;
00187 else if(b0 && !b1) battery_state = BATTERY_MED;
00188 else if(!b0 && b1) battery_state = BATTERY_HIGH;
00189
00190 bool is_plugged = (status>>4) & 0x01;
00191 bool is_charging = (status>>5) & 0x01;
00192 bool emergency_stop = (status>>6) & 0x01;
00193
00194 ros::spinOnce();
00195 r.sleep();
00196 }
00197
00198
00199 int sn_off[1] = {255};
00200 conf_sn(15, sn_off);
00201
00202 st();
00203
00204 disconnect_robot(1);
00205 }
00206
00207