1.3查看变换树 可以用tf工具来查看机器人的变换树结构,首先用前面额例子载入一个机器人系统。 roslaunch chapter7_tutorials gazebo_map_robot.launch model:="rospack find chapter7_tutorials/urdf/robot1_base_04.xacro" rosrun tf view_frames 可以得到以下的结果 d密e1455343707得 现在再次运行tf broadcasterf的node然后用view frame来观察新创建的坐标系 rosrun chapter7_tutorials tf_broadcaster rosrun tf view_frames 将会得到如下结果,红圈中为新添加的坐标系 5m 2.发布传感器信息 一个机器人可以使用很多传感器来观察世界,可以通过开发许多的ode来使用这些数据 做一些事情,但是导航包目前仅使用平面激光传感器的数据。所以,确保机器人的传感器 topic包含:sensor_.msgs/LaserScan或者sensor_.msgs/PointCloud:类型数据。 这里将使用机器人前端的激光传感器来在Gazebo中进行导航。注意这里的激光传感器 是在Gazebo中仿真出来的,发布的topic为base_scan/scan 在这里我们无需配置我们的激光传感器,因为在urdf文件里己经有了相对机器人的位姿 信息数据。 首先,可以查看这个消息sensor_.msgs/LaserScan的数类型。 -6-
- 6 - 1.3查看变换树 可以用tf工具来查看机器人的变换树结构,首先用前面额例子载入一个机器人系统。 $ roslaunch chapter7_tutorials gazebo_map_robot.launch model:="`rospack find chapter7_tutorials`/urdf/robot1_base_04.xacro" $ rosrun tf view_frames 可以得到以下的结果 现在再次运行tf_broadcaster的node然后用view_frame来观察新创建的坐标系 $ rosrun chapter7_tutorials tf_broadcaster $ rosrun tf view_frames 将会得到如下结果,红圈中为新添加的坐标系 2. 发布传感器信息 一个机器人可以使用很多传感器来观察世界,可以通过开发许多的node来使用这些数据 做一些事情,但是导航包目前仅使用平面激光传感器的数据。所以,确保机器人的传感器 topic包含:sensor_msgs/LaserScan 或者sensor_msgs/PointCloud类型数据。 这里将使用机器人前端的激光传感器来在Gazebo中进行导航。注意这里的激光传感器 是在Gazebo中仿真出来的,发布的topic为base_scan/scan. 在这里我们无需配置我们的激光传感器,因为在urdf文件里已经有了相对机器人的位姿 信息数据。 首先,可以查看这个消息sensor_msgs/LaserScan的数类型
rosmsg show sensor_msgs/LaserScan std_msgs/Header header uint32 seq time stamp string frame_id float32 angle_min float32 angle_max float32 angle_increment float32 time_increment float32 scan_time float32 range_min float32 range_max float320 ranges float320 intensities 2.1创建一个激光node 在chapter77_tutorials/src文件夹创建一个新的laser..cpp然后输入以下代码。 #include <ros/ros.h> #include <sensor_msgs/LaserScan.h> int main(int argc,char**argv){ ros::nit(argc,argv,"laser_scan_publisher"); ros::NodeHandle n; ros::Publisher scan_pub n.advertise<sensor_ msgs::LaserScan>("scan",50) unsigned int num_readings =100; double laser_frequency =40; double ranges[num_readings]; double intensities[num_readings]; int count =0; ros::Rate r(1.0); while(n.ok(){ //generate some fake data for our laser scan for(unsigned inti =0;i num_readings;++i) -7-
- 7 - $ rosmsg show sensor_msgs/LaserScan std_msgs/Header header uint32 seq time stamp string frame_id float32 angle_min float32 angle_max float32 angle_increment float32 time_increment float32 scan_time float32 range_min float32 range_max float32[] ranges float32[] intensities 2.1创建一个激光node 在chapter7_tutorials/src文件夹创建一个新的laser.cpp然后输入以下代码。 #include <ros/ros.h> #include <sensor_msgs/LaserScan.h> int main(int argc, char** argv){ ros::init(argc, argv, "laser_scan_publisher"); ros::NodeHandle n; ros::Publisher scan_pub = n.advertise<sensor_ msgs::LaserScan>("scan", 50); unsigned int num_readings = 100; double laser_frequency = 40; double ranges[num_readings]; double intensities[num_readings]; int count = 0; ros::Rate r(1.0); while(n.ok()){ //generate some fake data for our laser scan for(unsigned int i = 0; i < num_readings; ++i){
ranges[i]count; intensities[i]100 count; } ros::Time scan_time ros::Time::now(; //populate the LaserScan message sensor_msgs::LaserScan scan; scan.header.stamp scan_time; scan.header.frame_id "base_link"; scan.angle_min =-1.57; scan.angle_max 1.57; scan.angle_increment 3.14/num_readings; scan.time_increment =(1/laser_frequency)/(num_readings); scan.range_min 0.0; scan.range_max 100.0; scan.ranges.resize(num_readings); scan.intensities.resize(num_readings); for(unsigned int i =0;i num_readings;++i){ scan.ranges[i]ranges[i]; scan.intensities[i]=intensities[i]; scan_pub.publish(scan); ++count r.sleep(; } } 可以看到,我们创建一个名为scan数据类型为sensor_.msgs/儿aserScan的topic。.这个消 息的名字一定要正确,因为后续导航包将会读取这个topc。以下代码中设定了该消息名字。 ros::Publisher scan_pub n.advertise<sensor_msgs::LaserScan>("scan", 50: 同时,在发布topic的时候类似于header,stamp,frame_id等很多的元素都需要发布, 否则导航包也会无法正常工作 scan.header.stamp scan_time; scan.header.frame_id "base_link"; -8-
- 8 - ranges[i] = count; intensities[i] = 100 + count; } ros::Time scan_time = ros::Time::now(); //populate the LaserScan message sensor_msgs::LaserScan scan; scan.header.stamp = scan_time; scan.header.frame_id = "base_link"; scan.angle_min = -1.57; scan.angle_max = 1.57; scan.angle_increment = 3.14 / num_readings; scan.time_increment = (1 / laser_frequency) / (num_readings); scan.range_min = 0.0; scan.range_max = 100.0; scan.ranges.resize(num_readings); scan.intensities.resize(num_readings); for(unsigned int i = 0; i < num_readings; ++i){ scan.ranges[i] = ranges[i]; scan.intensities[i] = intensities[i]; } scan_pub.publish(scan); ++count; r.sleep(); } } 可以看到,我们创建一个名为scan数据类型为sensor_msgs/LaserScan的topic。这个消 息的名字一定要正确,因为后续导航包将会读取这个topic。以下代码中设定了该消息名字。 ros::Publisher scan_pub = n.advertise<sensor_msgs::LaserScan>("scan", 50); 同时,在发布topic 的时候类似于header,stamp,frame_id等很多的元素都需要发布, 否则导航包也会无法正常工作 scan.header.stamp = scan_time; scan.header.frame_id = "base_link";