用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

版權聲明:本文爲白夜行的狼原創文章,未經允許不得以任何形式轉載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章