ROS话题queue_size的含义与设置技巧

ROS1中发布和订阅话题时,都需要设置queue_size,参考:

roscpp/Overview/Publishers and Subscribers - ROS Wiki

rospy/Overview/Publishers and Subscribers - ROS Wiki

1. 发布话题

# roscpp
ros::Publisher publisher = nh.advertise<std_msgs::String>("topic_name", 10)
# rospy
pub = rospy.Publisher('topic_name', std_msgs.msg.String, queue_size=10)

以上publisher中的10就是queue_size,大小并不太重要,一般设置为超过1就行。

roscpp的publish()是异步的(不阻塞),rospy中的publish()在指定了queue_size后也是异步的(否则默认是同步的)。这意味着publish(msg)并不会阻塞程序。

需要发布的消息msg被publish(msg)后,需要经过序列化(serialize)存入缓冲区(queue),然后缓冲区的消息依次发送。异步模式下,当你“publish消息的速度/频率”比“序列化和发送消息的速度/频率”更快时,缓冲区就会逐渐被填满达到queue_size,然后旧的消息就会被丢弃。这会导致实际发送的消息并不是最新的,而是积压了一个queue之前的。

但事实上,一般话题消息序列化和本地TCP发送所需的时间很短,你publish消息的频率很难超过序列化和发送的处理能力,因此queue_size设置为大概10就行。

如果话题消息内容很大,比如是图像或者点云,那么为了保证发布和订阅的实时性,一般要另外使用nodelet来实现节点间消息传输的零拷贝,即略去了序列化和反序列化过程。

2. 订阅话题

# roscpp
ros::Subscriber sub = nh.subscribe("topic_name", 1, callback, ros::TransportHints().tcpNoDelay())
# rospy
rospy.Subscriber("topic_name", std_msgs.msg.String, callback, queue_size=1)

以上subscriber中的1就是queue_size,大小很重要,需要最新消息的时候queue_size要设置成1,不能遗漏消息时queue_size要设置大一些。

新消息收到后,会触发callback()函数执行,但是callback()函数是我们自己定义的,可能执行所需时间较长,就会阻塞住这个接收线程,之后新来的消息会存入queue中。对于不断传输的实时数据流,如果接收消息的频率大于处理的能力(callback函数运行的最高频率),那么queue中的消息就会积压,满了之后旧消息就会被丢弃。这会导致callback当前处理的消息是队列中积压已久的之前的消息。

对于数据实时性要求高的应用,callback函数要写的尽可能简单,避免执行时间过长。同时queue_size要设置成1。

对于非实时数据流、不能遗漏任何一次消息的情况,比如发送的一些指令话题,queue_size要设置尽可能的大,比如rospy中默认设置成为None,roscpp中设置成0,都意味着queue_size无穷大(危险,尽量不要这么设置)。

还要特别注意,rospy中Subscriber默认queue_size不设置时是None,即队列无穷大,一般需要手动设置为1。而且rospy的Subscriber的queue_size只能设置为1或者None,设置为其他数时并不是依次丢弃旧数据,而是一次性接收queue_size个数据!

参考:rospy.topics.Subscriber

### 关于ROS中机器人自主定位 在ROS环境中,机器人的自主定位主要依赖于`amcl`包(自适应蒙特卡洛定位),该算法通过粒子滤波器估计机器人在其已知地图中的位置[^1]。为了使机器人能够执行这一功能,通常需要安装`navigation`套件,这可以通过命令`sudo apt install ros-noetic-navigation`来完成对于ROS Noetic版本而言[^2]。 #### 使用AMCL进行定位的具体流程 - **启动环境**:确保已经加载了静态的地图服务器节点,并且发布了地图数据到指定话题。 - **初始化AMCL节点**:配置参数文件以适配具体的硬件平台特性,比如激光雷达型号等传感器接口设置;之后运行AMCL节点让其订阅来自这些传感器的数据流以便更新内部状态估计。 ```bash roslaunch my_robot_navigation amcl.launch map_file:=<path_to_map> ``` 此处假设存在一个名为`my_robot_navigation`的工作空间目录结构下的launch脚本集,其中包含了针对特定应用定制化的启动项定义[^3]。 #### 配置调试技巧 当遇到定位不准确或者完全失败的情况时,可以从以下几个方面入手排查: - 检查传感器输入是否正常工作; - 调整AMCL参数如粒子数量、初始分布范围等提高鲁棒性和精度; - 确认所使用的地图质量良好无明显误差源影响匹配效果。 #### 示例代码片段展示如何发布初始位姿猜测给AMCL ```python import rospy from geometry_msgs.msg import PoseWithCovarianceStamped def set_initial_pose(): pub = rospy.Publisher('/initialpose', PoseWithCovarianceStamped, queue_size=10) rospy.init_node('set_init_pose') initial_pose = PoseWithCovarianceStamped() # 设置起始姿态的位置坐标(x,y,z)和四元数表示的角度(qx,qy,qz,w),这里仅作为例子给出固定值 initial_pose.pose.pose.position.x = 0.5 initial_pose.pose.pose.orientation.w = 1.0 rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown() and pub.get_num_connections() < 1: rate.sleep() pub.publish(initial_pose) if __name__ == '__main__': try: set_initial_pose() except rospy.ROSInterruptException: pass ``` 这段简单的Python程序演示了怎样向AMCL提供一个预估的起始位置信息,这对于某些场景下帮助系统更快收敛至正确解非常重要。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值