歡迎來(lái)到第七講,我居然能寫(xiě)這么多,撒花J蜇摇旭贬!
rosbag是用來(lái)儲(chǔ)存ros消息的東西。
在我們平時(shí)處理一些robotics問(wèn)題的時(shí)候吟税,我們得到一些數(shù)據(jù)凹耙,有些時(shí)候我們需要實(shí)時(shí)的處理,即獲得數(shù)據(jù)肠仪,寫(xiě)好的程序分析數(shù)據(jù)然后得出結(jié)果肖抱,但另一些時(shí)候我們只是想采集數(shù)據(jù),事后分析异旧,這些數(shù)據(jù)存儲(chǔ)在哪兒呢意述?就存儲(chǔ)在rosbag里了。
那么這一講我們就要搞定兩個(gè)簡(jiǎn)單的問(wèn)題
1:如何使用rosbag采集數(shù)據(jù)
2:如何重新使用儲(chǔ)存在rosbag里的數(shù)據(jù)
使用rosbag采集數(shù)據(jù)
對(duì)于第一個(gè)問(wèn)題吮蛹,我們用之前的寫(xiě)的程序來(lái)講解荤崇。還記得在第三講,我們寫(xiě)過(guò)一個(gè)pub_poseStamped.cpp的程序潮针,什么术荤?你是直接跳到這兒來(lái)的?那簡(jiǎn)單解釋一下那個(gè)程序就是模仿我們有一個(gè)傳感器每篷,能每隔100ms獲取機(jī)器人的位置和方向瓣戚,并放到poseStamped這個(gè)消息類(lèi)型中發(fā)布出來(lái)。那么接下來(lái)我們就使用rosbag來(lái)采集這個(gè)假的傳感器所發(fā)布出來(lái)的數(shù)據(jù)焦读。
rosbag在采集數(shù)據(jù)時(shí)自身相當(dāng)于一個(gè)subscriber程序
最開(kāi)始幾講你寫(xiě)一個(gè)publisher文件子库,就要寫(xiě)有一個(gè)subscriber文件,他們總是成雙成對(duì)地出入矗晃。那么當(dāng)你用rosbag采集數(shù)據(jù)時(shí)仑嗅,你有publisher就行了,不需要再寫(xiě)subscriber文件了。
那么具體怎么實(shí)施呢无畔?
首先啟動(dòng)roscore啊楚,rosbag才能記錄數(shù)據(jù)。
然后建立一個(gè)叫dataset的文件夾專(zhuān)門(mén)來(lái)儲(chǔ)存這些數(shù)據(jù)浑彰,cd到那個(gè)文件夾去
然后在terminal中恭理,寫(xiě)入下面內(nèi)容
rosbag record /chatter -O record_poseStamped
這行命令第一個(gè)是表示我們要使用rosbag相關(guān)命令了,第二個(gè)record表示我們想要采集(記錄)數(shù)據(jù)郭变。
第三個(gè)颜价,由于我們之前說(shuō)了,rosbag在采集數(shù)據(jù)時(shí)自身相當(dāng)于一個(gè)subscirber程序诉濒,既然要subscribe周伦,那么我們肯定需要指定subscriber哪個(gè)topic了,觀察我們?cè)趐ub_poseStamped.cpp中未荒,定義topic那一行我們定義的topic的名字是chatter专挪,于是我們就在第三個(gè)參數(shù)寫(xiě)入/chatter
表示記錄這個(gè)topic發(fā)布出來(lái)的信息。rosbag可以同時(shí)記錄多個(gè)topic的信息片排,你只需要在record后接/topicA /topicB /topicC....
即可寨腔。
命令行中-O及其后面的參數(shù),是用來(lái)給bag文件命名的率寡。我們?cè)谟涗浗Y(jié)束之后迫卢,rosbag的名字就會(huì)是record_poseStamped.bag
,(如果參數(shù)是-o冶共,那么記錄名字會(huì)自動(dòng)加上年月日時(shí)間乾蛤,比如上面的例子如果用rosbag record /chatter -o record_poseStamped
,輸出會(huì)是record_poseStamped-2019-09-08-15-24-05.bag
)捅僵。按下確認(rèn)鍵后家卖,你會(huì)看到下面的消息
[ INFO] [1551144307.272157111]: Subscribing to /chatter
[ INFO] [1551144307.274766644]: Recording to record_poseStamped.bag.
表示已經(jīng)在開(kāi)始記錄chatter發(fā)布的消息了,消息會(huì)存儲(chǔ)到record_poseStamped.bag里命咐。如果topic沒(méi)有消息發(fā)布篡九,那么自然不會(huì)有任何東西會(huì)儲(chǔ)存到這個(gè)rosbag文件里,這個(gè)文件會(huì)一直處于檢測(cè)是否有消息發(fā)布的狀態(tài)醋奠。你如果去看dataset文件夾里的圖標(biāo)榛臼,會(huì)發(fā)現(xiàn)一個(gè)叫record_poseStamped.bag.active的文件,表示這個(gè)bag文件目前正在處于記錄的狀態(tài)窜司。
之后我們打開(kāi)另一個(gè)terminal沛善,輸入下面的命令
cd ~/catkin_ws
source devel/setup.bash
rosrun pub_sub_test pub_poseStamped
把pub_poseStamped跑起來(lái)。你應(yīng)該看到print出很多信息塞祈,這時(shí)候你觀察跑rosbag那個(gè)terminal金刁,什么也沒(méi)有輸出。 你可能會(huì)擔(dān)心,到底是不是在記錄發(fā)布出來(lái)的消息尤蛮。rosbag里的topic名字和你publisher的名字是在對(duì)應(yīng)上的媳友,就一定在記錄。極少數(shù)情況rosbag會(huì)拒絕記錄新的消息产捞,比如你的磁盤(pán)空間小于一個(gè)G了醇锚,rosbag會(huì)自動(dòng)停止記錄,如果你的磁盤(pán)空間小于5個(gè)G了坯临,會(huì)出現(xiàn)warning但是不影響記錄焊唬。
有些時(shí)候?qū)懗绦虻娜瞬⒉粫?huì)把publisher發(fā)布的消息print出來(lái),你如果有成千上萬(wàn)條消息發(fā)布都print出來(lái)確實(shí)很煩看靠。這時(shí)候你publisher的terminal中沒(méi)什么信息print出來(lái)赶促,rosbag的terminal中沒(méi)什么信息print出來(lái),你可能慌得一匹挟炬,不知道消息有沒(méi)有被發(fā)布出來(lái)鸥滨。你可以用下面的方式檢查一下你的topic有沒(méi)有發(fā)布消息。
打開(kāi)另一個(gè)terminal谤祖,輸入
rostopic echo /chatter
這行命令會(huì)把你chatter這個(gè)topic發(fā)布的命令print到terminal中爵赵。按下確認(rèn)之后你會(huì)安心地看到下面的內(nèi)容。
上面那行命令其實(shí)也相當(dāng)于你跑了一個(gè)subscriber并且把收到的消息print出來(lái)泊脐。并且格式固定∷盖停可以看到每一則消息由
---
分開(kāi)容客。然后顯示出你消息的header(我們第三講講過(guò)header這個(gè)包含的成員由seq,stamp,frame_id,他們分別對(duì)應(yīng)uint32,time,string類(lèi)型的變量约郁,沒(méi)有印象了可以再回去回顧)缩挑。同時(shí)print出來(lái)了pose的內(nèi)容,即position和orientation鬓梅。當(dāng)你覺(jué)得記錄到足夠的數(shù)據(jù)之后供置,點(diǎn)擊rosbag在運(yùn)行的那個(gè)terminal并按下
ctrl+c
,rosbag就會(huì)停止記錄并被保存下來(lái)了绽快。每次記錄完數(shù)據(jù)芥丧,我們都要馬上檢查一下是否記錄成功。這時(shí)候我們?cè)趖erminal中使用下面的命令可以看到rosbag的信息
rosbag info record_poseStamped.bag
運(yùn)行這行命令坊罢,我們可以看到下面的信息续担。
其中我們可以看到這個(gè)bag文件記錄了多少消息,記錄的是哪個(gè)topic的消息活孩,消息的類(lèi)型是什么等物遇。讀者自行研究了。
至此利用rosbag采集(記錄)數(shù)據(jù)工作就完成了。
重新使用儲(chǔ)存在rosbag內(nèi)的數(shù)據(jù)
當(dāng)你采集完成數(shù)據(jù)之后询兴,要拿回去分析乃沙,這時(shí)你就需要重新把儲(chǔ)存在bag里的消息發(fā)布出來(lái)。
首先確保roscore已經(jīng)運(yùn)行诗舰,cd到你rosbag所在的文件夾警儒,然后執(zhí)行下面的命令
rosbag play record_poseStamped.bag
這時(shí)你會(huì)看到下面的內(nèi)容
表示bag已經(jīng)在發(fā)布消息了。上面的操作是什么意思呢始衅?
當(dāng)你重新使用rosbag的數(shù)據(jù)(即使用rosbag play bag_name.bag)的時(shí)候冷蚂,你的rosbag自身相當(dāng)于一個(gè)publisher程序。
你的消息會(huì)在rosbag記錄的topic的名字下重新發(fā)布出來(lái)汛闸。如果你打開(kāi)一個(gè)terminal蝙茶,重新運(yùn)行我們之前的sub_poseStamped.cpp對(duì)用的那個(gè)node,即在新的terminal中source之后運(yùn)行
rosrun pub_sub_test sub_poseStamped
你應(yīng)該會(huì)看到和第三講里面同事運(yùn)行pub和sub程序時(shí)一樣的內(nèi)容诸老。只不過(guò)這時(shí)候我們的rosbag取代了那個(gè)pub程序而已隆夯。
這兒稍微值得注意的一點(diǎn)是,我們上面print出來(lái)的Bag Time
是這個(gè)rosbag收到每一則消息時(shí)的時(shí)間别伏,并不是我們poseStamped里那個(gè)stamp儲(chǔ)存的時(shí)間蹄衷。
總結(jié)
這么快就總結(jié)了,我是不是越來(lái)越懶了厘肮,飄了...不是滴愧口,主要是關(guān)于rosbag最主要的作用就是兩個(gè):作為subscriber接收信息并儲(chǔ)存,作為publisher重新發(fā)布信息类茂,沒(méi)有太多需要解釋的耍属。雖然其實(shí)rosbag ...
后面還可以跟許多命令。詳情可以見(jiàn)
http://wiki.ros.org/rosbag/Commandline
比如網(wǎng)頁(yè)中在rosbag record部分巩检,你可以在rosbag record后接--duration命令指定最長(zhǎng)記錄多少時(shí)間厚骗;
rosbag play部分,你可以在rosbag play 后接--pause命令兢哭,這樣你開(kāi)始運(yùn)行bag時(shí)不發(fā)布數(shù)據(jù)领舰,直到你按下空格鍵它才開(kāi)始發(fā)布,同樣你再按空格鍵rosbag又會(huì)暫停發(fā)布迟螺。
rosbag filter部分冲秽,你可以使用rosbag filter 命令拆分一個(gè)rosbag。正如filter部分中的例子所說(shuō)
rosbag filter input.bag output.bag "t.to_sec() <= 1284703931.86"
上面的命令需要你有inputbag矩父,然后它會(huì)把Bag Time<=1284703931.86的部分提取出來(lái)劳跃,重新放到一個(gè)新的ouput.bag里。這個(gè)命令在你bag文件很大你只需要其中一部分時(shí)還是很管用的浙垫。記錄圖片的rosbag動(dòng)不動(dòng)就幾十個(gè)G.
總是記住它最基礎(chǔ)的作用然后你根據(jù)你的需要去慢慢研究使用更高級(jí)的命令刨仑。
前面七講我們說(shuō)了發(fā)布接收了那么多數(shù)據(jù)郑诺,是時(shí)候把數(shù)據(jù)可視化一下了。下一講我們學(xué)習(xí)一下rviz的基礎(chǔ)杉武,這是ros自帶的強(qiáng)大的可視化程序辙诞。