对视觉类论文详解(免费)感兴趣的同学,可以关注微信公众号 李卓璐随手记
初始化ROS节点
ros::init(argc,argv,“name”,options);
作用:ros初始化函数
参数:
1.argc —封装实参的个数(n+1个->有一个是自身);
2.argv —封装参数的数组;
3.name —为节点命名(唯一性);
4.options —节点启动项,解决节点重名问题。
返回值: void
使用:
1.argc和argv的使用:
如果按照ROS中的特定格式传入实参,那么ROS可以加以使用,比如可以用来设置全局参数、给节点命名。
2.options的使用:
节点名称需要保证唯一,当有重名的节点启动时,之前的节点会被关闭。
需求:特定场景下,需要一个节点多次启动且能正常运行怎么办?
ros::init(argc,argv,“name”,ros::init_options::AnonymousName);
原理:创建节点时,使用name前缀,后面加上随机数,即避免名称重名,实现一个节点启动多次。
创建话题和服务相关对象
创建节点句柄
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<std_msgs::String>(“话题名称”,队列长度,latch);
1.创建发布者对象nh.advertise
作用:创建发布者对象
模板:被发布的消息的类型
参数:
1.话题名称
2.队列长度
3.latch(可选):如果设置为true,会保存发布方的最后一条消息,并且新的订阅对象链接到发布方时,发布方会将这条消息发送给订阅者。
使用:
latch设置为true的作用?
以静态地图发布为例:
方案1:可以使用固定频率发送地图数据,但是必须一直发送保证订阅者能够获取信息,效率低;
方案2:将地图发布对象的latch设置为true,发布方会将最后一条发送的数据保存,所以即使订阅者连接时,发布方此刻没有发送数据,订阅者也能获取到地图信息。这种方法可以使发布方只发送一次信息,提高数据发送效率。
2.函数返回值ros::Publisher,对应函数pub.publish();
回旋/头函数
1.发布方:ros::spinOnce(); 代码中存在回调函数,当遇到spinOnce()会回头寻找回调函数,并处理一轮后退出,执行spinOnce()后的程序。
2.订阅方:ros::spin(); 代码中存在回调函数,当遇到spin()同样会回头寻找回调函数,但不会退出,进入循环体内持续处理,导致spin()下面的代码执行不到。
时间(如:获取当前时刻,持续时间执行频率,休眠,定时器等)
1.时刻:
注意必须创建句柄,否则时间没有初始化,导致后续API调用失败 ros::NodeHandle nh;
ros::Time 对象名 = ros::Time::now();
now函数会将当前时刻封装返回,当前时刻指now被执行的一刻,距离1970年01月01日 00:00:00 的时间。
ROS_INFO(“当前时刻:%.2f”,对象名.toSec()); //.toSec()可以将时间转化成秒,浮点型。
ROS_INFO(“当前时刻:%d”,对象名.sec); //.sec返回是整形秒数
2.设定指定时刻:调用构造函数Time
方案1:
ros::Time 对象名(100,100000000);// Time(参数1:秒数sec 参数2:纳秒nsec),最后的时间是100s+100000000ns
ROS_INFO(“时刻:%.2f”,对象名.toSec());//100.10
方案2:
ros::Time 对象名2(100.3);//直接传入 double 类型的秒数
ROS_INFO(“时刻:%.2f”,对象名2.toSec()); //100.30
3.持续时间
需求:程序执行中停顿5s
实现:
1.创建执行时间对象:
ros::Duration 对象名(4.5);
2.休眠:
对象名.sleep();//按照指定的持续时间(4.5s)休眠
4.持续时间与时刻运算
需求:已知程序开始运行时刻和程序运行时间,求运行结束的时刻
实现:
1.获取开始执行时间
ros::Time begin = ros::Time::now();
2.模拟运行时间N秒
ros::Duration 对象名(N);
3.计算结束时刻=开始+持续
ros::Time stop = begin + 对象名;
5.持续时间与持续时间运算
ros::Duration du1(10);
ros::Duration du2(20);
ros::Duration du3 = du1 + du2;
ros::Duration du4 = du1 - du2;
ROS_INFO(“du3 = %.2f”,du3.toSec());//正常
ROS_INFO(“du4 = %.2f”,du4.toSec());//正常
6.时刻与时刻运算
ros::Time nn = begin+ stop;//异常,因此time 与 time 不可以运算
ros::Time nn = begin-stop;//正常
注意:持续时间与时刻运算可以加减运算,持续时间与持续时间运算可以加减运算,但时刻与时刻运算只能减法不能加。
7.运行频率
ros::Rate rate(1);//指定频率
while (true)
{
rate.sleep();//休眠,休眠时间 = 1 / 频率。
}
8.定时器
需求:要求每隔1秒钟,在控制台输出一段文本
实现:
方案一:ros::Rate rate(1);
方案二:ros::Timer
ros::Duration period —时间间隔
const callback —回调函数
bool oneshot —如果设置为 true,只执行一次回调函数,设置为 false,就循环执行。
bool autostart —如果为true,返回已经启动的定时器,设置为 false,需要手动启动。
举例:
ros::Timer 定时器 = nh.createTimer(时间间隔,回调函数cd,是否一次性,自动启动);
#其中时间间隔:ros::Duration(1);回调void cd(const ros::TimerEvent& event)封装业务,oneshot=true/false,autostart=true/false—>当autostart=false一般需要手动调用timer.start();
ros::spin(); //定时器启动后必须有回头函数 spin()
其他函数
1.节点的生命周期
C++用while (ros::ok())
导致节点关闭的原因:
1.在运行窗口输入ctrl+c,节点收到关闭信号;
2.同名节点启动;
3.程序中的其他部分调用了节点关闭API(ros::shutdown()),如在循环体中有if判断。
2.日志相关API
声明:
DEBUG(调试):只在调试时使用,此类消息不会输出到控制台;
INFO(信息):标准消息,一般用于说明系统内正在执行的操作;
WARN(警告):提醒一些异常情况,但程序仍然可以执行;
ERROR(错误):提示错误信息,此类错误会影响程序运行;
FATAL(严重错误):此类错误将阻止节点继续运行。
调用:
ROS_DEBUG(“hello,DEBUG”); //不会输出
ROS_INFO(“hello,INFO”); //默认白色字体
ROS_WARN(“Hello,WARN”); //默认黄色字体
ROS_ERROR(“hello,ERROR”);//默认红色字体
ROS_FATAL(“hello,FATAL”);//默认红色字体