学习目标
- 自定义一种消息
- 调用一个turtle,使用键盘控制
- 读取这个turtle的为止信息,填充自己的消息,并发布出来
- 订阅这个话题,打印出读取到的内容
- 使用launch文件启动
自定义消息话题
自己定义的消息
string name
float32 x
float32 y
float32 angle
注意一下格式,类型和名称之间是空格,写成table会有问题
在xml文件中增加依赖
<exec_depend>message_runtime</exec_depend>
在CMakeList.txt文件中增加编译选项
10 find_package(catkin REQUIRED COMPONENTS
11 roscpp
12 rospy
13 std_msgs
14 message_generation
15 actionlib_msgs
16 actionlib
17 )
58 add_message_files(
59 FILES
60 Person.msg
61 Position.msg
62 )
85 generate_messages(DEPENDENCIES std_msgs actionlib_msgs)
catkin_make 之后可以看到
raoxu@raoxu:~/catkin_ws/src/learning_communication$ rosmsg show learning_communication/Position
string name
float32 x
float32 y
float32 angle
写源文件
1 #include <sstream>
2 #include "ros/ros.h"
3 #include "std_msgs/String.h"
4 #include "learning_communication/Position.h"
5 #include <geometry_msgs/Twist.h>
6 #include <turtlesim/Spawn.h>
7 #include <turtlesim/Pose.h>
8
9 ros::Publisher position_pub;
10
11 void poseCallback(const turtlesim::PoseConstPtr& posmsg)
12 {
13 //创建消息
14 learning_communication::Position msg;
15
16 msg.name = "turtle1";
17 msg.x = posmsg->x;
18 msg.y = posmsg->y;
19 msg.angle = posmsg->theta;
20
21 position_pub.publish(msg);
22 }
23
24 int main(int argc, char **argv)
25 {
26 // ROS节点初始化
27 ros::init(argc, argv, "position_publish");
28 ros::NodeHandle n;
29
30 ROS_INFO("create publish");
31
32 // 创建一个Publisher,发布名为show_position的topic,消息类型为
33 position_pub = n.advertise<learning_communication::Position>("show_position", 1000);
34
35 ros::Subscriber sub = n.subscribe("/turtle1/pose", 1000, poseCallback);
36
37 ros::spin();
38
39 return 0;
40 }
5 #include <sstream>
6 #include "ros/ros.h"
7 #include "std_msgs/String.h"
8 #include "learning_communication/Position.h"
9
10 // 接收到订阅的消息后,会进入消息回调函数
11 void listenCallback(const learning_communication::Position &msg)
12 {
13 // 将接收到的消息打印出来
14 ROS_INFO("listen: [name:%s, x:%f, y:%f, a:%f]", msg.name.c_str(), msg.x, msg.y, msg.angle);
15 }
16
17 int main(int argc, char **argv)
18 {
19 // 初始化ROS节点
20 ros::init(argc, argv, "position_listen");
21
22 // 创建节点句柄
23 ros::NodeHandle listen;
24
25 ROS_INFO("create listener");
26 // 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback
27 ros::Subscriber sub = listen.subscribe("show_position", 1000, listenCallback);
28
29 // 循环等待回调函数
30 ros::spin();
31
32 return 0;
33 }
在CMakeList.txt文件中增加编译选项
155 add_executable(position_pub src/position_publisher.cpp)
156 target_link_libraries(position_pub ${catkin_LIBRARIES})
157
158 add_executable(position_listen src/position_listen.cpp)
159 target_link_libraries(position_listen ${catkin_LIBRARIES})
catkin_make 之后成功编译出可执行文件,可以查看
ls ~/catkin_ws/devel/lib/learning_communication/
client DoDishes_client DoDishes_server listener listen_pos position_listen position_pub server talker
写launch文件
<launch>
<node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>
<node pkg="turtlesim" type="turtlesim_node" name="sim"/>
<node pkg="learning_communication" name="position_listen" type="position_listen" output = "screen"/>
<node pkg="learning_communication" name="position_publish" type="position_pub" output = "screen"/>
</launch>
运行效果
敲命令
roslaunch learning_communication positon_show.launch
tf包的学习
本来预计这次也要做tf包学习的作业,不过目前学习的东西太少,等学会urdf之后,关于tf的内容会统一一起做的。
目前先简单说一下,自己对于tf的简单理解:
- 各个位置需要将自己的坐标信息,创建tf发布器,讲位置信息发送给tf,tf会有一个树的结构管理,计算出各个点的坐标系的关系
- 需要时用的时候去监听tf的信息,使用TransformListener,然后查找里面的内容lookupTransform
例如:
listener.lookupTransform("/turtle2", “/turtle1”, ros::Time(0), transform);
查找的内容在transform里面,这个代表的是,turtle1在turtle2坐标系下面的位置。片面的看就是,向量turtle1减去turtle2。