【ROS】rosbag播放完毕后,rosservice call卡住无反应的解决

本文介绍了如何使用rosbag播放录制数据,结合cartographer进行建图,并解决rosbag结束后rosservice调用失效的问题,关键在于处理仿真时间和时钟同步。
部署运行你感兴趣的模型镜像

一、任务描述

播放录制好的 rosbag,使用 cartographer 建图,在 rosbag 播放完后保存所构建的地图。

二、步骤

1. 使用仿真时间
<!-- 在roslaunch中设置仿真时间 -->
<param name="/use_sim_time" value="true" />

# 在终端中设置仿真时间
rosparam get use_sim_time
rosparam set use_sim_time false
2. 播放数据包并启动建图
<!-- 在roslaunch中设置播放数据包 -->
    <node name="playbag" pkg="rosbag" type="play"
          args="--clock $(arg bag_filename)" />
# 用cartographer建图
roslaunch cartographer_ros xxx.launch bag_filename:=xxx.bag

rosbag play xxx.bag --clock # 播放数据包
roslaunch cartographer_ros xxx.launch # 用cartographer建图
3.保存地图
rosservice call /write_state ~/map1.pbstream true
rosrun cartographer_ros cartographer_pbstream_to_ros_map -map_filestem=map1 -pbstream_filename=map1.pbstream -resolution=0.05

# 自己写的直接保存pgm
rosservice call /save_pgm #TAB,填写参数

三、问题描述

rosbag 数据包播放完毕后,rosservice call没反应。

四、原因和解决方法

因为使用了仿真时间,且在rosbag play时附带参数--clock,也就是使用了 rosbag 的时间作为时钟,所以,随着rosbag 播放完毕,时钟也消失了。没有时钟就没有办法调用 rosservice。
解决思路:既然没有时钟,再制作一个时钟就可以了。

具体方法:
在播放完要建图的 rosbag 之后,再播放另一个 rosbag ,然后就可以正常rosservice call了。注意需要保证后一个 rosbag 没有包含建图会订阅的话题(/scan 乃至 /odom /imu等),以免 cartographer 又继续建图,干扰了建图效果。

rosbag play xxx.bag --clock

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

ROS(Robot Operating System)中,当你使用`roslaunch`命令启动了一个包含`rosbag play`的节点,该节点通常会持续运行直到`rosbag play`命令完成或者遇到错误。如果你想在`rosbag play`结束后自动关闭程序,一种常见的做法是在`rosbag play`前设置一个信号处理器或者监听特定的生命周期事件。 例如,你可以通过`rosservice call`发送一个服务请求来手动结束程序,或者当`rosbag`节点的状态改变时(如`rosnode list`显示的节点状态变为“shutdown”),你可以编写一个定时任务检查这个状态并停止程序。 这里有一个简单的Python示例,假设你有一个名为`stop_node_when_play_done`的服务: ```python import rospy from std_msgs.msg import Empty def stop_node_on_bag_end(): # 创建一个停止服务的对象 stop_service = rospy.ServiceProxy('stop_node_when_play_done', Empty) # 播放rosbag rosbag.play() # 监听服务调用 while not rospy.is_shutdown() and not rospy.wait_for_service('stop_node_when_play_done'): pass try: # 如果服务可用,发送停止信号 stop_service() print("Rosbag playback finished, stopping the node.") except (rospy.ServiceException, rospy.exceptions.ROSException) as e: print(f"Failed to stop node due to error: {e}") if __name__ == '__main__': rospy.init_node('play_and_stop') stop_node_on_bag_end() ``` 在这个例子中,你需要先创建一个名为`stop_node_when_play_done`的服务,并确保在`roslaunch`文件中正确地启动了它。当`rosbag play`完成后,该服务将接收请求并关闭节点。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值