ROS::message_filters中的一個報錯(mt::TimeStamp……)
『方便檢索』 ros::Time msg_time = mt::TimeStamp<typename mpl::at_c<Messages, i>::type>::value(msg);
1. 瞎扯一會兒:
博主是大學生,最近一直使用ROS進行機器人控制程式設計。由於專案需要對多個接受者(Subscriber)進行同時接收。於是決定使用ROS裡面的message_filters進行多訊息接受的同步。
官方連結如下:message_filters - ROS Wiki。
並參考學習了這篇文章:時間同步及在回撥函式中釋出ROS訊息_羅賓醬的部落格-CSDN部落格_ros時間同步函式
個人覺得上面的文章非常不錯。(強烈推薦!!!)
2. 遇見的問題:(Header header 的缺失)
主要報錯如下:
###最開始顯示的資訊:
/opt/ros/noetic/include/message_filters/sync_policies/approximate_time.h: In instantiation of ‘bool message_filters::sync_policies::ApproximateTime<M0, M1, M2, M3, M4, M5, M6, M7, M8>::checkInterMessageBound() [with int i = 0; M0 = rfid_reader::DataDev_<std::allocator<void> >; M1 = tracer_msgs::TracerStatus_<std::allocator<void> >; M2 = message_filters::NullType; M3 = message_filters::NullType; M4 = message_filters::NullType; M5 = message_filters::NullType; M6 = message_filters::NullType; M7 = message_filters::NullType; M8 = message_filters::NullType]’:
主要報錯如下:
/opt/ros/noetic/include/message_filters/sync_policies/approximate_time.h:170:85: error: ‘value’ is not a member of ‘ros::message_traits::TimeStamp<rfid_reader::DataDev_<std::allocator<void> >, void>’
170 | ros::Time msg_time = mt::TimeStamp<typename mpl::at_c<Messages, i>::type>::value(msg);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
/opt/ros/noetic/include/message_filters/sync_policies/approximate_time.h:181:86: error: ‘value’ is not a member of ‘ros::message_traits::TimeStamp<rfid_reader::DataDev_<std::allocator<void> >, void>’
181 | previous_msg_time = mt::TimeStamp<typename mpl::at_c<Messages, i>::type>::value(previous_msg);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
/opt/ros/noetic/include/message_filters/sync_policies/approximate_time.h:187:87: error: ‘value’ is not a member of ‘ros::message_traits::TimeStamp<rfid_reader::DataDev_<std::allocator<void> >, void>’
187 | previous_msg_time = mt::TimeStamp<typename mpl::at_c<Messages, i>::type>::value(previous_msg);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
報錯原因:
訊息型別中沒有Head,就是沒有時間戳資訊。所以不能夠同步。
解決方法:
在自定義訊息中新增 Header header 即可。(可以看一下鬆靈機器人的官方ROS包裡的原始碼,就像下面這樣),個人覺得看官方原始碼確實收穫不小。
新增後即可編譯成功:
!!!不要忘記
在Cmakelists.txt中的find_package新增message_filters
3. 學霸題,反思一下(C++與python的區別):
由於博主使用ROS C++與python ,在使用python時卻沒有出現相同的問題。那麼問題來了,what f**k ? 有必要研究一番,(下面是官方文件裡的c++與python中的相關程式碼部分)
//C++
typedef sync_policies::ApproximateTime<Image, Image> MySyncPolicy;
// ApproximateTime takes a queue size as its constructor argument, hence MySyncPolicy(10)
Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), image1_sub, image2_sub);
sync.registerCallback(boost::bind(&callback, _1, _2));
#python相關程式碼
ts = message_filters.ApproximateTimeSynchronizer([mode_sub, penalty_sub], 10, 0.1, allow_headerless=True)
我們注意到python程式碼中多了一個奇怪的引數『allow_headerless=True』,並且官方文件中給出了相關解釋:
如果某些訊息的型別不包含標頭欄位,則 ApproximateTimeSynchronizer 預設拒絕新增此類訊息。 但是,它的 Python 版本可以使用 allow_headerless=True 構建,它使用當前的 ROS 時間代替任何缺失的 header.stamp 欄位:
那麼終於可以解釋得通了(不得不吹一下python。不但numpy好用,還這麼貼心)。雖然但是,我還是主要使用C++(doge)。
如果幫到了你,可以麻煩點一個贊嗎?
(圖片來自網路,侵刪)
本文來自部落格園,作者:litecdows,轉載請註明原文連結:https://www.cnblogs.com/litecdows/p/15864391.html