使用ROS的cpp客户端库写程序
2016-04-26 12:52
555 查看
以下,是针对roscpp客户端库的常用API进行必要的说明。
ros::NodeHandle类维护一个引用计数,仅仅在第一次NodeHandle对象创建时,才会在节点管理器注册新的节点。同样,只有当所有NodeHandle对象都销毁后,节点才会注销
advertise函数返回一个Publisher对象,这个对象可调用publish函数,向特定话题发布消息
Arguments of publish is msg object, whose type must be consensus with the template argument of advertise. For example:
使ros::ok返回false的几个原因:
对节点使用了rosnode kill命令
向程序发送了一个终止信号(Ctrl-C)
以相同的名字启动了其他节点
ros::init给Ctrl-C终止信号放置了一个句柄,用它来发起正常的关机程序。其过程是Ctrl-C可以被用来使ros::ok返回false,但不会立刻终止程序。如果在程序退出前完成一些必要的收尾工作,如写日志文件、保存结果,这个设计是很重要的。
注:运行ORB-SLAM2的ROS版本时,就充分利用了这一功能。实际上,这个功能是必要的。当更改成普通的C++程序时,发出Ctrl-C信号后,程序直接就终止了,而无法在退出程序前保存内存中的数据
ros::Rate对象相对于简单的固定延迟,如sleep,其优势在于,ros::Rate可以考虑循环中其他部分消耗的时间。如果每个迭代包含复杂计算,通过该计算所消耗的时间应该从延迟中减除
订阅者回调函数的一般形式:
注:返回类型为void。这样安排是合理的,因为调用此函数是ROS的工作,返回值也要交给ROS,所以用户程序无法获得返回值,非void的返回值类型也就没有意义了
要求ROS执行所有挂起的回调函数,然后将控制权返回给用户
ros::spin
要求ROS等待并且执行回调函数,直到这个节点关机。
注:相当于一个while ( true )循环
ros::ok和while的组合
作用同ros::spin
选用策略:程序除了响应回调函数,还有其他的重复性工作要做吗?如果答案是“否”,那么使用ros::spin;否则,合理的选择是写一个循环,做其他需要做的事情,并且周期性地调用ros::spinOnce来处理回调
订阅者程序中常见的一个错误是不小心地忽略了调用ros::spinOnce和ros::spin。在这种情况下,ROS永远没有机会执行回调函数。忽略ros::spin会导致程序在开始运行后不久就退出。忽略ros::spinOnce使程序表现得好像没有接收到任何消息
ros::init
ros::init函数的节点名参数可在运行时覆盖ros::NodeHandle
ros::NodeHandle对象是程序用于和ROS系统交互的主要机制ros::NodeHandle类维护一个引用计数,仅仅在第一次NodeHandle对象创建时,才会在节点管理器注册新的节点。同样,只有当所有NodeHandle对象都销毁后,节点才会注销
ros::Publisher
如果想从同一个节点发布关于多个不同话题的消息,需要为每个话题创建一个独立的ros::Publisher对象advertise函数返回一个Publisher对象,这个对象可调用publish函数,向特定话题发布消息
Arguments of publish is msg object, whose type must be consensus with the template argument of advertise. For example:
nh.advertise< std_msgs::String >( "topic", 1000 ); // ... std_msgs::String msg; // ... topic_pub.publish( msg );
ros::ok
检查程序作为ROS节点是否仍处于运行良好的状态使ros::ok返回false的几个原因:
对节点使用了rosnode kill命令
向程序发送了一个终止信号(Ctrl-C)
以相同的名字启动了其他节点
ros::init给Ctrl-C终止信号放置了一个句柄,用它来发起正常的关机程序。其过程是Ctrl-C可以被用来使ros::ok返回false,但不会立刻终止程序。如果在程序退出前完成一些必要的收尾工作,如写日志文件、保存结果,这个设计是很重要的。
注:运行ORB-SLAM2的ROS版本时,就充分利用了这一功能。实际上,这个功能是必要的。当更改成普通的C++程序时,发出Ctrl-C信号后,程序直接就终止了,而无法在退出程序前保存内存中的数据
ros::Rate( rate_in_hz ) & ros::Rate::sleep
sleep方法在程序中产生延迟,延迟的持续时间用来阻止循环的迭代速率超过指定的速率,这里是rate_in_hz赫兹。没有这种控制,程序会以计算机允许的最快速度发布消息,这样会占满发布和订阅的序列,并且浪费计算和网络资源ros::Rate对象相对于简单的固定延迟,如sleep,其优势在于,ros::Rate可以考虑循环中其他部分消耗的时间。如果每个迭代包含复杂计算,通过该计算所消耗的时间应该从延迟中减除
关于回调函数
发布和订阅消息的一个重要区别是,订阅者节点无法知道消息什么时候到达。为了应对这一事实,必须把响应收到消息事件的代码放到回调函数里订阅者回调函数的一般形式:
void function_name( const package_name::type_name& msg ) { }
注:返回类型为void。这样安排是合理的,因为调用此函数是ROS的工作,返回值也要交给ROS,所以用户程序无法获得返回值,非void的返回值类型也就没有意义了
给ROS控制权
ros::spinOnce要求ROS执行所有挂起的回调函数,然后将控制权返回给用户
ros::spin
要求ROS等待并且执行回调函数,直到这个节点关机。
注:相当于一个while ( true )循环
ros::ok和while的组合
作用同ros::spin
选用策略:程序除了响应回调函数,还有其他的重复性工作要做吗?如果答案是“否”,那么使用ros::spin;否则,合理的选择是写一个循环,做其他需要做的事情,并且周期性地调用ros::spinOnce来处理回调
while ( ros::ok( ) ) { ros::spinOnce( ); }
订阅者程序中常见的一个错误是不小心地忽略了调用ros::spinOnce和ros::spin。在这种情况下,ROS永远没有机会执行回调函数。忽略ros::spin会导致程序在开始运行后不久就退出。忽略ros::spinOnce使程序表现得好像没有接收到任何消息
相关文章推荐
- c++ 继承、多态——c++复习(三)
- C/C++复习:小数计算(结构体)
- C/C++复习:学生信息的输出(结构体)
- C++: 详解 使用Schrage's Method Revealed 实现随机化算法
- C++ STL -- stack / queue / priority_queue 的使用方法
- 数组实现循环队列 C++实现
- 简要的Windows API函数大全
- c++ hook 钩子的使用介绍
- C++高手必看书籍
- c++实现人命币大小写转换
- C语言隐式类型转换的规则
- c++ vector的几个常用方法
- [C/C++11]_[初级]_[使用std::function来封装函数]
- [C/C++11]_[初级]_[使用std::function来封装函数]
- C++ STL算法之:copy
- C++引用
- C++ 构造双向链表的实现代码
- C语言的setvbuf函数:设置文件流的缓冲区
- 值得学习的C语言开源项目
- C语言最优状态机规范