尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

第121篇 ROS2消息类型——std_msgs/sensor_msgs/geometry_msgs详解

第121篇 ROS2消息类型——std_msgs/sensor_msgs/geometry_msgs详解 面试被问ROS2里常用的消息类型有哪些geometry_msgs里的Pose和PoseStamped有什么区别我说Pose是位置加姿态PoseStamped多了个时间戳。面试官说那Header里除了时间戳还有什么frame_id是干什么的这个问题看着简单但很多人用了好久都没搞明白frame_id的意义。今天把ROS2的消息类型系统讲透。消息类型体系ROS2的消息类型分三大类std_msgs——基础类型。String、Int32、Float64、Bool、Header这些。大部分时候你不会直接用它们传输传感器数据但Header是几乎所有复杂消息的基础组成部分。sensor_msgs——传感器数据。LaserScan激光雷达、PointCloud2点云、Image图像、ImuIMU数据、NavSatFixGPS、JointState关节状态。做机器人开发这些类型你得天天打交道。geometry_msgs——几何数据。Point、Vector3、Quaternion、Pose、Twist、Transform、Wrench。这些类型描述的是空间中的位置、姿态、速度、力和坐标变换。除了这三个还有nav_msgs导航相关路径、地图、里程计、action_msgsAction通信、trajectory_msgs轨迹、shape_msgs形状描述等。Header消息的身份证几乎所有复杂的ROS消息都有一个Header字段。Header包含三个信息stamp——时间戳。消息产生的时间。这个时间戳通常来自传感器硬件或者驱动不是你收到消息的时间。在时间同步要求高的场景里比如多传感器融合这个时间戳至关重要。frame_id——参考坐标系。消息中的数据是在哪个坐标系下表达的。比如激光雷达的scan数据frame_id是laser_link表示这些数据是在激光雷达自身坐标系下测量的。seq——序列号ROS1有ROS2去掉了。ROS2里用时间戳来标识消息顺序。frame_id为什么这么重要举个例子你的激光雷达检测到一个障碍物在雷达前方3米处。这个前方3米是相对于雷达坐标系的。导航算法需要知道这个障碍物在世界坐标系下的位置。如果没有frame_id你就不知道这个数据该做怎样的坐标变换。geometry_msgs核心类型Point——三维空间中的一个点。只有x、y、z没有方向信息。Vector3——三维向量。有大小和方向但没有位置。和Point结构相同但语义不同。Quaternion——四元数表示旋转。x、y、z、w四个分量。相比欧拉角四元数没有万向锁问题是机器人中表示姿态的标准方式。Pose——位姿。等于Point位置加Quaternion姿态。描述物体在空间中的位置和朝向。PoseStamped——带Header的Pose。多了时间戳和frame_id。在Topic中传输位姿数据时几乎总是用PoseStamped而不是Pose。Twist——速度。包含线速度Vector3 linear和角速度Vector3 angular。/cmd_vel这个Topic的消息类型就是geometry_msgs/Twist。TwistStamped——带Header的Twist。Transform——坐标变换。包含平移Vector3 translation和旋转Quaternion rotation。TF2系统的核心数据类型。TransformStamped——带Header的Transform。TF2发布和接收的都是TransformStamped。Wrench——力和力矩。包含力Vector3 force和力矩Vector3 torque。力/力矩传感器的数据类型。sensor_msgs核心类型LaserScan——2D激光雷达数据。包含角度范围、角度增量、距离数组、强度数组。一维数组每个元素对应一个角度的测距值。PointCloud2——3D点云数据。二进制格式支持任意字段组合xyz、rgb、intensity等。数据量大传输和存储都需要注意效率。Image——图像数据。包含宽高、编码格式bgr8、rgb8、mono8等、像素数据。大图像传输时注意带宽占用。CompressedImage——压缩图像。JPEG或PNG格式。带宽友好但需要解压适合远程传输。Imu——IMU数据。包含姿态Quaternion、角速度Vector3、线加速度Vector3每个都带协方差矩阵。NavSatFix——GPS数据。经纬度、海拔、定位精度。JointState——关节状态。关节名、位置、速度、力的数组。机械臂控制中常用。nav_msgs核心类型OccupancyGrid——栅格地图。二维数组每个格子表示被占据的概率0-100-1表示未知。导航系统的核心数据。Path——路径。PoseStamped的数组表示一系列路径点。路径规划器的输出。Odometry——里程计。包含Header、子坐标系ID、Pose位姿和Twist速度。底盘定位的基础数据。MapMetaData——地图元数据。分辨率、宽、高、原点位置。加载地图时先获取元数据再获取完整地图数据。消息类型选择的经验实际项目中消息类型的选择有一些经验。能用标准类型就不要自定义。标准类型是社区通用的其他工具和包都能直接使用。你自定义一个类型所有对接的包都要改。大数据类型注意效率。PointCloud2和Image的数据量很大。如果你的节点只是转发数据不需要解析内容可以用const std::shared_ptrconst sensor_msgs::msg::PointCloud2这种常量引用来避免拷贝。时间戳要统一。多传感器融合时所有消息的时间戳必须对齐到同一个时钟源。否则融合结果会出错。ROS2默认用系统时钟多机场景下需要用PTP或NTP同步时钟。面试中怎么聊面试官问消息类型你可以说ROS2的消息类型分std_msgs、sensor_msgs、geometry_msgs三大类。Header包含时间戳和frame_idframe_id标识数据所在的参考坐标系是多传感器融合和坐标变换的基础。geometry_msgs中Pose和PoseStamped的区别在于有没有Header实际传输中通常用Stamped版本。cmd_vel用Twist类型TF2用TransformStamped类型。消息类型的选择与优化选择合适的消息类型对系统性能有影响。比如发布角度数据时用std_msgs/Float64比用geometry_msgs/Quaternion更轻量发布位姿时如果只需要2D位置用自定义的简单消息比用PoseStamped更高效。另外要注意消息的时间戳用builtin_interfaces/Time还是Header中的stamp字段取决于你是否需要坐标系信息。还有一个容易忽略的点消息的序列化方式。ROS2默认使用CDR序列化但某些场景下可能需要兼容其他格式。ros2 topic echo --no-arr可以紧凑显示消息内容调试时很方便。给你的建议打开终端用ros2 interface show命令看看这些消息类型的定义。比如ros2 interface show geometry_msgs/msg/PoseStamped看看它的结构到底长什么样。用ros2 interface list可以浏览全部消息类型对理解整个消息体系很有帮助。然后ros2 topic echo /scan --no-arr看看激光雷达数据的实际内容。亲手看过数据结构比看十遍文档都记得清楚。上一篇第120篇 ROS2 Launch进阶——参数传递、条件启动和节点编排下一篇预告第122篇 自定义消息类型——rosidl与接口设计
返回列表