
面試被問ROS2里常用的消息類型有哪些geometry_msgs里的Pose和PoseStamped有什么區(qū)別我說Pose是位置加姿態(tài)PoseStamped多了個(gè)時(shí)間戳。面試官說那Header里除了時(shí)間戳還有什么frame_id是干什么的這個(gè)問題看著簡單但很多人用了好久都沒搞明白frame_id的意義。今天把ROS2的消息類型系統(tǒng)講透。消息類型體系ROS2的消息類型分三大類std_msgs——基礎(chǔ)類型。String、Int32、Float64、Bool、Header這些。大部分時(shí)候你不會(huì)直接用它們傳輸傳感器數(shù)據(jù)但Header是幾乎所有復(fù)雜消息的基礎(chǔ)組成部分。sensor_msgs——傳感器數(shù)據(jù)。LaserScan激光雷達(dá)、PointCloud2點(diǎn)云、Image圖像、ImuIMU數(shù)據(jù)、NavSatFixGPS、JointState關(guān)節(jié)狀態(tài)。做機(jī)器人開發(fā)這些類型你得天天打交道。geometry_msgs——幾何數(shù)據(jù)。Point、Vector3、Quaternion、Pose、Twist、Transform、Wrench。這些類型描述的是空間中的位置、姿態(tài)、速度、力和坐標(biāo)變換。除了這三個(gè)還有nav_msgs導(dǎo)航相關(guān)路徑、地圖、里程計(jì)、action_msgsAction通信、trajectory_msgs軌跡、shape_msgs形狀描述等。Header消息的身份證幾乎所有復(fù)雜的ROS消息都有一個(gè)Header字段。Header包含三個(gè)信息stamp——時(shí)間戳。消息產(chǎn)生的時(shí)間。這個(gè)時(shí)間戳通常來自傳感器硬件或者驅(qū)動(dòng)不是你收到消息的時(shí)間。在時(shí)間同步要求高的場景里比如多傳感器融合這個(gè)時(shí)間戳至關(guān)重要。frame_id——參考坐標(biāo)系。消息中的數(shù)據(jù)是在哪個(gè)坐標(biāo)系下表達(dá)的。比如激光雷達(dá)的scan數(shù)據(jù)frame_id是laser_link表示這些數(shù)據(jù)是在激光雷達(dá)自身坐標(biāo)系下測量的。seq——序列號(hào)ROS1有ROS2去掉了。ROS2里用時(shí)間戳來標(biāo)識(shí)消息順序。frame_id為什么這么重要舉個(gè)例子你的激光雷達(dá)檢測到一個(gè)障礙物在雷達(dá)前方3米處。這個(gè)前方3米是相對于雷達(dá)坐標(biāo)系的。導(dǎo)航算法需要知道這個(gè)障礙物在世界坐標(biāo)系下的位置。如果沒有frame_id你就不知道這個(gè)數(shù)據(jù)該做怎樣的坐標(biāo)變換。geometry_msgs核心類型Point——三維空間中的一個(gè)點(diǎn)。只有x、y、z沒有方向信息。Vector3——三維向量。有大小和方向但沒有位置。和Point結(jié)構(gòu)相同但語義不同。Quaternion——四元數(shù)表示旋轉(zhuǎn)。x、y、z、w四個(gè)分量。相比歐拉角四元數(shù)沒有萬向鎖問題是機(jī)器人中表示姿態(tài)的標(biāo)準(zhǔn)方式。Pose——位姿。等于Point位置加Quaternion姿態(tài)。描述物體在空間中的位置和朝向。PoseStamped——帶Header的Pose。多了時(shí)間戳和frame_id。在Topic中傳輸位姿數(shù)據(jù)時(shí)幾乎總是用PoseStamped而不是Pose。Twist——速度。包含線速度Vector3 linear和角速度Vector3 angular。/cmd_vel這個(gè)Topic的消息類型就是geometry_msgs/Twist。TwistStamped——帶Header的Twist。Transform——坐標(biāo)變換。包含平移Vector3 translation和旋轉(zhuǎn)Quaternion rotation。TF2系統(tǒng)的核心數(shù)據(jù)類型。TransformStamped——帶Header的Transform。TF2發(fā)布和接收的都是TransformStamped。Wrench——力和力矩。包含力Vector3 force和力矩Vector3 torque。力/力矩傳感器的數(shù)據(jù)類型。sensor_msgs核心類型LaserScan——2D激光雷達(dá)數(shù)據(jù)。包含角度范圍、角度增量、距離數(shù)組、強(qiáng)度數(shù)組。一維數(shù)組每個(gè)元素對應(yīng)一個(gè)角度的測距值。PointCloud2——3D點(diǎn)云數(shù)據(jù)。二進(jìn)制格式支持任意字段組合xyz、rgb、intensity等。數(shù)據(jù)量大傳輸和存儲(chǔ)都需要注意效率。Image——圖像數(shù)據(jù)。包含寬高、編碼格式bgr8、rgb8、mono8等、像素?cái)?shù)據(jù)。大圖像傳輸時(shí)注意帶寬占用。CompressedImage——壓縮圖像。JPEG或PNG格式。帶寬友好但需要解壓適合遠(yuǎn)程傳輸。Imu——IMU數(shù)據(jù)。包含姿態(tài)Quaternion、角速度Vector3、線加速度Vector3每個(gè)都帶協(xié)方差矩陣。NavSatFix——GPS數(shù)據(jù)。經(jīng)緯度、海拔、定位精度。JointState——關(guān)節(jié)狀態(tài)。關(guān)節(jié)名、位置、速度、力的數(shù)組。機(jī)械臂控制中常用。nav_msgs核心類型OccupancyGrid——柵格地圖。二維數(shù)組每個(gè)格子表示被占據(jù)的概率0-100-1表示未知。導(dǎo)航系統(tǒng)的核心數(shù)據(jù)。Path——路徑。PoseStamped的數(shù)組表示一系列路徑點(diǎn)。路徑規(guī)劃器的輸出。Odometry——里程計(jì)。包含Header、子坐標(biāo)系ID、Pose位姿和Twist速度。底盤定位的基礎(chǔ)數(shù)據(jù)。MapMetaData——地圖元數(shù)據(jù)。分辨率、寬、高、原點(diǎn)位置。加載地圖時(shí)先獲取元數(shù)據(jù)再獲取完整地圖數(shù)據(jù)。消息類型選擇的經(jīng)驗(yàn)實(shí)際項(xiàng)目中消息類型的選擇有一些經(jīng)驗(yàn)。能用標(biāo)準(zhǔn)類型就不要自定義。標(biāo)準(zhǔn)類型是社區(qū)通用的其他工具和包都能直接使用。你自定義一個(gè)類型所有對接的包都要改。大數(shù)據(jù)類型注意效率。PointCloud2和Image的數(shù)據(jù)量很大。如果你的節(jié)點(diǎn)只是轉(zhuǎn)發(fā)數(shù)據(jù)不需要解析內(nèi)容可以用const std::shared_ptrconst sensor_msgs::msg::PointCloud2這種常量引用來避免拷貝。時(shí)間戳要統(tǒng)一。多傳感器融合時(shí)所有消息的時(shí)間戳必須對齊到同一個(gè)時(shí)鐘源。否則融合結(jié)果會(huì)出錯(cuò)。ROS2默認(rèn)用系統(tǒng)時(shí)鐘多機(jī)場景下需要用PTP或NTP同步時(shí)鐘。面試中怎么聊面試官問消息類型你可以說ROS2的消息類型分std_msgs、sensor_msgs、geometry_msgs三大類。Header包含時(shí)間戳和frame_idframe_id標(biāo)識(shí)數(shù)據(jù)所在的參考坐標(biāo)系是多傳感器融合和坐標(biāo)變換的基礎(chǔ)。geometry_msgs中Pose和PoseStamped的區(qū)別在于有沒有Header實(shí)際傳輸中通常用Stamped版本。cmd_vel用Twist類型TF2用TransformStamped類型。消息類型的選擇與優(yōu)化選擇合適的消息類型對系統(tǒng)性能有影響。比如發(fā)布角度數(shù)據(jù)時(shí)用std_msgs/Float64比用geometry_msgs/Quaternion更輕量發(fā)布位姿時(shí)如果只需要2D位置用自定義的簡單消息比用PoseStamped更高效。另外要注意消息的時(shí)間戳用builtin_interfaces/Time還是Header中的stamp字段取決于你是否需要坐標(biāo)系信息。還有一個(gè)容易忽略的點(diǎn)消息的序列化方式。ROS2默認(rèn)使用CDR序列化但某些場景下可能需要兼容其他格式。ros2 topic echo --no-arr可以緊湊顯示消息內(nèi)容調(diào)試時(shí)很方便。給你的建議打開終端用ros2 interface show命令看看這些消息類型的定義。比如ros2 interface show geometry_msgs/msg/PoseStamped看看它的結(jié)構(gòu)到底長什么樣。用ros2 interface list可以瀏覽全部消息類型對理解整個(gè)消息體系很有幫助。然后ros2 topic echo /scan --no-arr看看激光雷達(dá)數(shù)據(jù)的實(shí)際內(nèi)容。親手看過數(shù)據(jù)結(jié)構(gòu)比看十遍文檔都記得清楚。上一篇第120篇 ROS2 Launch進(jìn)階——參數(shù)傳遞、條件啟動(dòng)和節(jié)點(diǎn)編排下一篇預(yù)告第122篇 自定義消息類型——rosidl與接口設(shè)計(jì)