用CPP控制rosbag record的运行和关闭

0. 写在最前面

本文持续更新地址:https://haoqchen.site/2019/11/30/rosbag-run-and-kill-cpp/

我们经常会用rosbag来录一些ROS的消息进行离线调试什么的。如果是在终端运行,输入命令,然后Ctrl + C就可以运行和关闭了,但如果我想在C++程序里面去控制什么时候录包,什么时候停止录包呢?

这篇文章对以上的情形进行总结。

如果觉得写得还不错,可以找我其他文章来看看哦~~~可以的话帮我github点个赞呗。
你的Star是作者坚持下去的最大动力哦~~~

1. 终端操作

终端录包的指令可以参考ROS官网rosbag的介绍。这里以最简单的情形为例,录/top2record话题的数据,将其放到当前文件夹的bag_name.bag

rosbag record -O ./bag_name.bag /top2record

录完只要Ctrl + C就可以了。

2. CPP操作

rosbag提供了官方的CPP API,但是看着很难用,没有用熟了的命令行那么好用,所以这里是通过CPP启动终端运行命令行,而不是真的rosbag的官方API。

请注意代码中的空格。

录包:

std::string path = "./bag_name.bag";
std::string topics = " /top2record";
std::string node_name = " __name:=my_record_node";
std::string cmd_str = "gnome-terminal -x bash -c 'rosbag record -O " + path + topics + node_name + "'";
int ret = system(cmd_str.c_str()); // #include <stdlib.h>

这样就会弹出一个终端进行录包。这里之所以要通过__name:=加节点名称,是为了方便后面关闭,否则就只能用killall来杀掉所有record,如果没有这个进程会报错不说,还会因为没有正确关闭节点得到不正确的bag文件(killall没有发送终止命令给节点,即没有Ctrl + C)。

停止录包:

#include <ros/ros.h>

ros::V_string v_nodes;
ros::master::getNodes(v_nodes);

std::string node_name = std::string("/my_record_node");
auto it = std::find(v_nodes.begin(), v_nodes.end(), node_name.c_str());
if (it != v_nodes.end()){
    std::string cmd_str = "rosnode kill " + node_name;
    int ret = system(cmd_str.c_str());
    std::cout << "## stop rosbag record cmd: " << cmd_str << std::endl;
}

这样刚才那个弹框就会消失,录包成功。这里先利用ROS master来判断是否存在这个录包节点,如果存在,调用rosnode kill来终止这个node。

如果存在namespace请在名字中加上相应前缀std::string ns = nh_->getNamespace() + std::string("/");,如果没有ns,请记得在节点名字前加上斜杠。

参考

https://answers.ros.org/question/275441/start-and-kill-rosbag-record-from-bash-shell-script/


喜欢我的文章的话Star一下呗Star

版权声明:本文为白夜行的狼原创文章,未经允许不得以任何形式转载

  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,你需要先安装ROS和turtlebot3的相关软件,请参考官方文档安装。 然后,可以使用以下代码实现小乌龟走正方形的功能,并将其保存为一个ROS节点进行运行: ```cpp #include <ros/ros.h> #include <geometry_msgs/Twist.h> int main(int argc, char** argv) { ros::init(argc, argv, "square_turtle"); ros::NodeHandle nh; ros::Publisher vel_pub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 10); // Set up the geometry_msgs::Twist message geometry_msgs::Twist vel_msg; vel_msg.linear.x = 0.5; vel_msg.angular.z = 0.0; // Set the loop rate to 10 Hz ros::Rate loop_rate(10); // Set the time duration to move forward and turn double forward_time = 1.0; double turn_time = 0.75; // Loop to make the turtle move in a square for (int i = 0; i < 4; i++) { // Move forward for a set duration ros::Time start_time = ros::Time::now(); while (ros::Time::now() - start_time < ros::Duration(forward_time)) { vel_pub.publish(vel_msg); loop_rate.sleep(); } // Stop the turtle vel_msg.linear.x = 0.0; vel_pub.publish(vel_msg); ros::Duration(1.0).sleep(); // Turn the turtle for a set duration vel_msg.linear.x = 0.0; vel_msg.angular.z = 0.5; start_time = ros::Time::now(); while (ros::Time::now() - start_time < ros::Duration(turn_time)) { vel_pub.publish(vel_msg); loop_rate.sleep(); } // Stop the turtle vel_msg.angular.z = 0.0; vel_pub.publish(vel_msg); ros::Duration(1.0).sleep(); } return 0; } ``` 这个程序首先初始化ROS节点,并创建一个publisher,用于发布小乌龟的速度指令。然后设置小乌龟前进和转弯的时间,并通过循环来让小乌龟走正方形。在每个循环中,先让小乌龟前进一段时间,然后停止并等待一段时间,接着让小乌龟转弯一段时间,最后再次停止并等待一段时间。 注意,这个程序假设你使用的是turtlebot3的模拟器,如果你要在真实的机器人上运行,请确保安全并进行适当的调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值