当前位置: 代码迷 >> 综合 >> ROS(4)--------------------ros::Rate loop_rate( ) loop_rate.sleep()ros_spin()ros_spinOnce()
  详细解决方案

ROS(4)--------------------ros::Rate loop_rate( ) loop_rate.sleep()ros_spin()ros_spinOnce()

热度:50   发布时间:2023-11-25 13:27:52.0

ros::Rate是一个类

1 ros::Rate loop_rate( ) & loop_rate.sleep()

这两个函数必须一起使用,控制的是循环的频率,与消息或者服务的发布频率无直接关系,当然控制了循环的频率自然就控制了循环内消息或者服务的发布频率

ros::Rate loop_rate( ); 写在循环外部 //ros::Rate rate();
loop_rate.sleep();写在循环内部 //rate.sleep();

ros::Rate loop_rate(50) 这个很好理解,我的程序如果在不断地发布信息,那么有时候我会想控制发布的信息的快慢,这行表示你希望你发布信息的速度为50Hz,这个函数要和**loop_rate.sleep()**配合使用才能达到控制速度目的。

这个频率是指运行上一次loop.sleep()到下一次loop.sleep()之间保持的时间,通常情况下,代码运行速度比设定的频率要快,所以如果运行到下一次loop.sleep()后未达到0.02s(1/50Hz),则会开始休眠,等到0.02s后再执行下一句程序。

2 ros_spin()&ros_spinOnce()

参考:
https://blog.csdn.net/qq_42037180/article/details/100531348?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.compare&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.compare

spin:旋转,这里是指ROS信息数据(消息或者服务)的轮转。

2.1 ros_spin()&ros_spinOnce()的作用对象


集 中 处 理 本 节 点 所 有 的 回 调 函 数 !
集 中 处 理 本 节 点 所 有 的 回 调 函 数 !
集 中 处 理 本 节 点 所 有 的 回 调 函 数 !

所以,有回调函数,就必须设置 ros_spin()和ros_spinOnce()!

一般subscriber和server有回调函数

ros_spin()和ros_spinOnce()并不直接处理节点订阅的消息或者服务的requeset,而是控制callback函数的使用,实际处理节点订阅的消息或者服务的requeset的是callback函数。

2.2 ros的消息接收机制


在ros中提到消息,就是指topic通信中的messages。但是在此处,service的request和response的接收机制和messages的类似。

任何一个发布和订阅,都会有其对应的发布缓存区和订阅缓存区,正如publisher和subscriber函数中都有缓存数量的参数(队列长度)。

publisher在一个while里面一直循环发送“hello world”到话题(topic) chatter上。
subscriber一旦知道chatter上面有data,就会将这data作为参数传入callback函数中。
但是此时还没有执行callback函数,而是把callback函数放到了一个回调函数队列中。所以当发布器不断发送data到chatter上面时,就会有相应的callback函数进入队列中,它们函数名一样,只是实参不一样

那么什么时候才会执行callback函数呢?

就是ros::spin()和ros::spinOnce()的事了。

当spinOnce函数被调用时,spinOnce就会调用回调函数队列中第一个callback函数,此时callback函数才被执行,然后等到下次spinOnce函数又被调用时,回调函数队列中第二个callback函数就会被调用,以此类推。

spin()和spinOnce()起到开关的作用,也就是说消息经过spin()或者spinOnce()后才恢复轮转。

2.3 spinOnce()

当程序运行到spinOnce()时,程序到相应的topic订阅缓存区查看是否存在消息,如果有消息,则将消息传入回调函数执行回调函数;如果没有消息则继续向后执行。spinOnce()并不是等待到一个消息才向后执行,而是查看有没有消息!

2.4 spin()

当程序运行到spin()时,程序同样去相应的topic订阅缓存区查看是否有消息,如果有消息,则将消息传入回调函数;如果没有消息则重复上述过程。因此spin()可以当作是对spinOnce()的循环,即:

while(1)
{
    ros::spinOnce();
}

显然,spin()后面的代码将不会再被执行,表现出来的功能就是持续等待消息。

  相关解决方案