ROS中常用API
ROS常用API
ros::init()
ros::init( argc, argv, "name of node",option)
该函数有四个参数, argc, argv, name,option
其中,各参数有以下作用:
argc:
向该函数传入的实参数量 +1,即如果向内传入10个参数,那么该值是 11;
argv:
该参数是向其中传入的参数的数组,即假设我们向其中传入了0~9共10 个数,那么这个数组将会是: \[ 0 \ 1 \ 2 \ 3 \ 4 \ 5 \ 6 \ 7 \ 8 \ 9 \]
name of node:
该节点的名称,通常情况下节点名称具有唯一性,即每个节点的名字要不同
option:
有些时候,我们会反复开启一个节点。此时为了保持节点唯一性,就需要使用option下面的ros::init_options::AnonymousName,该值为封装好的值,直接替换option所在位置即可
为了向其中传入数据,我们可以用特定格式,如 _length := 2
这会为参数服务器插入一个值为2的length
无返回值
ros::Publisher
ros::Publisher pub = nh.advertise < std_msgs::String >("name of topic",frequency,latch)
创建一个发布者对象。其中,各参数的意义如下:
- name of node
该参数用于指定发布者对象的发布话题是什么,可以自定义但要记得节点名称具有唯一性
- nh.advertise<>
用于指定是发布对象,假使要为接受方,则为subscribe<>。
尖括号内事消息的格式,后面还有geometry_msg类型,可以自我定义
frequency
用于指定发布的评论,单位为Hz。比如我们这里填写10,那么就是一秒钟发布10个消息
latch
optional的选项,即可以写也可以不写使用默认值,是一个额外的对象。
该值如果为true,那么发布方就会将最后发布的消息储存,当有新的订阅者连接到它时,就会再将这个信息发布出去
pub.publish是其返回值
ros::Subscriber
ros::Subscriber sub = nh.subscribe("topic_name", queue_size, callback_function)
创建一个订阅者对象
“topic_name”
话题名称,不再过多介绍
queue_size
队列长度,当接受到的消息数量大于队列长度时,队列会将最开始收到的信息出队,这里用到的知识是队列的FIFO(First in first out)知识
call_backfunction
回调函数,在接受到消息时,配合spin/spinonce函数可以达到不断调用该函数的功能。
例如,我想在接受到一个函数信息时,就发布“我接受到的消息是:+xxx”,那么代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "ros/ros.h"
#include "std_msgs/String.h"
// 回调函数定义
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "listener");
// 创建节点句柄
ros::NodeHandle n;
// 订阅消息,并注册回调函数
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
// 循环等待消息
ros::spin();
return 0;
}spin/spinOnce
1
2ros::spin();
ros::spinOnce();ros::spin();
会一直前面的回调函数位置,其后的内容无法执行
ros::spinOnce();
仅仅回调一次,其后的内容在回调一次后又会执行
ros:Time::now()
1
2
3
4
5
6
7
8
9
10
11ros::init(argc,argv,"hello_time");
ros::NodeHandle nh;
ros::Time right_now = ros::Time::now();//将当前时刻封装成对象
ROS_INFO("当前时刻:%.2f",right_now.toSec());//获取距离 1970年01月01日 00:00:00 的秒数
ROS_INFO("当前时刻:%d",right_now.sec);//获取距离 1970年01月01日 00:00:00 的秒数
ros::Time someTime(100,100000000);// 参数1:秒数 参数2:纳秒
ROS_INFO("时刻:%.2f",someTime.toSec()); //100.10
ros::Time someTime2(100.3);
ROS_INFO("时刻:%.2f",someTime2.toSec()); //100.30该函数可以返回当程序调用它时举例1970年1月1日8点的时间戳
1.在使用该函数时,必须使用Nodehandle进行初始化,否则时间没有初始化该函数无法调用
1
right_now.toSec()可以将right_now的值转换为秒数
1
ros::Time someTime(100,100000000);设置一个sometime的值为100秒+1000000纳秒,也可以这样设置:
1
ros::Time someTime2(100.3);ros::time相减可以,相加不可以。
1
2
3
4
5
6ros::Time begin = ros::Time::now();
ros::Duration dul(5);
ros::Time end = begin + dul;
ros::Duration du2 = end - begin;duration之间可以任意相加
1
2
3ros::Duration du3 = du2 - dul;
ros::Duration du4 = du2 + dul;
ros::Rate
1
2
3
4
5
6
7
8ros::Rate rate_20hz(20); // 创建一个20Hz的频率对象
while (true)
{
messenger.PublishStateToROS();
ros::spinOnce();
rate_20hz.sleep();
}
ros::Timer
1 | |
创建一个定时器对象
其中,各参数的含义如下:
- ros::Duration period 定时器周期
- const ros::TimerCallback &callback 回调函数
- bool oneshot = false 是否只执行一次
- bool autostart true 是否自动启动
常常与ros::Spin()函数一起使用
使用案例
1 | |
和创建订阅对象是类似的
当bool autostart = false时,如果想要开启定时器,那么可以用以下语句:
1 | |
ros::Shutdown()
可以关闭主节点,配合while(ros::OK());使用