《 无人驾驶原理与实践》一2.6ROS的基本编程
2.6ROS的基本编程
前文讨论了ROS的核心概念以及命令行的基本操作,本节将通过Husky模拟器完成一个简易的ROS包,通过实例描述ROS下CMakeList文件的语法,然后使用Rviz可视化激光扫描的结果。
ROS程序可以由多种语言编写,由于C++更贴近于无人车工程实践,因此本节从C++入手开始学习ROS编程。
2.6.1ROS C++编程
下面是使用ROS C++库编写的一个hello world程序。
接下来看一下程序含义。引入ROS的头文件:
#include <ros/rosh>
初始化ROS节点:
ros::init(argc, argv, "hello_world");
每个ROS节点都应该最先调用该方法,这个节点被命名为hello_world。为进程节点创建句柄:
ros::NodeHandle nodeHandle;
第一个创建的NodeHandle会对节点进行初始化,最后一个销毁的NodeHandle则会释放该节点所占用的所有资源。指定循环的频率:
ros::Rate loopRate(10);
ros::Rate是一个用于以指定的频率循环的辅助类,例子中循环频率是10Hz。循环语句如下:
while(ros::ok()){}
这条语句会以之前在Rate对象中指定的频率循环执行,其中ros::ok()会在ROS节点结束运行时返回false从而终止循环。在如下几种情况下ros::ok()会返回false:
◆ SIGINT被触发 (Ctrl-C)。
◆ 被另一同名节点“踢”出ROS网络。
◆ ros::shutdown()被程序的另一部分调用。
◆ 节点中的所有ros::NodeHandle都已经被销毁。
在循环体中有一条ros::spinOnce()语句,其作用在于,当我们订阅某个话题的时候,执行这条语句意味着只处理一次回调。我们会在后面详细讨论。
1节点句柄
有四种定义节点句柄的语法:
◆ 默认的公共句柄:nodeHandle=ros::NodeHandle()
◆ 私有句柄:nodeHandle=ros::NodeHandle("~")
◆ 命名空间句柄:nodeHandle=ros::NodeHandle("adam")
◆ 全局句柄(不推荐使用):nodeHandle=ros::NodeHandle("/")
使用这四种语法定义句柄的节点在订阅一个主题时,分别订阅的是下列主题:
/namespace/topic
/namespace/node_space/topic
/namespace/adam/topic
/topic
2 ROS中的日志记录方法
在ROS节点中通常不提倡直接使用C++的标准输入输出日志记录(Logging)语法,一般使用ROS_INFO来代替标准输出std:cout。ROS_INFO会自动将信息发送到命令行、log文件以及/rosout主题上。
当然,还有其他的日志记录类型,比如ROS_WARN、ROS_ERROR等。同时,ROS还提供了printf风格和stream风格的方法。
如果使用ROS_INFO但在屏幕上没有找到应打印的信息,通常来说,除了检查代码逻辑以外,还须检查launch文件中Node节点的output标签值是否设置为screen,即是否有output="screen"。
- 点赞
- 收藏
- 关注作者
评论(0)