ROS消息通讯
一、创建工作空间和工作环境
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
cd ~/catkin_ws/
catkin_make
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
sudo su //切换管理员登录,然后也添加环境变量
echo "source /home/chenjian/catkin_ws/devel/setup.bash" >> ~/.bashrc
二、修改配置文件package.xml
三、配置CMakeList.txt
四、创建功能包和依赖
cd ~/catkin_ws/src/
catkin_create_pkg learning_communication std_msgs roscpp message_generation message_runtime //功能包名约定小写字母开头,且有小写字母、下划线、数字、破折号组成
cd ~/catkin_ws
catkin_make
细节
1、注:如果要用ros的函数,CmakeLists.txt中,
头文件路径加上
${catkin_INCLUDE_DIRS}
链接库加上
${catkin_LIBRARIES}
2、catkin_make编译输出的可执行文件在dev/lib/功能包名/ 目录下,可以直接启动,也可以通过[rosrun 功能包名 节点名] 方式启动
3、如果直接复制的别人的工作空间,先把除src文件夹外的所有内容删除,然后进src,把CmakeFilelist.txt删除,再在src目录下catkin_initworkspace,然后cd .., catkin_make -j1
4、建议所有的msg和srv单独创建一个功能包,这个功能包xml文件基本要求如下,这个包没有cpp文件,所以不依赖roscpp。如果消息文件中包含其他ros消息类型,则对应加入build_depend和exec_depend中
<buildtool_depend>catkin</buildtool_depend> <build_depend>message_generation</build_depend> <build_depend>std_msgs</build_depend> <exec_depend>message_runtime</exec_depend> <exec_depend>std_msgs</exec_depend>
Cmakelist.txt
find_package(catkin REQUIRED COMPONENTS message_generation //加在COMPONENTS的后面
std_msgs )
add_service_files(
DIRECTORY srv
FILES
)
add_message_files()
catkin_package(
CATKIN_DEPENDS
message_runtime //加在CATKIN_DEPENDS的后面
std_msgs
)
5、
message_generation只写在 <build_depend> 和find_package中
message_runtime只写在<exec_depend>和catkin_packages中
一个功能包调用自己的包内定义的消息,直接在cpp 的头文件中写就行(生成消息头文件的步骤和单独创建一个消息包一样)
一个功能包调用其他包定义的消息,首先xml 文件中的<build_depend> 和<exec_depend>要添加包名,Cmakelist.txt中find_package要添加包名。
“Cmakelist.txt少写绝对路径,不方便移植”
6、定义好的ros msg,如果修改后,将收不到原有录制的rostopic
7、Eigen 与 eigen3/Eigen 的问题
原因:Eigen默认安装在/usr/include/eigen3/Eigen,而很多库指定的Eigen路径是/usr/include/Eigen
确保已经正确安装Eigen库,然后
解决办法一:
在CMakeLists.txt里面添加include_directories("/usr/include/eigen3")
解决办法二:
sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen
8、ros的通信默认是tcp,可切换为udp
ros::Subscriber chatter_sub = private_nh.subscribe( "/chatter" , 10, print_message, ros::TransportHints().unreliable().maxDatagramSize(1000));
9、ros_bridge 是用python写的,性能待测试
10、话题订阅说明放在类里面,需要传入this参数,ros node 如果在类里面初始化,一定要将句柄初始化在public里面,这样这个订阅其他的成员才能看得到。
11、ros::Timer定时器要和ros::spin()配合使用,如果没有调用ros::spin(),定时器设置的回调函数在回调队列里面不会被执行。