Wiki
loam_interface(Point-LIO输出的坐标与话题适配)
Existing English translations were reused. 5 current source blocks remain in Simplified Chinese, without triggering paid translation.
1.loam_interface(Point-LIO输出的坐标与话题适配)
This node connects the pose and registered scan of Point-LIO to the subsequent navigation interface: it subscribes to aft_mapped_to_init and cloud_registered and publishes lidar_odometry and registered_scan. It performs coordinate transformation, is not responsible for SLAM estimation, and does not directly publish the TF of odom → base_footprint.
The following is verified against the current source code and physical YAML as of 2026-10-10. The parameter names and current values can be confirmed, but there are source-code doubts regarding the complete pose transformations of the IMU, LiDAR, and chassis; having output on a topic cannot be equated with the coordinate relationships being correct.
1.1.参数
1.1.1.ros__parameters (ROS node parameters)
1.1.1.1.Parameter table
loam_interface:
ros__parameters:
use_sim_time: False
state_estimation_topic: "aft_mapped_to_init"
registered_scan_topic: "cloud_registered"
odom_frame: "odom"
base_frame: "base_footprint"
lidar_frame: "front_mid360"
| Parameter | Current value | Units | Hardware guidance | Purpose | Effect of increasing | Effect of decreasing | Activation conditions / notes |
|---|---|---|---|---|---|---|---|
use_sim_time |
False |
Not applicable; boolean | Verify and configure correctly before running on hardware | Select the time source for the node and TF buffer | Not applicable | Not applicable | Standard ROS2 parameter; usually False on hardware, True in simulation with /clock; the complete launch overrides the YAML value. Input timestamps are not converted |
state_estimation_topic |
"aft_mapped_to_init" |
Not applicable; topic name | Verify and configure correctly before running on hardware | Specify the input pose topic, of type nav_msgs/msg/Odometry |
Not applicable | Not applicable | Currently corresponds to Point-LIO’s camera_init → body pose message; body is the internal IMU, but the code uses it as a LiDAR pose; see below |
registered_scan_topic |
"cloud_registered" |
Not applicable; topic name | Verify and configure correctly before running on hardware | Specify the input registered scan, of type sensor_msgs/msg/PointCloud2 |
Not applicable | Not applicable | Point coordinates are currently in camera_init, already transformed using LiDAR→IMU extrinsics by Point-LIO. Do not replace them with a raw scan or cloud_registered_body |
odom_frame |
"odom" |
Not applicable; frame name | Usually keep the current value; not a priority for tuning | Specify the reference frame name for output point clouds and odometry | Not applicable | Not applicable | Transforms data using a cached matrix, then sets the output name. It does not query TF for an arbitrary target frame or publish the corresponding TF. The name alone does not ensure correct leveling or gravity direction |
base_frame |
"base_footprint" |
Not applicable; frame name | Verify and configure correctly before running on hardware | Specify the target body frame for the first TF query, used to build the initial alignment cache | Not applicable | Not applicable | Query lookupTransform(base_frame, lidar_frame, 输入位姿时间戳, 0.5秒); no further queries after the first success. The standalone launch specifies gimbal_yaw, unlike the complete configuration |
lidar_frame |
"front_mid360" |
Not applicable; frame name | Verify and configure correctly before running on hardware | Specify the source frame for the first TF query and the child frame name for output odometry | Not applicable | Not applicable | Points to the LiDAR frame. Setting this name does not automatically convert an internal IMU pose into a LiDAR pose. The currently missing extrinsic transformation requires a separate fix |
All six items have an effect; this block has no parameters that are currently completely uninvolved in operation. The five service parameters are only read at construction time, and the source code has no runtime update handling; writing parameters with the same names during operation will not rebuild subscriptions or update caches, and must be applied during a separately authorized restart.use_sim_time Managed by ROS2, not belonging to these five items.
1.1.1.2.Parameter Details
1.1.1.2.1.use_sim_time (system time and simulation time selection)
False uses system time; True uses the ROS time provided by /clock. The TF cache uses the node clock; Point-LIO, joint TF, and this node must be in a consistent time domain.
This node does not retimestamp input poses with the current time. Switching time sources does not correct LiDAR point-time units, sensor clock synchronization or old timestamps. The earlier seconds versus microseconds inconsistency in the simulation converter remains unresolved.
1.1.1.2.2.state_estimation_topic and registered_scan_topic (input odometry and registered point cloud)
| Direction | Topic | Message and coordinate semantics |
|---|---|---|
| Subscribe | aft_mapped_to_init |
Odometry; reference frame camera_init, child frame body; values describe the internal IMU pose |
| Subscribe | cloud_registered |
PointCloud2; registered point coordinates from the current scan, in reference frame camera_init |
| Publish | lidar_odometry |
Odometry; reference frame name set to odom, child frame name set to front_mid360; the numerical semantics still require verification |
| Publish | registered_scan |
PointCloud2; transforms point coordinates with a cached matrix and sets the reference frame name to odom |
The queue depth for both subscriptions and both publications is 5. The input topic name is a relative name, resolved according to the node namespace and remapping; the coordinate system string does not automatically add the node namespace. The two output topic names are fixed in the source code and cannot be renamed by modifying the input parameters.
Position and point coordinates follow the upstream m, orientation uses a dimensionless quaternion, and timestamps are expressed by seconds and nanoseconds fields; this node does not scale units, does not downsample again, and does not perform time synchronization between the two inputs. Odometry follows the input pose timestamp, and normal point cloud conversion follows the input point cloud timestamp; the latter has been checked against the container-installed pcl_ros 2.4.5 corresponding implementation.
This node only writes the pose of the output odometry and does not forward the input velocity and covariance. These fields remain at their default zero values, and this cannot be used to determine that the vehicle is stationary or that there is no uncertainty in the estimate.
1.1.1.2.3.odom_frame (output odometry and point cloud reference frame)
Currently keep odom. The node performs a rigid transformation on the point cloud, left-multiplies the same cached matrix to the pose, and then fills in the output reference frame name. It does not verify whether the input pose's header.frame_id and child_frame_id meet expectations, nor does it query camera_init → odom by input name.
Therefore, changing to another name will not automatically obtain the transformation of that reference frame.odom is the output naming; the actual axes, origin, and gravity relationship depend on the cache and Point-LIO initialization, and correctness cannot be determined by the name.
1.1.1.2.4.base_frame (initializes the baseline chassis coordinate system)
When the pose is received for the first time, the node queries by the timestamp of that message base_footprint ← front_mid360, with a maximum wait of 0.5 seconds; if it fails, an alarm is raised and this pose is discarded, and subsequent pose callbacks will retry. After the first success, the radar mounting and joint transforms at that time are stored as a fixed matrix C, and both subsequent poses and point clouds use it.
The body frame on which this specified initial alignment depends does not represent the chassis pose output by this node. The current MID360 is mounted on gimbal_yaw; therefore, this TF includes the chassis-to-gimbal, mechanical yaw, and LiDAR mounting relationships; it changes with yaw but does not change with pitch. The cache time also is not necessarily equal to the Point-LIO initialization time, so the pose and joint states at startup need to be verified.
A fixed cache itself is not an error: the alignment between two fixed reference frames should generally remain fixed, and the moving radar-to-chassis transform is queried downstream sensor_scan_generation by point cloud timestamp. What needs to be confirmed is whether C correctly represents the relationship between odom and camera_init; it cannot simply be changed to update every frame following the gimbal. Point-LIO's initial rotation is also affected by gravity alignment, so the input initial pose cannot be assumed by default to be a unit rotation.
1.1.1.2.5.lidar_frame (radar coordinate system and output odometry subframe)
The current front_mid360 is consistent with the radar name in the model, but the upstream body is an internal IMU. Let T_AB denote the transformation of coordinates from frame B to frame A, where W=camera_init; I=internal IMU; L=front_mid360; O=odom. The complete radar pose should generally satisfy:
The current source code actually computes C × 输入位姿 , i.e. C × T_WI(t) , and then sets the subchain name to L; there is no right multiplication by T_IL , nor any condition that verifies C=T_OW using the initial input pose.
Point-LIO The registered point cloud already uses mapping.extrinsic_R/T, while pose publishing directly takes the filter's IMU position and orientation. Currently, the physical extrinsic_R is the identity matrix, and extrinsic_T=[-0.011,-0.02329,+0.04412] m is nonzero; axial alignment does not mean the two origins are the same. Without this step, the lever-arm effect of the lidar rotating around the IMU may manifest as position error. Simply changing lidar_frame or the topic name cannot fill in the extrinsics; record this interface gap first, and engineering modifications are separately authorized.
1.1.1.2.6.Boot configuration and source code gaps
| Launch method | Parameter source | Values to distinguish |
|---|---|---|
| Complete reality launch | Defaults to pb2025_nav_bringup/config/reality/nav2_params.yaml; an alternative file can be specified using params_file and passed through bringup to navigation_launch.py |
base_frame=base_footprint;use_sim_time is ultimately overridden by the launch argument, defaulting to False |
| Complete simulation launch | Defaults to pb2025_nav_bringup/config/simulation/nav2_params.yaml; also loaded through navigation_launch.py as the configuration |
base_frame=base_footprint;use_sim_time is ultimately overridden by the launch argument, defaulting to True |
Standalone loam_interface_launch.py |
The launch’s parameter dictionary; does not read the YAML above | base_frame=gimbal_yaw; no use_sim_time launch argument is set or declared, so ROS2 defaults to False |
The entire set of started independent processes and component modes all load the same processed parameter file;slam Selecting mapping or localization will not skip this navigation interface. This time in ysu_ros_humble only the environment is loaded and the package path is queried, confirming that the launch and YAML after the relevant installation point to the current source code; no nodes were started, and no valid parameters of running nodes were read.
Another confirmed source code gap is initialization protection: the point cloud callback does not check whether the initial TF succeeded and directly uses the cache. The container's tf2::Transform default constructor does not initialize values, and the node also does not first set the cache to an identity transform. If the point cloud arrives first, or the initial TF query keeps failing, an uninitialized matrix may be used; the runtime behavior after triggering was not tested in this round.
Source code location: loam_interface/src/loam_interface.cpp parameter reading, point cloud callback, and pose callback; point_lio/src/laserMapping.cpp of set_posestamp/publish_odometry , as well as point_lio/src/Estimator.cpp of pointBodyToWorld. The above packages are all located in src/pb2025_sentry_nav/.
1.1.1.2.7.Observed and To Be Verified Items
- Confirmed from the source code: Usage of the six parameters, input and output topics, the first TF cache, missing LiDAR extrinsics for the IMU pose, missing initialization guards, and launch configuration sources.
- Observed in simulation: The independent Point-LIO check on 2026-10-08 produced normal poses and registered point clouds while stationary and during roughly 20 cm of slow back-and-forth motion. It did not cover this node’s complete downstream transformations or independently verify gimbal yaw, so it cannot establish that this interface is correct.
- Requires hardware verification: Actual MID360 mounting position and axes, internal LiDAR and IMU extrinsics, mechanical yaw/pitch zero positions and directions, serial angle units and meanings, clock consistency across messages, and the relationship between the Point-LIO gravity target frame and navigation’s
odomframe. The current convention requires mechanical relative angles in JointState; world-frame IMU orientation cannot replace joint angles. Gravity direction is unchanged in this round.
机械关系与Linux与MCU数据对接、MID360安装位置一致:两个odom关节固定,实际yaw在gimbal_yaw_joint、实际pitch在gimbal_pitch_joint,串口position为{relative_pitch, relative_yaw, 0, 0}。MID360挂在实际yaw关节之后,随yaw、不随pitch;不能用关节之前的gimbal_yaw_odom替代其挂载层。