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
版權聲明:本文爲白夜行的狼原創文章,未經允許不得以任何形式轉載