Skip to content

Wiki

slam_toolbox(二维地图生成与轨迹优化)

About 198 min read

Existing English translations were reused. 14 current source blocks remain in Simplified Chinese, without triggering paid translation.

1.slam_toolbox(二维地图生成与轨迹优化)

1.1.二维图、PCD与实时定位:各自负责什么

The current project’s two-dimensional occupancy grid is generated by slam_toolbox, while the three-dimensional PCD is saved by Point-LIO. The two-dimensional map records occupied, free or unknown states for planar cells; the PCD retains three-dimensional point positions. They serve different purposes.

The two output chains during graph construction are:

Point-LIO配准点云
    ├─ 累计并保存三维PCD
    └─ loam_interface → registered_scan
           → terrain_analysis / terrain_analysis_ext(估计地面与高差)
           → pointcloud_to_laserscan(筛选、转到底盘系、压成二维扫描)
           → obstacle_scan → slam_toolbox → /map(二维栅格)

pointcloud_to_laserscan supplies two-dimensional scans, and slam_toolbox places them in the map to generate the occupancy grid. The former does not save the two-dimensional map itself. Current scans come from terrain point clouds rather than directly slicing raw MID360 returns.

Files to retain Purpose Required by the current approach?
Two-dimensional map image, such as PGM or PNG, and its YAML Read by map_server; supplies static road and obstacle layout to Nav2 Retain the complete set; YAML records image path, resolution, origin and other settings. An image alone is insufficient
Three-dimensional PCD for the corresponding site Target point cloud for small_gicp_relocalization localization Retain it; a two-dimensional image cannot replace it. The current launch specifies it through prior_pcd_file
slam_toolbox’s serialized .posegraph and .data Retain its internal mapping state and scans for continued mapping or its own localization mode Normal current navigation does not read these. Optionally save the complete set for later continued mapping, but verify usability under the current settings

The serialization interface writes .posegraph and .data separately. These are distinct outputs from the two-dimensional image and three-dimensional PCD.slam_toolbox serialization implementation (2.6.10)

Enabling the save function does not mean the file has been written to disk. use_map_saver=True provides the map saving service; currently slam_launch has also started Nav2's map_saver_server, but the launch does not automatically call the save service, and the 2D map still requires a save operation to be executed.Map saving function description (2.6.10)

For the PCD path, the integrated slam_launch overridespcd_save.pcd_save_ento True. Currently interval=-1 and scan_publish_en=True, so the point cloud accumulates continuously and the normal-exit save branch writes scans.pcd. Forced abnormal termination may prevent saving; long accumulation also increases memory usage. A later save may overwrite the same filename, so archive by site and session.

In the currently installed Point-LIO program, the save location corresponding to the compilation directory is:

/home/tungchiahui/UserFolder/MySource/ysu2026_rm_sentry/ysu2026_rm_sentry_nav/src/pb2025_sentry_nav/point_lio/PCD/scans.pcd

保存目录由编译时ROOT_DIR确定,详见Point_LIO的PCD保存说明;在其他路径重新编译后需要重新核对。文件不会自动成为导航launch指定的场地PCD。

The relationship with existing map navigation (slam:=False) is:

保存的二维图片 + YAML → map_server → 静态地图 → Nav2规划
实时registered_scan + 保存的三维PCD → small_gicp → map与odom之间的定位变换
实时terrain_map / terrain_map_ext → 局部/全局代价地图 → 更新当前障碍

Therefore,During navigation, the 2D map and PCD are read; what is matched in real time is the “current 3D point cloud and the saved 3D PCD.” It is not matching the PCD with a 2D image, nor saving a copy of the PCD each frame before matching. The current small_gicp processes the accumulated point cloud on a timer of about 0.5 s, and updates the result only when matching converges; this does not guarantee correct localization every 0.5 s. Normal navigation does not start slam_toolbox or this 2D scan conversion node, nor does it use them for real-time 2D map matching. For wiring, seeslam_launch.py、localization_launch.py.

The two-dimensional map and PCD should represent the same site with consistent scale, origin and orientation. Saving both in one session does not automatically establish alignment. Point-LIO outputs the internal IMU pose, and the PCD is in camera_init. Downstream IMU, LiDAR and chassis transformations and the startup transformation of the prior PCD still have recorded concerns; check the preceding loam_interface and small_gicp sections. Changing image size, origin or rotation also requires considering PCD localization coordinates, rather than only the image’s appearance.

1.2.上下坡能否建图,是否需要PS改图

A ramp can leave a planar layout on a 2D map, but a 2D grid does not record ramp surface height, slope, or vehicle climbing capability. A single-layer map also cannot separately represent structures where both the upper and lower layers at the same planar position are passable.

If the terrain node correctly identifies a normal slope as ground, its height difference should be near 0 and is usually removed by the currentmin_intensity=0.1 mfilter. Only pronounced height differences such as walls and steps enter the two-dimensional obstacle outline. Filtering slope points does not guarantee that the entire ramp is marked traversable; that still depends on other valid returns, scan-ray coverage and downstream handling of free and unknown regions.

For example, a normal slope point is incorrectly estimated as a 15 cm height difference, and when passing through other windows, it will cross the 10 cm threshold and may be drawn as an obstacle; if a downhill point is below -0.5 m in the base_footprint system, it will be deleted by min_height again. These respectively involve ground estimation and the projection height window, and cannot be handled by the same parameter.

Ramp problem Checks to prioritize
A continuous slope appears as a wall or obstacle band Terrain ground estimation, useSorting and quantileZ, and the height-difference threshold for two-dimensional scans. The two terrain nodes handle positive and negative differences differently in near and far fields
Downhill points are missing, leaving incomplete ramp outlines Upstream height windows, the chassis projection frame’s direction, and the converter’s fixed min_height and max_height range
Hardware ground appears tilted overall, or the map deforms after rotating the gimbal Gravity direction; IMU, LiDAR and chassis extrinsics; mechanical joint angles; and point timing. Rule out interface problems before tuning filtering thresholds
The two-dimensional map looks clear, but navigation still avoids the ramp Live costmaps also receive terrain point clouds. Static-map traversability does not ensure the live obstacle layer allows passage
Recognition is correct, but the vehicle still cannot climb or descend Actual slope, traction, ground clearance, transitions at the top and bottom, and braking capability. Map parameters cannot improve mechanical capability

The goal of parameter tuning is to ensure that real ground, obstacles, and no-data areas are represented reasonably; it must not filter out real steps or dangerous drops just to make ramps appear white. The actually traversable slope and drop need to be measured and verified, and there are currently no physical ramp conclusions.

Image editing with PS or similar software can clean static maps after on-site verification, butit is neither mandatory nor a fix for live terrain recognition. Even after false static obstacles are painted white, live terrain_map and terrain_map_ext may reintroduce the same slope into the costmap. First check coordinates, units, timing and uphill and downhill filtering, then assess whether manual map editing is needed.

1.3.当前建图方式与配置来源

The complete reality and simulation entry points pass their respectiveconfig/reality/nav2_params.yaml、config/simulation/nav2_params.yamlconfiguration to slam_launch and startsync_slam_toolbox_node; these six settings match in both configurations. By default, configuration is located through the installed pb2025_nav_bringup package directory; a specified params_file takes precedence. The current installed copy matches the corresponding source configuration.

The currently installed version is slam_toolbox 2.6.10, Ceres 2.0.0. The following reading and effective conditions are reviewed according to the corresponding versions; the humble branch link in the configuration can be used to check the description, but the branch content may continue to change.

Another startup configuration concern: neither of the two YAML slam_toolbox sections explicitly has use_sim_time. The currently installed RewrittenYaml only replaces existing keys, and slam_launch does not pass this parameter separately for this node; with the current default wiring, even if the simulation entry point passes True, it will not automatically be added to this node, and the standard default remains False. This is a static configuration assessment; the actual node parameters have not yet been observed; the ROS parameter partition needs to continue to be checked for this item.

Currently use_scan_matching=False, do_loop_closing=False. When performing regular mapping from an empty map, Karto still receives scans and forms a grid, but skips scan matching and does not add new scans to the pose graph; therefore, it will not call Ceres through automatic loop closure to correct the trajectory. The graph here mainly relies on upstream odometry to place scans, and accumulated errors after long distances and turns cannot be expected to be automatically eliminated by this set of solver settings.Current processing path (Mapper.cpp, 2.6.10)

The solver plugin is still loaded and reads parameters when the node is configured;reading a parameter and using it in actual optimization are separate matters. Loading an existing pose graph or triggering optimization through another feature requires checking that execution path. These switches determine whether the solver settings have an actual optimization task.

The Plugin, ROS, General, Correlation, and Scan Matcher sections in the original file are only comment categories; the parameters are still written directly under ros__parameters, without adding an extra layer of algorithm parameter keys.

1.4.参数

1.4.1.Plugin params (pose graph solver settings)

1.4.1.1.Parameter table
slam_toolbox:
  ros__parameters:
    solver_plugin: solver_plugins::CeresSolver
    ceres_linear_solver: SPARSE_NORMAL_CHOLESKY
    ceres_preconditioner: SCHUR_JACOBI
    ceres_trust_strategy: LEVENBERG_MARQUARDT
    ceres_dogleg_type: TRADITIONAL_DOGLEG
    ceres_loss_function: None

All six settings are type names, without meter, second or angle units. Increasing or decreasing them has no numerical meaning.

Parameter name Current value Unit Recommended action for real vehicle handling Effect Effect of increasing Effect of decreasing Conditions / notes
solver_plugin solver_plugins::CeresSolver Not applicable, plugin name Usually keep the current value; not a priority tuning item Select the optimization backend for the 2D pose graph Not applicable Not applicable Loaded at startup; the currently installed solver_plugins.xml registers only Ceres; an incorrect or unavailable plugin name will cause loading to fail
ceres_linear_solver SPARSE_NORMAL_CHOLESKY Not applicable, algorithm enum Usually keep the current value; not a priority tuning item Select the method for solving linear equations in each round of graph optimization Not applicable Not applicable Currently sparse direct solving; only affects computation when Ceres optimization is actually invoked; current regular mapping does not trigger automatic graph optimization
ceres_preconditioner SCHUR_JACOBI Not applicable, algorithm enum This parameter is not used in the current operation; do not adjust for now Provide an acceleration method for applicable iterative linear solver methods Not applicable Not applicable The parameter is read, but the current SPARSE_NORMAL_CHOLESKY does not use a preconditioner; after switching algorithms, verify whether the combination is supported
ceres_trust_strategy LEVENBERG_MARQUARDT Not applicable, algorithm enum Usually keep the current value; not a priority tuning item Determine how each round of graph optimization proposes and adjusts the correction step size Not applicable Not applicable Currently LM is used; the other exposed option is DOGLEG; it affects the solution only after actual optimization is triggered, and does not control vehicle motion
ceres_dogleg_type TRADITIONAL_DOGLEG Not applicable, algorithm enum This parameter is not used in the current operation; do not adjust for now Select the internal solving method of the Dogleg strategy Not applicable Not applicable Used only when ceres_trust_strategy=DOGLEG; under the current LM it does not participate in computation
ceres_loss_function None, string Not applicable, type name Usually keep the current value; not a priority tuning item Determine whether graph constraint errors use a robust loss to reduce the influence of abnormal constraints Not applicable Not applicable None uses ordinary squared loss; it affects results only after graph constraints enter optimization; it is not turning off map saving, scan matching, or the entire SLAM

For the meaning of the enum, seethe official solver parameter description (2.6.10); for the conditions under which a preconditioner is applicable to an iterative linear solver, seeCeres 2.0.0 option definitions.

1.4.1.2.Parameter Details
1.4.1.2.1.solver_plugin (Select 2D trajectory optimization backend)

A "pose graph" can be understood as: recording the vehicle's position and orientation during each frame scan, as well as the relative relationships between frames. When these constraints are present and optimization is triggered, the solver adjusts the 2D x, y, and yaw to make the constraints more consistent. It does not optimize the 3D IMU state of Point-LIO, nor does it replace the PCD localization of small_gicp.

The current Ceres plugin still needs to load successfully during the startup phase. The other plugin names mentioned in the official documentation do not mean that the current installation package already provides them; you cannot assume that switching is possible just by changing the name.

1.4.1.2.2.ceres_linear_solver (How equations are solved inside graph optimization)

SPARSE_NORMAL_CHOLESKY can be understood as exploiting the many zero entries in the equations to directly solve for one correction step. Other exposed options are SPARSE_SCHUR, ITERATIVE_SCHUR and CGNR. These select algorithms rather than accuracy or speed levels; switching does not universally guarantee greater accuracy or speed.

Currently there is no evidence of abnormal solving time or memory usage, and conventional mapping does not perform automatic graph optimization, so continue using it for now. It does not change map resolution, LiDAR sampling rate, terrain elevation difference, or climbing capability.

1.4.1.2.3.ceres_preconditioner (acceleration aid for iterative solving, currently unused)

A preconditioner is an auxiliary method that helps certain linear algorithms that "repeatedly approach the answer" solve faster. Currently, a direct solve is used, so SCHUR_JACOBI does not participate in this computation; the log showing it was read does not mean there is an actual speedup.

If we switch to an iterative solver later, the preconditioner support scope needs to be checked together; SCHUR_JACOBI applies to ITERATIVE_SCHUR and cannot be treated as a universal switch for all solvers.

1.4.1.2.4.ceres_trust_strategy (correction strategy for graph optimization)

LEVENBERG_MARQUARDT, abbreviated as LM, can be understood as adjusting the strength of trajectory correction in each iteration based on the improvement in error. DOGLEG is another method for proposing correction steps; when using it, only then further choose TRADITIONAL_DOGLEG or SUBSPACE_DOGLEG.

1.4.1.2.5.ceres_dogleg_type (Dogleg internal method, currently inactive)

Currently it is LM, so changing ceres_dogleg_type will not change the current result. The "step size" here refers to the pose correction amount in the computation, not how far the vehicle travels each time, the chassis speed, or the slope limit.

1.4.1.2.6.ceres_loss_function (Influence of abnormal graph constraints)

None means no robust loss is added, and the constraint error is treated as its square. HuberLoss and CauchyLoss are used to reduce the influence of constraints with large errors; they cannot guarantee the removal of all incorrect matches, and they also affect constraints with large errors that are actually valid.

This handles pose-graph constraints. It cannot directly remove pedestrians from point clouds, change slope height differences or fix IMU extrinsics or point timing. Automatic graph optimization is not currently triggered, and switching loss functions cannot automatically make a ramp traversable.

The read path is slam_toolbox’s setSolver loading the plugin, followed by CeresSolver::Configure reading five ceres settings. This path has no callback to automatically rebuild the solver after parameter changes. Unrecognized linear-solver, trust-region or loss names may fall back to defaults; successful startup does not establish correct spelling.Parameter reading and configuration branches (2.6.10)

  • Confirmed from the source code: Two-dimensional mapping and PCD saving are separate output paths. Normal navigation uses both a static two-dimensional map and a three-dimensional prior cloud. Scan matching and loop closure are currently disabled. The preconditioner and Dogleg type do not participate in the current algorithm combination.
  • Existing verification scope: Only standalone Point-LIO while stationary and during roughly 20 cm of slow back-and-forth motion. Two-dimensional mapping, slope projection, long-distance trajectories, loop closure and actual optimization with these solver settings remain unverified.
  • Pending hardware checks: Coordinate consistency between the two-dimensional map and PCD; distinguishing real ramps from steps; vehicle climbing and descent capability; map stability during gimbal rotation; and map saving and reloading results.

1.4.2.ROS Parameters (coordinate interface, mapping mode, and resume-mapping entry)

1.4.2.1.Parameter table

The first 6 items are the currently enabled values; the last 3 items are commented out in the YAML, and the example content is not the actual parameter values. In addition, the ROS standard use_sim_time is listed to explain the missing simulation clock item found earlier.

slam_toolbox:
  ros__parameters:
    odom_frame: odom
    map_frame: map
    base_frame: base_footprint
    scan_topic: obstacle_scan
    use_map_saver: true
    mode: mapping

    # 可选:载入此前序列化的地图,从指定位置或第一帧位置继续建图
    # 两种起点同时设置时,优先采用map_start_pose
    # map_file_name: test_steve
    # map_start_pose: [0.0, 0.0, 0.0]
    # map_start_at_dock: true
Parameter Current value Units Hardware guidance Purpose Effect of increasing Effect of decreasing Activation conditions / notes
odom_frame odom Not applicable; frame name Verify and configure correctly before running on hardware Specify the reference frame used to obtain chassis odometry poses Not applicable Not applicable Query odom←base_footprint through TF at scan time; does not directly subscribe to aft_mapped_to_init or an Odometry topic, and does not generate chassis odometry
map_frame map Not applicable; frame name Verify and configure correctly before running on hardware Specify the reference frame name for two-dimensional maps and mapping poses Not applicable Not applicable Must match Nav2 static-map and localization coordinates. Renaming does not automatically transform a PCD or old map, or ensure this node publishes map→odom
base_frame base_footprint Not applicable; frame name Verify and configure correctly before running on hardware Specify the robot reference point tracked during mapping Not applicable Not applicable Currently the chassis frame; must match scan projection and mechanical TF. The extracted two-dimensional pose contains only x, y and yaw, without z, roll or pitch
scan_topic obstacle_scan Not applicable; topic name Verify and configure correctly before running on hardware Specify the two-dimensional LaserScan input Not applicable Not applicable Currently published by pointcloud_to_laserscan as a virtual scan filtered from terrain points. Relative topic names resolve under the node namespace
use_map_saver true Not applicable; boolean Enable or configure as needed Create slam_toolbox’s own two-dimensional map-saving service and subscribe to the map Not applicable Not applicable Provides slam_toolbox/save_map; does not automatically save files or control Point-LIO’s PCD saving or pose-graph serialization. Launch separately starts Nav2 map_saver_server
mode mapping Not applicable; mode name Usually keep the current value; not a priority for tuning Provide an internal mapping and localization configuration hint to the current Ceres plugin Not applicable Not applicable In this version, localization affects fast constraint removal; it does not itself switch the synchronous mapping node or the complete small_gicp navigation chain
map_file_name Unset, default empty string; test_steve is commented out Not applicable; file-path prefix Unused in the current execution path; leave unchanged for now Specify the serialized slam_toolbox map loaded at startup Not applicable Not applicable Only a nonempty value attempts continued mapping. Reads .posegraph and .data files with the specified prefix, rather than a two-dimensional map YAML or PCD
map_start_pose Unset; [0.0, 0.0, 0.0] is commented out [m, m, rad],[x, y, yaw] Unused in the current execution path; leave unchanged for now Provide the robot’s approximate initial position and heading in the old two-dimensional map When enabled: components change along the old map’s +x, +y or increasing-yaw directions When enabled: components change in the opposite directions Used when map_file_name is nonempty; requires three floating-point values. If dock is also set, pose takes precedence. Not z, roll and pitch, or small GICP’s six-component init_pose
map_start_at_dock Unset; true is commented out Not applicable; boolean Unused in the current execution path; leave unchanged for now Choose the old map’s first-frame location as the starting point for continued mapping Not applicable Not applicable When map_file_name is nonempty and map_start_pose is unset, True selects the first frame. Dock does not automatically find a charging dock or command movement
use_sim_time Absent from both hardware and simulation slam_toolbox sections; standard defaultFalse 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 Hardware should match system and driver time; simulation should use /clock. The current launch’s True replacement does not add missing keys; the actual node value has not been observed
1.4.2.2.Parameter Details
1.4.2.2.1.odom_frame (from which set of coordinates is the chassis pose obtained)

The odom can be understood as the "position coordinates continuously recorded by the upstream odometry". For each scan frame, this node queries the TF at the frame's timestampodom←base_footprintto obtain the chassis's position and orientation in odom; if the query fails at that moment, the frame is skipped.

It does not directly subscribe to Point-LIO's aft_mapped_to_init, nor does it rely on a topic called /odom to obtain the pose. In the current chain, Point-LIO is first adapted via loam_interface, and then sensor_scan_generation publishes the TF from odom to base_footprint; having only odometry messages without this valid transform is still insufficient for mapping.

When obtaining the pose, only x, y, and yaw are retained. Position is expressed in m, and yaw is expressed in rad; the altitude, roll, and pitch when going uphill do not enter the 2D mapping pose.2D pose reading implementation (2.6.10)

1.4.2.2.2.map_frame (reference system used by two-dimensional maps)

map is the reference frame for the final 2D grid and mapping pose; odom is the current odometry reference frame; base_footprint is a reference point that moves with the chassis. The normal relationship can be read as:

map → odom → base_footprint
旧场地图    当前里程计    底盘参考点

On hardware, the two-dimensional image and YAML, PCD localization and Nav2’s map must share scale, origin and orientation. Changing map_frame to another name does not rotate or translate an old map or PCD into that frame.

The current mapping launch provides a static map→odom transform for the unit transform, and configures transform_publish_period=0, slam_toolbox does not publish this dynamic TF. This only explains the source of the coordinates; existing map navigation is provided by small_gicp for the localization relationship, which differs from the mapping entry point. If continuing to build on an old map by restarting from a different position or orientation, the old map and the new odom may not coincide; the startup chain must be checked together, and simply uncommenting map_file_name is not enough.

1.4.2.2.3.base_frame (tracking the chassis reference point, not an independently rotating gimbal)

The current base_frame is base_footprint; pointcloud_to_laserscan's target_frame is also base_footprint, soobstacle_scan.header.frame_id=base_footprintThe virtual scan center coincides with the chassis reference point tracked here, and the transform from the scan to the base is the identity transform.

Upstream TF has already transformed LiDAR points into the chassis projection frame. Do not manually add front_mid360’s mounting offset or gimbal yaw again here. If either side merely changes frame_id without transforming coordinates, the map remains wrong. Matching parameter names also cannot establish that upstream IMU, LiDAR and chassis transformations are correct.

MID360 is still mounted on gimbal_yaw, rotating with the actual yaw and not with pitch; the two odom joints are fixed. Using the chassis frame for mapping does not mean that the MCU world pose can be treated as a mechanical joint angle, nor does it change these mechanical conventions.

base_footprintThis name does not automatically yield a horizontal projection. The current upstream retains the full 3D pose; the scan is projected onto the system's x-y plane, while slam_toolbox takes only the 2D x, y, and yaw. Whether it behaves as expected on a slope requires checking the actual projection plane; this node cannot be relied upon to restore lost height or automatically flatten an inclined scan. The mounting relationship from the scan to the base is obtained viaLaserAssistant implementation.

1.4.2.2.4.scan_topic(which 2D scan to receive)

The current input is:

terrain_map_ext(地形点云)
    → pointcloud_to_laserscan(高度/高差筛选,转到底盘系)
    → obstacle_scan(LaserScan)
    → slam_toolbox

It is not a raw 3D point cloud, nor does it directly read terrain_map_ext. Slope points, low obstacles, or missing data that have already been deleted upstream cannot be recovered by changing this topic name.

The current value obstacle_scan is a relative name: in the default empty namespace it is /obstacle_scan; if the node is in the /sentry namespace, it is /sentry/obstacle_scan. The preceding converter output also uses relative names and must be connected under a consistent namespace and remapping.

The tutorial and the official README describe scan_topic as an absolute name; the current 2.6.10 subscription implementation does not enforce this form, and this project uses the relative name obstacle_scan, resolved according to ROS rules. The topic name and the frame_id in the message are also two different things: the name determines which message is received, while frame_id determines how the scan coordinates are interpreted.ROS2 topic name rules

Input uses SensorDataQoS with TF message filtering. Besides receiving LaserScan, it must obtain the relationships between odom, the scan frame and the chassis frame at scan time.Subscription and TF filtering implementation (2.6.10)

1.4.2.2.5.use_map_saver (provides an entry point for saving 2D maps)

True creates theslam_toolbox/save_mapservice and subscribes to the map; only after the map is received will the service call trigger the saving of the 2D image and YAML. When there is no map, it will report that saving is not possible, and True itself does not periodically persist to disk.MapSaver implementation (2.6.10)

This item only controls slam_toolbox's own save entry point. Point-LIO Saving PCD is controlled by pcd_save; .posegraph and .data are saved through the serialize_map interface. Setting it to False also does not mean disabling 2D mapping or disabling all save channels.

Currently slam_launch also starts Nav2's map_saver_server, which is an independent map saving service; the two cannot be regarded as the same node. The saved 2D map should be archived together with the corresponding PCD for use by the current navigation solution.

1.4.2.2.6.mode (the distinction between internal mode hints and the actual startup process)

Currently, mapping is maintained, consistent with the mapping process being started for sync_slam_toolbox_node. In this version, mode is read by the Ceres plugin; localization will enable internal settings that make it easier to remove constraints.Only changing this string will not automatically turn the current program into a localization node. Ceres mode read、Synchronous mapping node entry

The selection of the entire process flow for this project comes from the launch parameters:

Startup selection Current actual working chain
slam=True Point-LIO, 2D scan conversion and slam_toolbox mapping; additionally provides static map→odom
slam=False Point-LIO, small_gicp 3D PCD localization and map_server 2D map; does not start slam_toolbox

Therefore, when performing navigation on an existing map, even if the mode in this YAML is still set to mapping, it does not mean that slam_toolbox continues to build the map in the background, because that node is not started at all. If slam_toolbox's own localization solution is to be used in the future, the corresponding localization node, serialized map, and matching process are required; that is a separate startup requirement.Official localization node implementation

1.4.2.2.7.map_file_name (serialized map prefix required for resumption; currently not enabled)

All three example lines begin with #. No old pose graph is currently loaded; this mapping session starts with an empty map. map_file_name is neither the save-target name nor map_server’s two-dimensional map YAML path, nor small_gicp’s prior_pcd_file.

If set to/某个目录/sitethe files read aresite.posegraphandsite.data. The program appends suffixes, so a single PGM or PCD is insufficient. Both files should come from the same serialization result.Serialization read and write implementation

Currently use_scan_matching=False, so starting from an empty map does not create new matching graph nodes. Existing serialized files are not automatically verified maps for continued mapping or localization. Continued mapping also depends on the old graph structure, start pose and relationship between old and new coordinates; this is currently unverified.

1.4.2.2.8.map_start_pose (2D starting point in the old map, currently disabled)

When legacy map loading is enabled, the array means[x, y, yaw]; positions are in m and headings are in rad, both relative to the legacy map; under the current base_frame it represents the 2D initial pose of the chassis. For example, yaw=1.5708 is approximately 90°, not 90.

It is an approximate starting point used for matching against the old map, not a requirement for the vehicle to move to that point, nor is it used to define the origin for a new map. A non-empty map_file_name must also be provided; when there is no old map path, setting this item alone will not enable continued construction.

1.4.2.2.9.map_start_at_dock (continued from the first frame of the old map, currently not enabled)

The dock here refers to the position of the first frame in the old map, not detecting a physical charging pile, and certainly not automatic return to the pile. True indicates that a new round starts docking from this starting point in the old map; the vehicle's actual starting point and orientation still need to correspond.

When enabling resume construction, select map_start_pose, or set map_start_at_dock=True. If both are provided, pose takes priority; when the number of poses is not 3, the source code reports an error and then uses[0,0,0]and will not automatically switch to dock because of this. Setting only dock to False also does not mean disabling old map loading; the entry point for disabling loading is an empty map_file_name.Starting point selection and loading logic (2.6.10)

1.4.2.2.10.use_sim_time (ROS standard clock parameters: missing entries in the simulation section)

This setting is currently absent from both hardware and simulation YAML slam_toolbox sections. slam_launch passes use_sim_time to RewrittenYaml for replacement, but the installed implementation only changes existing keys without adding one to this section. Node does not separately receive a use_sim_time override.

Therefore, based on the current default startup wiring, it can be inferred that this node uses the standard default False, and the True at the simulation entry point does not affect this section. Simulation should use /clock together with the upstream point cloud and mechanical TF; the physical system typically uses False and verifies the driver time. This is a judgment based on the configuration and startup logic; the actual running node value and simulation effect still need to be verified.

Clock selection is controlled by use_sim_time; changing odom_frame, scan_topic, or the mode cannot replace this setting.

1.4.2.2.11.Read Timing and Verification Scope

Coordinates, topics, the save switch, and the Ceres mode are read during node configuration; the three legacy map parameters are read at the startup loading entry point. The relevant paths have no callbacks that automatically rebuild subscriptions, the solver, or reload the legacy map after parameter changes; the ROS standard use_sim_time is handled by the node clock mechanism and should be understood separately from these startup parameters.

  • Confirmed from the source code: The current six hardware and simulation settings match. Chassis poses come from TF at scan time and retain only x, y and yaw. Input is a virtual chassis-frame scan. A save service differs from writing files. Three continued-mapping settings are unset. Mode alone does not switch the complete pipeline. The simulation section lacks explicit use_sim_time.
  • Existing verification scope: Standalone Point-LIO while stationary and during roughly 20 cm of back-and-forth movement. This node’s mapping, continued mapping, map saving, uphill and downhill projection and actual simulation-clock value remain unverified.
  • Pending hardware checks: IMU, LiDAR and chassis transformations and mechanical joint angles; scan center and projection plane; TF and scan timing consistency; and a shared coordinate basis for the two-dimensional map and PCD. Continued mapping also requires checking the old graph’s first frame and the new session’s starting pose.
1.4.2.3.Parameter table (scan processing, map output, and runtime resources)

These 13 items still belong to the ROS Parameters section of the original document. Scan reception, map building, and map output are different stages; the following follows the current sync_slam_toolbox_node and the description for version 2.6.10, where the physical and simulation configuration values are the same.

    debug_logging: false
    throttle_scans: 1
    scan_queue_size: 10
    transform_publish_period: 0.0   # 0:本节点不发布map→odom TF
    map_update_interval: 0.5
    resolution: 0.05
    min_laser_range: 0.3
    max_laser_range: 10.0
    minimum_time_interval: 0.2
    transform_timeout: 0.2
    tf_buffer_duration: 10.
    stack_size_to_use: 40000000     # B,申请的栈软限制目标
    enable_interactive_mode: true
Parameter Current value Units Hardware guidance Purpose Effect of increasing Effect of decreasing Activation conditions / notes
debug_logging false Not applicable; boolean Enable or configure as needed Request debug logs and allow complete Ceres solver reports Not applicable Not applicable Does not improve localization accuracy. Automatic graph optimization is not currently triggered, so there is no corresponding Ceres report. ROS debug logs also depend on the actual log level; see the source-code concern
throttle_scans 1 Dimensionless; scan-sampling factor N Observe closely on hardware; adjust only for a specific problem Keep one of every N candidate scans by count Fewer candidate scans may reduce load but lose motion information More candidate scans may increase load Current 1 adds no extra subsampling, but TF, time and displacement gates still apply. The first scan is an exception. Must be a positive integer; 0 falls back to 1
scan_queue_size 10 Messages; count Usually keep the current value; not a priority for tuning Limit the scan-message buffer waiting for TF Accommodate more waiting messages, potentially retaining older data Drop messages more readily when TF arrives late Drops the oldest message when full. 0 means unlimited in the filter; not the downstream synchronous-processing queue q_ length or worker count
transform_publish_period 0.0 s; TF publication period, with 0 a special value Enable or configure as needed Control this node’s map→odom TF publication loop For positive values: slower publication For positive values: faster publication Current 0 stops publication directly. The mapping launch separately publishes an identity static map→odom. Does not disable Point-LIO odometry or odom→base TF
map_update_interval 0.5 s; two-dimensional map update-loop interval Observe closely on hardware; adjust only for a specific problem Periodically regenerate and publish the occupancy grid Slower display updates, potentially less reconstruction cost More frequent updates, potentially greater grid reconstruction cost Nominally about 2 Hz, affected by computation time. Not scan reception or processing frequency, and does not automatically save files. Requires a /map subscriber and a map that can be generated
resolution 0.05 m per cell; grid side length Observe closely on hardware; adjust only for a specific problem Set the generated two-dimensional map’s cell size Coarser map with fewer cells; narrow passages and small structures merge more readily Finer map with more cells, usually increasing computation and memory Currently 5 cm per cell; not localization error or traversable height. Does not change PCD, terrain downsampling or actual returns
min_laser_range 0.3 m; lower two-dimensional scan-range bound Verify and configure correctly before running on hardware Set the minimum scan distance used for mapping Ignore more nearby readings, potentially missing structures beside the robot Allow nearer readings, without recovering points discarded upstream Read when this scan frame is first initialized; cannot be below the input LaserScan.range_min. The current center is base_footprint, not the MID360 housing
max_laser_range 10.0 m; mapping ray and endpoint threshold Observe closely on hardware; adjust only for a specific problem Limit the distance over which valid returns contribute to grids and matching Use farther structures within the valid range, with greater sparse-point influence Distant endpoints stop being obstacles; some valid rays are shortened Read during first initialization and constrained by message range. Current input range_max is also 10 m, so increasing this does not see farther. Exceeding the threshold does not always discard the entire beam
minimum_time_interval 0.2 s; difference between candidate scan timestamps Observe closely on hardware; adjust only for a specific problem Limit the minimum interval between consecutively accepted scans Stricter time filtering may leave sparser motion trajectories Looser time filtering may increase load Compared using header.stamp. Usually an acceptance upper limit around 5 Hz, without guaranteeing insertion every 0.2 s; subsampling and horizontal displacement gates must also pass
transform_timeout 0.2 s; TF waiting time, also a conditional TF timestamp advance Observe closely on hardware; adjust only for a specific problem Set the scan TF filter’s transform-wait deadline Wait longer, potentially delaying scan acceptance Abandon unavailable transforms sooner If this node publishes map→odom, also set TF time to the latest scan timestamp plus this value. Publication is currently disabled, so this additional use is inactive. Does not compensate for point-time errors
tf_buffer_duration 10.0 s; dynamic TF history span Usually keep the current value; not a priority for tuning Retain dynamic TF history for scan queries Query older transforms, increasing cache usage Shorter history may leave old scans without transforms Not a 10 s wait, permitted 10 s timestamp mismatch or publication frequency. Cannot fix different time domains, wrong frames or nonexistent TF
stack_size_to_use 40000000 B; bytes, approximately 40 MB / 38.15 MiB Usually keep the current value; not a priority for tuning Request an increased process stack soft limit at node entry Allow more stack usage, without inherently accelerating mapping A lower target may constrain deep calls; the code does not actively lower an existing soft limit Mainly serves larger-map serialization; not a PCD cache, total-memory limit or limit for all thread memory. Actual limits depend on the system
enable_interactive_mode true Not applicable; boolean Enable or configure as needed Allow manual pose-graph adjustment and retain extra scan buffers Not applicable Not applicable True only permits the feature; actual interactive_mode is still False at startup. Scan matching is disabled, leaving no newly created graph nodes to drag, but the additional scan buffer still grows
1.4.2.4.Parameter details (scan processing, map output, and runtime resources)
1.4.2.4.1.debug_logging (debug information, does not change mapping accuracy)

Currently, False is suitable for ordinary observation; True enables the actual Ceres solver to output a complete report, but currently automatic graph optimization is not triggered, and this report will not automatically appear just by toggling the switch.

Source code debug level setting uses the literal logger namelogger_namerather than the node's slam_toolbox logger; therefore, setting True alone does not guarantee that the node's DEBUG logs will be displayed—you must also check the log level passed in by launch. It is not a switch for "enabling a more accurate algorithm".

1.4.2.4.2.throttle_scans (sampling scan by fraction)

N=1 does not increase frame dropping; N=2 keeps approximately one out of every two, and N=3 keeps approximately one out of every three. The count applies to scans entering the filtering function, not to every point of the MID360 or all raw messages; the first frame is passed through directly.

For example, if the candidate input is 20 Hz and N=2, the candidate upper limit after frame decimation is about 10 Hz; the subsequent 0.2 s time threshold may still reduce it to no more than about 5 Hz, and it will be even lower when the displacement is insufficient. Changing N does not control the radar publication frequency, nor does it guarantee that the actual map insertion frequency equals the input frequency divided by N.

1.4.2.4.3.scan_queue_size (queue waiting for TF, cannot handle the backlog on its own)

Wait for the scan of the TF corresponding to the time, caching at most 10 messages first; when exceeded, discard the oldest message. Increasing this can alleviate brief TF lateness, but it will not increase computing power, nor will it generate missing transforms.Humble MessageFilter implementation

After TF is ready, the current synchronization node also places filtered scans into an independent FIFO queue q_, and then processes them one by one. This queue is not subject to scan_queue_size; the source code issues a warning when the remaining length exceeds 10, but it does not automatically discard the backlog here. Increasing the preceding wait queue cannot solve the subsequent slow processing.Synchronous processing implementation (2.6.10)

1.4.2.4.4.transform_publish_period (the map→odom publishing period of this node)

The original comment, if 0 never publishes odometry, can misleadingly suggest that odometry is disabled. What this actually controls isslam_toolbox’s own map→odom TF. Current 0 makes that thread return immediately; it does not disable Point-LIO, lidar_odometry or sensor_scan_generation’s odom→base_footprint.

For positive values, 0.05 s is about 20 Hz and 0.1 s is about 10 Hz; changing the publishing cadence does not mean that the same frequency produces new localization results. The current mapping launch already has a static identity map→odom, and before enabling dynamic publishing it must be clarified who provides this relationship, to avoid both sources publishing at the same time.

1.4.2.4.5.map_update_interval (2D map update interval, separate from the map insertion interval)

The current 0.5 s corresponds to a nominal approximately 2 Hz map update cycle; minimum_time_interval=0.2 s controls scan filtering, and the two frequencies can differ. The same processed scan set can also be redrawn into a map multiple times; a faster update does not mean obtaining more environmental information.

The current implementation regenerates the grid from all processed scans, rather than only modifying the latest small patch; as the map expands and historical scans accumulate, shortening the interval may significantly increase the load. When there are no /map subscribers, generation is skipped; however, the current map-saving component subscribes on its own, so the map may continue to be generated even when RViz is not being viewed.Grid generation entry point

This loop uses the host clock of rclcpp::Rate and is not bound to the node's /clock. The map message stamp is taken from the most recent header.stamp that entered the scan callback, and it is not guaranteed that that scan has finished being inserted into the map; "the message became newer," "the grid changed," and "the new scan has been processed" should be determined separately. The interval should be positive; 0 does not have a branch that stops publishing like the TF publishing period.Humble Rate clock implementation

1.4.2.4.6.resolution (how large each cell is in a 2D image)

0.05 m means one grid cell is 5 cm. If increased to, for example, 0.1 m, the grid becomes coarser, and small rods, wall edges, or narrow openings may be merged; if decreased to, for example, 0.025 m, the grid becomes finer, but it will not recover points that the radar did not sample or that were already deleted upstream.

With the same coverage area, halving the grid cell edge length roughly quadruples the number of cells. Finer does not necessarily mean more accurate: positioning drift, terrain misclassification, projection direction, or point timing errors can still draw incorrect contours into finer cells.

This item is not about “allowing a 5 cm step,” nor does it determine whether a slope can be recognized as ground; it only affects the granularity of the two-dimensional representation. After generating a map, the saved YAML should record the corresponding resolution; merely changing the number in an old YAML will change the actual metric dimensions of the old map and cannot serve as a substitute for rebuilding the map.

1.4.2.4.7.min_laser_range (the nearest distance used for mapping)

The current lower bound is 0.3 m, consistent with the converter's range_min; distances are calculated from the virtual scan center base_footprint. Reducing this cannot restore points within 0.3 m that the converter has already deleted, and the source code will also raise settings below the message range_min to the message lower bound.

Increasing the value may filter out nearby ego-vehicle echoes, but it will also filter out obstacles beside the vehicle; a circular distance threshold cannot fully replace ego-vehicle filtering based on the vehicle body and gimbal motion envelope. In the current Karto grid ray processing, readings less than or equal to the actual lower bound are skipped.

1.4.2.4.8.max_laser_range (How do distant echoes participate in mapping?)

The current threshold is 10 m, and the range_max output message of the converter is also 10 m; parameters exceeding the message upper limit will be clamped back to that limit. Increasing this value cannot enable the current input to obtain echoes from farther away, while shortening it will reduce the structures available for drawing distant obstacles.Range initialization implementation

This is not simply “delete everything that exceeds the threshold”: if the threshold is set to 5 m, and the input contains one valid 8 m echo while the message upper limit remains 10 m, the grid ray will be clipped at 5 m and will not render the 8 m endpoint as an obstacle; this ray segment can still participate in the statistics of free space.

Current ∞ no-return values are skipped; they do not automatically mark the entire direction as 10 m of free space. Values at or above the message upper limit and NaN are also skipped. If upstream filtering removes normal slope points and no other valid return provides ray coverage in that direction, the slope region is not guaranteed to become free. Resolution or output-frequency tuning cannot create the missing observation. Occupied and free states also depend on accumulated grid statistics.Karto ray-grid implementation

1.4.2.4.9.minimum_time_interval (scanning the shortest release interval, and there is also a displacement threshold)

Currently, comparison is made between the scan timestamp and the previous release scan; if the difference is less than 0.2 s, it is rejected; the first frame is an exception. It only gives a usual time upper limit of about 5 Hz, not a fixed 5 Hz processing timer. Increasing it can reduce the amount of data entering the map, while decreasing it only relaxes the time condition.

Currently, there is also a prerequisite restriction related to in-place rotation of the real vehicle: The common filtering function checks the square of horizontal displacement and does not allow passage based on yaw. Currently, minimum_travel_distance=0.1 m, corresponding to a horizontal displacement threshold of about 8.94 cm here, and there is also an initial count limit. Moving for 0.2 s at 0.2 m/s is only 4 cm, which may still be insufficient, so the low-speed mapping interval will be longer.

After the first frame, when rotating the chassis in place or rotating the gimbal independently, if the x and y of the chassis TF remain essentially unchanged, subsequent scans will be blocked by this layer; simply shortening minimum_time_interval does not solve the problem. The minimum_travel_heading of the subsequent Karto layer has not yet had a chance to intervene, so one cannot assume that in-place rotation will update the map normally just because a rotation angle threshold has been set. This is the source code condition, and there is still no verification of turning or independent yaw for this node.

1.4.2.4.10.transform_timeout (waiting for TF; under conditions it also affects the release stamp)

Currently, a value of 0.2 s is passed to the TF message filter, indicating the maximum time to wait for the transform corresponding to the scan timestamp. Increasing it allows tolerance of valid TF that arrives later, but may also cause old messages to wait longer; when TF does not exist at all or the time domains are inconsistent, waiting longer has no corrective effect.

If transform_publish_period is positive, the source code also sets the published map→odom stamp to "latest scan stamp + transform_timeout"; this is not predicting future motion. Currently period=0, so this use does not participate in the output. It also does not add motion compensation to the input point cloud, correct the per-point time units, or make the TF history cache longer.

1.4.2.4.11.tf_buffer_duration (How long is the dynamic TF history retained?)

10 s represents the dynamic TF history cache span, used to query the transform at the time of the scan; it is not about waiting 10 s before processing, nor does it allow the scan and TF to differ arbitrarily by 10 s. The saving rules for static mechanical transforms differ from those for dynamic history.

When the backlog scan is too old, appropriately increasing it may retain the required history, but it will not eliminate the processing backlog; decreasing it may discard old transforms more quickly. It has already been confirmed earlier that the simulation segment use_sim_time has missing items, and increasing the history cache cannot replace a unified time source.

1.4.2.4.12.stack_size_to_use (stack limit, usually inherited)

40000000 B is about 40 MB, or about 38.15 MiB. The node entry requests an increase when the existing stack soft limit is lower than the target; the source code does not proactively lower a higher existing limit; setting a smaller value does not necessarily make the actual stack smaller.Sync node entry

It is mainly prepared for calls such as large map serialization, and does not limit Point-LIO cumulative PCD, scan cache, or total program memory. Whether the system accepts the request is still affected by resource limits; the entry point does not check the return value of setrlimit; there is currently no relevant failure evidence, and it is usually left as is.

1.4.2.4.13.enable_interactive_mode (manual pose graph modification is allowed; this does not mean interaction has been enabled)

Currently, True allows switching to the RViz pose graph interaction feature; at startup, the actual interactive_mode=False, so it will not automatically enter drag mode. After entering, the post-processing thread is paused to facilitate modifying existing graph nodes; after exiting, it resumes. During this period, new candidate scans may still enter the synchronization queue, and using it while moving will cause a backlog.Interactive switching implementation

Currently use_scan_matching=False; when building a map from an empty map, there are no new map nodes available for dragging; however, enable=True will still additionally save the raw scans that have been successfully processed, even if actual interaction is not enabled. When there is no need for manual adjustment, disabling it can reduce additional caching; Karto's own historical scans still exist and cannot be treated as a total memory switch.

Manual dragging or optimization changes the two-dimensional pose graph without synchronously correcting the three-dimensional PCD saved by Point-LIO. The current two-dimensional map and PCD must share a coordinate basis. Interactive map editing cannot replace slope classification or coordinate-interface checks.

1.4.2.4.14.Read Timing and Verification Scope

Debug settings, scan subsampling, TF queues, time gates, grid resolution, TF buffers and interaction permission are read during node configuration or thread initialization. The two LiDAR range settings are read and cached when that scan frame’s metadata is first created. stack_size_to_use is read at executable entry. These paths have no callbacks to automatically rebuild members, queues or LiDAR metadata after parameter changes. Interactive mode uses a dedicated service; it is not equivalent to directly changing a parameter.

  • Confirmed from the source code: These 13 hardware and simulation settings match. Scan filtering and map output are separate. The TF-wait queue differs from the synchronous-processing queue. Dynamic map→odom is not currently published. Two-dimensional ranges are constrained by upstream range. ∞ does not automatically generate free-space rays. The preliminary displacement gate may block scans after rotation in place.
  • Existing verification scope: Standalone Point-LIO while stationary and during roughly 20 cm of slow back-and-forth motion. slam_toolbox’s actual processing frequency, rotation in place, ramp free-space coverage, long-running queues and memory, serialization and interactive features remain unverified.
  • Pending hardware checks: Scan insertion continuity during movement and rotation; LiDAR and chassis timing and coordinates; nearby self returns and low obstacles; valid ray coverage on ramps; map detail and computation load. Gravity direction, internal IMU conversion and point-time issues still require prior checks.

1.4.3.General Parameters (scanning into the map, matching, and loop closure)

Currently use_scan_matching=False, do_loop_closing=False. slam_toolbox still places scans according to the upstream odometry and generates a 2D map; the distance and angle thresholds are still checked, but ordinary scan matching, graph node association, and the automatic loop-closure branch are skipped. In the table, "not used in the current run" means the parameter has been read in and its active branch was not executed, not that the parameter spelling is invalid.

These parameters determine two-dimensional scan sampling and association, not whether the vehicle can climb slopes. The preceding terrain analysis and two-dimensional scan filtering still distinguish slopes from obstacles.

1.4.3.1.Parameter table
    # General Parameters
    use_scan_matching: false
    use_scan_barycenter: true
    minimum_travel_distance: 0.1
    minimum_travel_heading: 0.1
    scan_buffer_size: 10
    scan_buffer_maximum_scan_distance: 10.0
    link_match_minimum_response_fine: 0.1
    link_scan_maximum_distance: 1.5
    loop_search_maximum_distance: 3.0
    do_loop_closing: false
    loop_match_minimum_chain_size: 10
    loop_match_maximum_variance_coarse: 3.0
    loop_match_minimum_response_coarse: 0.35
    loop_match_minimum_response_fine: 0.45
参数名 当前值 单位 实车处理建议 作用 调大效果 调小效果 生效条件/备注
use_scan_matching false 不适用,布尔 根据实际功能需求开启或设置 是否用二维扫描匹配修正里程计给出的扫描位置 不适用 不适用 当前跳过匹配和新图节点/关联构建,但仍入图;不关闭Point-LIO三维估计;开启可能改变二维轨迹与PCD的对应关系
use_scan_barycenter true 不适用,布尔 当前运行不使用这个参数,暂不调整 选择扫描间距离判断的参考点:回波点重心或扫描中心 不适用 不适用 当前图关联分支未执行;True不是车辆重心,也不改变base_frame;启用关联后影响1.5 m/3 m候选距离的含义
minimum_travel_distance 0.1 m,平面位移 实物运行时重点观察,有问题再针对性调整 限制两份扫描之间的移动取样间隔 取样通常更稀,负担降低,也可能漏掉转弯细节 取样通常更密,负担增加 当前仍生效;外层约8.94 cm门槛,Karto内层约10 cm条件;与时间、转角两层组合,不保证每走10 cm入一帧
minimum_travel_heading 0.1 rad,约5.73° 实物运行时重点观察,有问题再针对性调整 Karto内层允许因朝向变化而采用新扫描 需转更多角度才满足内层转角条件 更小转角即可满足内层条件 当前仍被内层检查,但必须先通过外层水平位移门槛;不是坡度、云台转速或车辆控制角
scan_buffer_size 10 份,匹配历史扫描计数 当前运行不使用这个参数,暂不调整 限制连续扫描匹配的近期窗口长度 启用后:可保留更多近期结构,匹配工作量增加 启用后:窗口更短,历史结构支撑减少 当前不加入running scans;不是等待TF的scan_queue_size,也不限制全部建图历史;非正值会回退10
scan_buffer_maximum_scan_distance 10.0 m,近期窗口首尾扫描中心间距 当前运行不使用这个参数,暂不调整 限制近期匹配窗口的空间跨度 启用后:允许更大的窗口跨度,仍受份数上限限制 启用后:较早扫描更易被移出窗口 当前匹配窗口未使用;不是雷达10 m量程,不是累计行驶里程;这项按扫描中心距离判断
link_match_minimum_response_fine 0.1 无量纲,归一化匹配分数 当前运行不使用这个参数,暂不调整 接纳普通近邻扫描链关联的分数门槛 启用后:关联更严格,可能少连有效结构 启用后:更易关联,也可能接纳错误对应 仅当前关闭的图关联分支使用;不是所有逐帧匹配的统一拒帧门槛;0.1不是10%成功概率
link_scan_maximum_distance 1.5 m,扫描参考点的平面距离 当前运行不使用这个参数,暂不调整 限定普通近邻链与当前扫描可以关联的距离 启用后:候选范围扩大,可能比较更多相似区域 启用后:范围缩小,也可能漏关联 当前图关联未执行;使用barycenter所选参考点;不是激光回波距离或允许定位误差
loop_search_maximum_distance 3.0 m,闭环候选参考点距离 当前运行不使用这个参数,暂不调整 找出可能属于同一旧区域的历史扫描链 启用后:纳入更远历史候选,也增加歧义 启用后:候选更局限,漂移较大时易漏闭环 当前自动闭环未执行;不是后续匹配搜索网格的边长;3 m内也不保证匹配通过
do_loop_closing false 不适用,布尔 根据实际功能需求开启或设置 是否自动识别重访区域并优化闭环轨迹 不适用 不适用 只有use_scan_matching=True才进入此开关所在分支;当前两个False,单改为True也不会启用自动闭环
loop_match_minimum_chain_size 10 份,历史候选扫描计数 当前运行不使用这个参数,暂不调整 要求候选链包含足够扫描,以提供匹配结构 启用后:要求更长历史链,可能减少有效候选 启用后:短链更易参与,结构证据较少 当前图关联/闭环均跳过;还用于普通近邻链,非只用于闭环;不是激光点数
loop_match_maximum_variance_coarse 3.0 m,配置尺度;内部平方为m²门槛 当前运行不使用这个参数,暂不调整 粗匹配后排除位置估计过于分散的候选 正值范围内:内部方差门槛随平方增大,接受更分散的结果 正值范围内:内部方差门槛降低,要求更集中,也可能拒绝有效候选 当前闭环未执行;配置3.0先平方为9.0 m²,检查x、y方差各自小于9,不检查yaw方差;不是3 m实际误差上限或small_gicp的max_dist_sq
loop_match_minimum_response_coarse 0.35 无量纲,归一化匹配分数 当前运行不使用这个参数,暂不调整 闭环粗匹配进入精匹配的最低分数门槛 启用后:更严格,较少候选进入精匹配 启用后:更多候选进入,也可能带入假匹配 当前闭环未执行;须分数>0.35,且x、y方差都过门槛;不是35%定位置信度
loop_match_minimum_response_fine 0.45 无量纲,归一化匹配分数 当前运行不使用这个参数,暂不调整 最终闭环精匹配的分数门槛 启用后:更难接纳闭环,也可能漏掉真实重访 启用后:更易接纳,也更容易错连重复结构 当前闭环未执行;该步分数≥0.45才进入闭环连接/优化;不是45%成功概率或定位精度
1.4.3.2.Parameter Details
1.4.3.2.1.use_scan_matching (whether to use 2D contours to correct odometry)

Scan matching after activation can be understood as follows: first, place the current 2D contour according to the odometry estimate, then compare it with recently existing contours to find a more closely matching position and orientation. It may reduce 2D odometry error, but it may also find incorrect correspondences in repetitive corridors, sparse contours, or misclassified terrain.

The current False continues to use the motion estimation provided upstream by Point-LIO and still generates a 2D grid; the source code merely skips this node's 2D matching, graph nodes, and association construction. This cannot be used to claim that the vehicle SLAM has been disabled, nor can it be used to prove that the long-distance 2D graph will not drift.Normal processing path (2.6.10)

Whether it needs to be enabled should be determined based on long-distance, turning, and revisit results. 2D correction will not write back to the PCD saved by Point-LIO; the current mapping also uses a static identity map→odom, so before enabling it, the relationship among the 2D map, PCD, and positioning reference frame must be checked together. This switch cannot fix gravity, extrinsics, point timing, or slope misclassification.

1.4.3.2.2.use_scan_barycenter (uses echo centroid to measure scan spacing, currently not used)

When True, use the average position of valid echo endpoints in one scan as the reference for map distance determination; when False, use the scan center. The centroid here refers to the 'observed environmental points,' not the chassis center of mass, and it does not change the navigation reference frame to the gimbal frame.

Occlusion, changing visible walls or moving objects can shift the point barycenter even with little vehicle motion. It affects nearby graph-association coverage, but current use_scan_matching=False bypasses that path. Scan insertion displacement is still measured using the chassis or virtual scan center.Reference-point definition

1.4.3.2.3.minimum_travel_distance (how far to go before adopting the next scan)

Currently there are two filters, and it cannot be understood merely as "one frame per 10 cm":

  1. Outer slam_toolbox entry: typically requires a scan stamp interval of at least 0.2 s, also requires a horizontal displacement of at least about 8.94 cm relative to the last released scan, and is subject to frame dropping and initial count limitations.
  2. Inner Karto: relative to the last actually adopted scan, a displacement of about 10 cm or an orientation change of about 5.73° can release it; here the scan center is used, which currently coincides with base_footprint.

The outer layer executes first, and it updates its own comparison baseline after allowing the scan; if the inner layer rejects that scan, the two baselines will temporarily differ. Therefore, the actual step distance also depends on speed, turning angle, input period, and processing results. Increasing it generally reduces the number of included map portions, while decreasing it generally increases them; if it is too sparse, small structures near turns may be insufficiently covered.

There is also a version-specific distinction: ROS parameter minimum_time_interval=0.2 is used by the outer layer, but current SMapper::configure does not pass it to Karto. For a new map, Karto’s internal time fallback remains the default 3600 s, so ordinary short mapping sessions mainly rely on inner distance and rotation conditions. The 0.2 s parameter remains active, but does not mean both layers use the same time gate.ROS-to-Karto parameter wiring

1.4.3.2.4.minimum_travel_heading (angle interval of the incoming map, 0.1 is approximately 5.73°)

Units are rad; 0.1 does not mean 0.1°. The inner layer compares planar yaw changes between scans. Decreasing this lets smaller turns pass the inner condition; increasing it requires more rotation. It cannot bypass the earlier time and displacement filters.

After the first frame, when rotating the chassis in place or rotating the gimbal independently, if the x and y of the chassis TF remain unchanged, the scan will first be blocked by the outer layer; even if the inner-layer rotation angle could meet the requirement, it has no chance to participate in the judgment.Only reducing minimum_travel_heading cannot resolve the current entry point's limitation on in-place rotational scanning. This involves mapping sampling; it does not control the chassis wz, the gimbal mechanical yaw, and it is not a climbable slope angle.

1.4.3.2.5.scan_buffer_size (recent matches retain several scans, not currently used)

When matching is enabled, at most 10 recent scans are retained for continuous matching; this differs in meaning from the previous scan_queue_size=10, where the latter caches messages waiting for TF. This is also not "keeping only 10 histories for the entire map"; scans moved out of the recent window can still remain in the mapping history.

If the linear mapping step is exactly 0.1 m, the first and last of 10 scans are separated by about 9 intervals, i.e., 0.9 m; the actual step is not necessarily 0.1 m, so the number of parts cannot be directly converted into a fixed number of meters or seconds. Currently, no scans are added to this matching window, and no adjustment is made for now.

1.4.3.2.6.scan_buffer_maximum_scan_distance (distance between the beginning and end of the recent window, currently unused)

When enabled, the recent window is simultaneously constrained by both the 10-scan limit and the 10 m head-to-tail center spacing; if either limit is exceeded, scans are removed starting from the oldest until both conditions are satisfied. The distance is the straight-line distance between the head and tail; looping back to near the start does not mean the cumulative path length is small, nor is it the 10 m range of the radar echo.

When the copy-count limit is reached first, increasing by 10 m usually does not make the window larger; the two need to be understood together with the actual step size in the map. The current match is off, and the window deletion logic does not participate in the result.

After graph association is enabled, the current scan is matched against nearby historical scan chains, and such associations are accepted only if the score is high enough. 0.1 is the normalized score for contour matching, not "a 10% probability of matching correctly."

This is not a universal quality check for every sequential match. In the current version, Mapper::Process does not use this parameter to reject scans based on the sequential MatchScan score. The nearby-chain threshold therefore cannot catch all incorrect sequential matches. The entire matching branch is currently disabled, so changing this does not improve the existing map.

When enabled, only neighboring chain associations whose reference points are within about 1.5 m of each other are considered; currently with barycenter=True, the reference point is the environmental echo barycenter. Increasing it can include farther candidates but may also increase ambiguity from repeated structures; decreasing it makes it more restrictive.

It is not "the laser only looks at 1.5 m," nor is it the vehicle collision distance or the allowable map error; changing this does not change the upstream scan range.

1.4.3.2.9.loop_search_maximum_distance (from which old regions to find closed loops, not needed currently)

After loop closure is enabled, 3 m is used to filter the distance between the current scan and the reference point of the old scan; it does not mean that returning to the old position is determined if within 3 m. Candidates still need to pass the chain and matching conditions; the range of the subsequent matching search grid is another set of parameters.

For example, the vehicle may physically return to an old position, but the estimated reference point has already drifted far enough that the old region may fall outside the 3 m candidate range; increasing it can broaden the search range, but it also increases the chance of mistaking a similar corridor for the same region. Automatic loop closure is not currently performed, so no adjustment will be made for now.

1.4.3.2.10.do_loop_closing (automatic revisit identification and closed-loop correction)

A loop closure can be understood as: after traveling around, recognizing an area that was previously passed through, and using this new constraint to readjust the 2D trajectory so that the earlier and later contours are more consistent. A successful loop closure may reduce accumulated drift; an incorrect loop closure may also distort the entire map.

Currently False, and it is located inside the branch where use_scan_matching=True, so changing only do_loop_closing to True still will not run it. Conversely, enabling scan matching but keeping loop closure False still allows recent matching and ordinary nearest-neighbor chain association to run, just not the automatic loop-closure path.

This is slam_toolbox's own 2D functionality, not small_gicp real-time point cloud localization against the prior PCD. Even if loop closure succeeds, it does not automatically correct the independently saved 3D PCD or resolve the current static map→odom coordinate connection.

1.4.3.2.11.loop_match_minimum_chain_size (at least several copies of the history chain, not needed at present)

10 represents the number of scan copies of the candidate history chain, not 10 radar points or 10 m. Increasing it requires more historical structures, while decreasing it allows shorter chains to participate.

LinkNearChains, the ordinary near-neighbor chains in the source code, also use it, so even if do_loop_closing remains False in the future, as long as scan matching is enabled, it may still affect ordinary graph association. Currently, neither of these two association paths is enabled, so no adjustment will be made for now.

1.4.3.2.12.loop_match_maximum_variance_coarse(配置先平方,内部门槛9 m²)

粗匹配可能有多个近似答案。当前2.6.10读取YAML值3.0后,setParamLoopMatchMaximumVarianceCoarse会先平方,内部方差门槛实际为3.0²=9.0 m²。按赋值链与方差比较的量纲,配置值按位置分散尺度(m)理解,内部才使用m²。

这里检查算法给出的x、y方差各自是否小于9.0 m²;正值范围内,配置值越小要求结果越集中。不检查yaw方差,也不保证实际位置误差小于3 m。平方赋值与方差判定源码

它与small_gicp的max_dist_sq含义及配置尺度都不同:本项配置3.0先平方为9.0 m²的匹配结果方差门槛;max_dist_sq的配置值本身就是m²,3.0直接表示3.0 m²的点对应距离平方门槛。不能因为两项都写3.0就认为容差相同。当前闭环关闭,无须调整工程数值。

1.4.3.2.13.loop_match_minimum_response_coarse (the threshold for entering fine matching from coarse matching; currently not used)

The score must be greater than 0.35, and the variances of x and y must simultaneously pass the previous item, before entering fine matching. Increasing it makes it stricter, decreasing it relaxes it; the score comes from the degree of agreement between the contour and the correlation grid, normalized to the range 0 to 1, and is not a calibrated localization confidence.

1.4.3.2.14.loop_match_minimum_response_fine (final closed-loop matching threshold, currently unused)

After coarse matching is passed, fine matching is performed; only when the final score reaches 0.45 does the system proceed to loop closure connection and trajectory optimization. A stricter threshold may miss valid revisits, while a looser one may incorrectly link repeated structures; reaching 0.45 must not be interpreted as the position already being accurate.

These three quality thresholds act together; one cannot look only at one of the coarse score, fine score, or variance. The matching processes used at the coarse and fine levels also differ, so the two scores should not be directly compared as if they were on the same confidence scale.Candidate Association and Closed-Loop Decision Source Code

1.4.3.2.15.Read Timing and Verification Scope

Parameter names are case-sensitive according to the current source code: do_loop_closing and lowercase loop_are the actual key names; the do_loop_close, Loop_and other forms in the tutorial cannot be used directly as parameter names in this project.

This group of 14 items is read by SMapper::configure and set into Karto. During conventional mapping from an empty map, use_scan_matching=False causes recent matching, graph association, and loop closure branches to be skipped; distance and turning angle are still used for the insertion decision. The relevant path has no dynamic parameter update callback, and the outer layer also statically caches the distance threshold, so setting new values during runtime cannot be equated with all these conditions having been updated.

  • 源码能确认: 当前配置关闭二维匹配和自动闭环;距离/转角仍有作用但受两层门槛约束;重心只改变图距离参考;近期窗口不限制全部历史;链长度还用于普通关联;闭环配置尺度按m理解,先平方为m²方差门槛,当前3.0对应9.0 m²;响应值不是成功概率。
  • 已有验证范围: 仅独立Point-LIO静止与约20 cm低速往返;未验证slam_toolbox长距离、转弯、独立云台yaw、闭环或与PCD的一致性。
  • 实物待核实: 移动/原地转动时实际入图连续性,长距离及重访误差,坡道有效二维轮廓、遮挡与动态干扰;若需启用匹配/闭环,还须核对二维修正与PCD及定位参考系的衔接。

1.4.4.Correlation Parameters - Correlation Parameters (Normal Scan Matching Search)

These three settings can be understood as:how wide a nearby region to search, how far apart to test positions, and how much matching score to retain for slightly misaligned outlines. They control an internal matching grid, distinct from the output map grid at resolution=0.05 m.

Currently use_scan_matching=False, so ordinary match scoring is not performed; however, when the first valid scan enters Karto, a matcher is still created, using these 3 items to allocate the grid and check the numerical combination. Therefore, for now, keep it as is; "match not performed" cannot be understood to mean that any settings have no effect.

1.4.4.1.Parameter table
    # Correlation Parameters - Correlation Parameters
    correlation_search_space_dimension: 0.5
    correlation_search_space_resolution: 0.01
    correlation_search_space_smear_deviation: 0.1
Parameter Current value Units Hardware guidance Purpose Effect of increasing Effect of decreasing Activation conditions / notes
correlation_search_space_dimension 0.5 m; coarse translation search-region side length Usually keep the current value; not a priority for tuning Search for position corrections around the current two-dimensional pose estimate Within valid combinations: broader candidate translations, potentially more matching work and initial grid allocation, and more similar locations Narrower range with fewer candidates; the true correction may lie outside it Currently unused in matching, but still used for initialization. 0.5 m gives roughly ±0.25 m in x and y, not a 0.5 m radius. Angular coverage is separate
correlation_search_space_resolution 0.01 m per cell; correlation-grid spacing Usually keep the current value; not a priority for tuning Set the discrete scale of the matching grid and translation candidates Within valid combinations: coarser grid and steps, usually lower resource cost but less distinction between small misalignments Finer grid and steps, with more candidates and grid memory; does not guarantee greater accuracy Currently unused in matching but still used for initialization. This version’s coarse step is twice grid spacing, 2 cm; fine step is 1 cm. Not the output map’s 5 cm resolution
correlation_search_space_smear_deviation 0.1 m; matching-score smear standard deviation σ Usually keep the current value; not a priority for tuning Assign gradually decreasing scores around return endpoints so slightly misaligned outlines still produce a response Within valid combinations: wider, smoother scoring outlines tolerate more misalignment but distinguish nearby structures less readily Sharper scoring, but sparse points and small noise lower response more readily Currently unused for scoring, but the kernel is still initialized. Not permission for 10 cm localization error or an obstacle inflation radius. 0.1 is already the maximum allowed by current grid spacing and cannot be increased independently
1.4.4.2.Parameter Details
1.4.4.2.1.correlation_search_space_dimension (how large a range to search around the estimated position)

Test translations in the mapping plane’s x and y directions around the current internal two-dimensional scan pose. 0.5 m is the coarse-search square’s side length, giving approximately ±0.25 m per direction. The center comes from odometry or existing scan corrections, rather than the map origin, gimbal mechanical zero position or a Nav2 target.

For example, the true contour deviates by about 15 cm from the estimated position, and the range may include the correct translation; if a single match requires correction of about 40 cm, the default coarse search may not reach it. Including candidates only means "an attempt will be made," and does not guarantee that the correct position can be selected in repeated corridors or sparse points.

This is the coarse translation range; it does not directly expand the yaw search angle, nor does it require the vehicle to move to the candidate position. Fine matching will also search again near the coarse result; the current local fine search translation is about ±1 cm, so ±0.25 m is also not the absolute boundary of the final correction amount.

1.4.4.2.2.correlation_search_space_resolution (1 cm grid spacing; coarse search actually tested at 2 cm)

Current internal correlation-grid cells are 1 cm. Coarse translation steps move across two cells, or 2 cm; normal refinement returns to 1 cm steps within a small region around the coarse result.Search range and coarse and fine step implementation

Therefore, 0.01 cannot simply be understood as "a full fine search every 1 cm across the entire 0.5 m range," nor can it be treated as a 1 cm positioning accuracy. The output 2D image still uses resolution=0.05 m, Point-LIO and the terrain downsampling scale will not change because of this either.

Within the valid combination, if the search range is fixed while the step size is halved, the number of translation candidates increases by about a factor of 4; the total workload is also affected by the number of angle samples and scan points. The associated grid must also cover the valid echo range, and is not merely allocated as small cells of 0.5×0.5 m; reducing the grid spacing also increases initialization memory.

1.4.4.2.3.correlation_search_space_smear_deviation (fading matching score around the contour)

This can be understood as adding a "gradually weakening soft edge" around the internal matching contour: when the current point does not fall exactly on the old contour, a slightly offset point can still receive a score, and the farther away it is, the lower the score. Here a Gaussian standard deviation is used; σ=0.1 m does not mean "everything within 10 cm counts as a match, and everything outside does not count at all".

A wider soft edge may help match sparse or slightly noisy contours, but it also weakens discrimination between nearby positions. It affects only the internal matching score; it does not directly thicken the saved 2D walls, is not Nav2 obstacle inflation, and does not clear dynamic objects or change slope elevation differences.

Matching is currently disabled, so tuning this cannot improve the existing map. If enabled later, first verify IMU, LiDAR and chassis transformations, point timing and valid two-dimensional outlines. Expanding search or smearing cannot replace these interface checks.

1.4.4.2.4.All three must be used together: the current value is valid, and the coating has reached its upper limit.

The current version has these combination constraints:

  • The dimensions and grid spacing must be positive; the source code builds a discrete grid according to dimension/resolution, and the assertion requires this ratio to be an integer, and makes the relevant grid side length odd. According to this creation logic, one should choosea positive even integer ratio; the current 0.5/0.01=50 satisfies the condition.
  • The smearing standard deviation must be within0.5×格距~10×格距The boundary is inclusive. The current grid spacing is 0.01 m, corresponding to σ of 0.005–0.1 m, and the current 0.1 m is at the upper limit.
  • For example, if only the grid spacing is changed to 0.005 m while keeping σ=0.1 m, then the allowed upper limit becomes 0.05 m, and initialization will throw an exception; even if scan matching is disabled, this check cannot be bypassed.

The check of the combination of range and grid spacing uses assert; whether it actually triggers also depends on whether assertions are enabled at compile time; one cannot judge that the combination is reasonable merely because the program can start. The smearing range check explicitly throws runtime_error, and the error message may say "too small" even though the actual problem is exceeding the upper limit.Smearing kernel and value limits

1.4.4.2.5.Read and use paths

Three items are read in SMapper::configure and set to Karto; non-positive values fall back to 0.5, 0.01, and 0.1 respectively; the grid is created when the first valid scan initializes it, and there is no callback to automatically rebuild after dynamically modifying parameters.Parameter reading implementation

After scan matching is enabled, this ordinary matcher is used for recent matching and ordinary nearest-neighbor association; if loop closure is enabled later, the loop closure's fine matching will also reuse it. The following loop_search_space_* controls another loop closure matcher; different partitions do not mean the two pipelines are completely independent.

  • Confirmed from the source code: Search side length, coarse and fine steps, smear standard deviation and combination constraints. Scoring is not currently executed, but matching grids are still initialized. These three settings cannot all be treated as unread parameters.
  • Existing verification scope: Standalone Point-LIO while stationary and during roughly 20 cm of slow back-and-forth motion. This node’s search success rate, resource use, turns, independent yaw and slope-outline matching remain unverified.
  • Pending hardware checks: If matching is enabled, check that actual pose corrections lie within the usable range, two-dimensional structures are sufficiently distinguishable, and noise, occlusion and computation costs are acceptable. Also verify consistency between two-dimensional corrections and the PCD localization basis.

1.4.5.Correlation Parameters - Loop Closure Parameters (loop closure coarse matching search)

These three items are used for the large-scale coarse search when revisiting old areas after detouring: how large a position range to search, how fine a grid to use, and how wide a matching score margin to allow around old contours. Subsequent fine matching will still reuse the previous set of ordinary matchers, so the two partitions are not completely independent.

Both current hardware and simulation configurations use use_scan_matching=False and do_loop_closing=False, so automatic loop-closure scoring does not run. The loop-closure matching grid is still created when the first valid scan initializes, so numerical combinations and memory allocation still matter.

1.4.5.1.Parameter table
    # Correlation Parameters - Loop Closure Parameters
    loop_search_space_dimension: 8.0
    loop_search_space_resolution: 0.05
    loop_search_space_smear_deviation: 0.03
Parameter Current value Units Hardware guidance Purpose Effect of increasing Effect of decreasing Activation conditions / notes
loop_search_space_dimension 8.0 m; coarse loop-closure translation search-region side length Usually keep the current value; not a priority for tuning Search around the estimated scan position for alignment with a candidate old outline Within valid combinations: broader searches, greater computation and grid costs, and more chance of similar structures Narrower, faster searches, but the true correction may lie outside the region Currently unused for loop-closure scoring but still used for initialization. 8 m is the square side length, approximately ±4 m in x and y. Distinct from the 3 m historical-candidate distance
loop_search_space_resolution 0.05 m per cell; loop-closure correlation-grid spacing Usually keep the current value; not a priority for tuning Set the discrete scale of the coarse loop-closure grid and translation candidates Within valid combinations: coarser grids and search steps usually reduce resource cost but more readily miss narrow matching peaks Finer grids, more candidates and greater initialization memory; no guarantee of greater localization accuracy Still used for initialization. 5 cm cells give 10 cm coarse steps; final fine matching reuses the ordinary matcher. Not output map resolution
loop_search_space_smear_deviation 0.03 m; loop-closure scoring smear standard deviation σ Usually keep the current value; not a priority for tuning Assign gradually decreasing scores around old outlines so slight misalignment still produces a response Within valid combinations: wider scoring outlines tolerate more misalignment but distinguish nearby structures less readily Sharper scoring; sparse points or outline changes lower response more readily The smear kernel is still initialized. 3 cm is standard deviation, not permitted localization error. Current grid spacing requires σ from 0.025 to 0.5 m
1.4.5.2.Parameter Details
1.4.5.2.1.loop_search_space_dimension (8 m search edge length, different from the 3 m candidate distance)

The loop first selects historical scans that may be revisited, then moves the current scan to compare with the old contour. These two steps are controlled by different parameters respectively:

  • loop_search_maximum_distance=3.0 m: Filter nearby historical candidates and compare the distances between scan reference points. Currently use_scan_barycenter=True, and the reference point uses the centroid of valid echo endpoints.
  • loop_search_space_dimension=8.0 m: For the already selected candidates, with the current estimated scan pose as the center, attempt translation within approximately ±4 m in both the x and y directions of the mapping plane; this is an 8×8 m coarse search square.

Therefore, expanding to an 8 m search region cannot recover old regions that have already been excluded by the 3 m candidate distance. 8 m is also not the distance the vehicle must travel, the radar range, or the scope for globally searching for a position around the map; angular search has separate parameters.Candidate filtering and translational search implementation

If the physical environment passes through repetitive corridors, similar pillars, or a large number of dynamic obstacles, a larger range may find more locations that "look alike." First confirm whether the true 2D contour is stable and whether the position deviation exceeds the search range before considering adjustment; these parameters are not responsible for identifying slope or determining ramp passability.

1.4.5.2.2.loop_search_space_resolution (5 cm grid, closed loop initially rough-searched at 10 cm)

In this version, the coarse search spans two cells, so the current actual translation step is 2×0.05=0.1 m. The closed-loop process is:

  1. Use this group's 8 m range and 5 cm grid to complete coarse matching; at this stage, no further internal refinement at a 5 cm step is performed on this group's grid.
  2. After the coarse score and x, y variances pass the preceding thresholds, center on the coarse result and call thestandard matcherusing the previous group's 0.5 m range and 1 cm grid: first perform a 2 cm coarse search, then perform a 1 cm fine search within approximately ±1 cm around the obtained result.
  3. Only after the fine score passes the threshold are loop closures connected and the 2D trajectory optimized.

Therefore, 0.05 neither means that the final positioning error is 5 cm, nor does it control all subsequent fine searches. The output 2D map resolution is also 0.05 m; the values are merely the same and it belongs to another parameter.Closed-loop coarse-fine matching invoked

With the side length fixed and the grid spacing halved, the number of translation candidates increases by about a factor of 4, and the grid memory also increases; the total computational cost is also affected by the angles and the number of points. The final fine matching may also extend beyond the original coarse search boundary, so ±4 m is not an absolute upper limit on the final correction amount.

1.4.5.2.3.loop_search_space_smear_deviation (add a fading score ring to the old silhouette)

Same smearing meaning as ordinary matching, but here it is used only for closed-loop coarse matching. σ = 0.03 m can be understood as a relatively narrow scoring profile, where a slight offset still yields a score; it must not be understood as "everything within 3 cm is correct, and everything outside is wrong."

Smearing is discretized on a grid: the current combination generates a 3×3 cell kernel, extending one cell from the center in each of the x and y directions, i.e., 5 cm, with neighboring cell scores gradually decreasing. Therefore, a standard deviation of 3 cm and the kernel's actual coverage boundary are not the same quantity; it also does not directly thicken the saved walls or change navigation obstacle inflation.

The current 5 cm grid spacing allows σ from 0.025 to 0.5 m, and 0.03 m is legal. For example, if the grid spacing alone is increased to 0.1 m while σ = 0.03 m is retained, the new lower limit will become 0.05 m, and initialization will throw an exception; the check is performed even when the loop is closed.Allowable range and smearing kernel implementation

1.4.5.2.4.Combination restrictions, reading, and physical verification

The range and grid spacing must also satisfy the discrete grid constraint of the previous group: select a positive even integer ratio according to the creation logic; the current 8/0.05=160 satisfies the condition. Whether the relevant assert is executed depends on the compilation settings; if the smear goes out of bounds, an exception is explicitly thrown.

Three items are read and set into Karto in SMapper::configure; non-positive values fall back to 8.0, 0.05, and 0.03 respectively. The grid is created on the first valid scan, and there is no parameter callback that automatically rebuilds after these three items are modified during runtime.Parameter reading implementation

  • Confirmed from the source code: Loop-closure scoring does not currently run, but the grid is initialized. 8 m controls coarse search, while 3 m controls historical candidates. Coarse steps are 10 cm; fine closure matching reuses the ordinary matcher.
  • Existing verification scope: Only standalone Point-LIO while stationary and during roughly 20 cm of slow back-and-forth motion. This node’s loop closure, long-distance revisits and computation load were not observed.
  • Pending hardware checks: If loop closure is needed later, check revisit errors, repeated structures, dynamic occlusion, two-dimensional outline changes on slopes or during gimbal rotation, and computation load. Two-dimensional loop closure does not automatically correct a separately saved PCD; their localization coordinate bases must still agree.

1.4.6.Scan Matcher Parameters (Scan Matching Scoring and Search)

These two settings can be understood as:how much score to deduct when outline matching changes the estimated position or heading. When outline alignment scores are similar, the penalty favors an answer closer to the current estimate.

The easy-to-reverse relationship is:a larger configured value gives a lighter penalty; a smaller value gives a heavier penalty. Currently use_scan_matching=False, so both settings are read but do not participate in matching scores. Leave them unchanged for now.

1.4.6.1.Pose deviation penalty parameter table
    # Scan Matcher Parameters
    distance_variance_penalty: 5.5
    angle_variance_penalty: 5.0
Parameter name Current value Unit Vehicle handling suggestion Function Effect of increasing Effect of decreasing Effective conditions / remarks
distance_variance_penalty 5.5 m, distance penalty scale; squared internally This parameter is not used in the current run; do not adjust for now Reduces the score of translation candidates that deviate from the center of this search Within the positive range: for the same offset, the penalty is lighter, allowing contour matching to correct the estimate more; does not expand the search range The penalty is heavier, biasing more toward the vicinity of the estimate; it may also suppress necessary corrections, and once the coefficient lower limit is reached it will not decrease further Scan matching is currently disabled; the configured 5.5 is first squared to 30.25 m² and then enters the formula; it is not an allowed deviation of 5.5 m or the measured odometry variance
angle_variance_penalty 5.0 rad, angle penalty scale; squared internally This parameter is not used in the current run; do not adjust for now Reduces the score of yaw candidates that deviate from the heading at the center of this search Within the positive range: for the same angular offset, the penalty is lighter, allowing matching to correct the heading more; does not expand the angular search range The penalty is heavier, biasing more toward the estimated heading; it may also suppress necessary corrections, and once the coefficient lower limit is reached it will not decrease further Scan matching is currently disabled; the configured 5.0 is first squared to 25 rad²; it is not a 5° limit, angular velocity, or gimbal mechanical angle limit
1.4.6.2.Detailed Explanation of Pose Deviation Penalty
1.4.6.2.1.distance_variance_penalty (how many points to deduct for candidates near the estimated position)

For example, if the estimated scan position is at A, the algorithm attempts to place the current contour at a nearby B to align with the old contour. This item deducts points based on the planar distance between A and B;It does not deduct points based on how many meters the vehicle actually traveled from the previous frame, nor does it send the candidate position to the chassis for execution.

A smaller value will bias more toward the vicinity of A, possibly reducing the chance of being pulled away by similar structures, but it may also suppress correct pose corrections; a larger value relaxes this constraint. It only changes the scores of existing candidates and does not replace the preceding search range, contour quality, or matching threshold.

1.4.6.2.2.angle_variance_penalty (how many points to deduct when the candidate orientation deviation is estimated)

The meaning is the same, but what is compared is the difference between the yaw candidate of the internal 2D scan pose and the orientation of this search center. The normal rotation already included in the estimate is not directly treated as this deviation; the penalty targets the additional orientation correction attempted by the algorithm.

This is neither mechanical relative gimbal yaw in serial JointState nor wz from Nav2 or spin. Tuning it cannot set maximum chassis or gimbal rotation angles, or fix LiDAR-to-chassis transformation errors during gimbal rotation.

1.4.6.2.3.The configuration value is squared first; the unit and name are easily confused.

Under the current assignment chain in 2.6.10, setParamDistanceVariancePenalty and setParamAngleVariancePenalty both first square the passed-in value. The m and rad in the table are interpreted according to this assignment chain and the dimensions of the scoring formula; only the values used internally are m² and rad². The YAML value must not be treated directly as a variance just because the name contains "variance".Assignment and scoring implementation

Let d be the planar offset of the candidate relative to the search center, and θ be the orientation offset (in radians). With the current configuration, the calculation method is:

  • Distance coefficient: max(0.5, 1 − 0.2 × d² / 30.25).
  • Angle coefficient: max(0.9, 1 − 0.2 × θ² / 25).
  • Candidate score = original contour matching score × distance coefficient × angle coefficient.

0.5 and 0.9 come from the later minimum_distance_penalty and minimum_angle_penalty, representing lower bounds for the coefficients: the distance term can multiply the score by at most 0.5, and the angle term by at most 0.9; they do not permit distance or angle thresholds.

Pure formula example: when the offset is 20 cm, the distance coefficient is about 0.99974; when the orientation offset is 10°, the angle coefficient is about 0.99976. The current values apply only a very light penalty for offsets of this degree; this is a formula result, not a positioning accuracy or real-vehicle validation result.

The coarse search references the current estimated scanning pose, while the internal fine search references the pose obtained from coarse matching; it is not the case that both stages always compute the score relative to the same original odometry position.

1.4.6.2.4.Effective Path and Physical Verification

Recently, scan matching enables this penalty by default; ordinary nearest-neighbor chain association, and the coarse and fine matching calls of automatic loop closure, explicitly disable the penalty. Therefore,after enabling scan matching, not all matching uses these two items; although loop closure reuses the ordinary matcher for refinement, it still skips the penalty here.

The two current values match across hardware and simulation nav2_params.yaml and installed copies, passed through slam_launch to sync_slam_toolbox_node. SMapper::configure reads them and sets Karto values. Without ROS-wrapper parameters, defaults are 0.5 and 1.0, differing from this project’s 5.5 and 5.0.Parameter-reading implementation

A finite positive number should be used: this read chain has no automatic fallback for non-positive values; negative numbers will be squared, and 0 will make the scoring denominator 0. It cannot use 0 to indicate that the penalty is disabled, nor can setting the ROS parameter at runtime be regarded as the internal scoring scale having been synchronously updated.

  • Confirmed from the source code: Values are squared before scoring; larger positive values give lighter penalties. The reference is the current search center. Currently unused for scoring; nearby associations and loop closure also do not use this penalty.
  • Existing verification scope: Standalone Point-LIO while stationary and during roughly 20 cm of slow back-and-forth motion. This node’s translation and rotation corrections or penalty effects remain unverified.
  • Pending hardware checks: If scan matching is enabled later, observe whether repeated structures pull estimates away or necessary corrections are suppressed. First verify coordinate transformations, point timing and stable two-dimensional outlines. Slope recognition still requires terrain-analysis and scan-generation checks; these two scoring scales cannot repair it.
1.4.6.3.Angle Search and Penalty Lower Bound Parameter Table

Currently use_scan_matching=False, these 6 items will be read but will not participate in the matching search and scoring of the current automatic mapping process. If matching is enabled in the future, the current angle search can be summarized as:Coarse search: about 20° to the left and right, trying once every 2°; fine search: within about 1° to the left and right of the coarse result, trying once every 0.2°.

    fine_search_angle_offset: 0.00349
    coarse_search_angle_offset: 0.349
    coarse_angle_resolution: 0.0349
    minimum_angle_penalty: 0.9
    minimum_distance_penalty: 0.5
    use_response_expansion: true
Parameter Current value Units Hardware guidance Purpose Effect of increasing Effect of decreasing Activation conditions / notes
fine_search_angle_offset 0.00349 rad per step; approximately 0.2° Unused in the current execution path; leave unchanged for now Control internal fine-search yaw sampling steps Sparser fine searches with usually fewer candidates; may miss narrow matching peaks Denser fine searches and more computation; no guarantee of greater angular accuracy Currently unused. This version uses it as a step size, not a fine-search half-range. Current fine-search half-range is about 1°
coarse_search_angle_offset 0.349 rad; coarse-search half-range, approximately 20° Unused in the current execution path; leave unchanged for now Test yaw corrections on both sides of the estimated scan heading Broader coarse searches with more candidates and computation; more chance of similar headings Narrower searches with fewer candidates; the true heading correction may lie outside the range Currently unused. Coarse search is roughly ±20°, about 40° total; not a chassis or gimbal rotation limit
coarse_angle_resolution 0.0349 rad per step; approximately 2° Unused in the current execution path; leave unchanged for now Control coarse yaw steps and the internal fine-search half-range Sparser coarse angle sampling, but a larger fine-search half-range; computation cannot be judged only by coarse candidate count Denser coarse angle sampling, with a smaller fine-search half-range Currently unused. Fine-search half-range equals this value divided by 2, currently about ±1°. Must be compatible with the fine step
minimum_angle_penalty 0.9 Dimensionless; lower bound for the angle penalty factor Unused in the current execution path; leave unchanged for now Limit the maximum score reduction from the angle term Raise the floor, giving a lighter penalty when clamped; 1 disables this score reduction Lower the floor, permitting a heavier angle penalty; unchanged before reaching the floor Currently unused. Used only when the internal call enables penalties. 0.9 is neither 0.9 rad nor a 90% matching-success rate
minimum_distance_penalty 0.5 Dimensionless; lower bound for the distance penalty factor Unused in the current execution path; leave unchanged for now Limit the maximum score reduction from the distance term Raise the floor, giving a lighter penalty when clamped; 1 disables this score reduction Lower the floor, permitting a heavier distance penalty; unchanged before reaching the floor Currently unused. 0.5 is neither 0.5 m nor a final score threshold. The current formula usually does not reach this floor
use_response_expansion true Boolean Unused in the current execution path; leave unchanged for now Retry with expanded angular coverage when coarse response is approximately zero True: add angular searches when triggered, increasing computation and similar-heading candidates False: add no angular expansion, but normal coarse and fine searches remain available Currently not reached because matching is disabled. At most three extra attempts, each increasing the half-range by 20°. Expands angles only, not translation or LiDAR range
1.4.6.4.Detailed Explanation of Angle Search and Deduction Lower Limit
1.4.6.4.1.fine_search_angle_offset (fine search tests approximately every 0.2°)

The name and some tutorials describe it as the "fine search angle range", but the current source code passes it to the angle step position; the actual fine search half-range takes 0.5×coarse_angle_resolution, currently 0.01745 rad, about 1°.

Therefore, currently within approximately ±1° around the coarse matching orientation, a trial is performed every 0.00349 rad (about 0.2°), giving a total of 11 angle candidates. Reducing this item only makes the trials denser within this range; it does not expand the range, nor does it mean that the final orientation error can reach 0.2°。Actual invocation of coarse and fine search

The internal fine search here is used for refinement by the ordinary matcher; the large-range coarse matching of the automatic closed loop does not perform this refinement on the closed-loop mesh, and it is used only when the ordinary matcher is subsequently invoked.

1.4.6.4.2.coarse_search_angle_offset (coarse search over an estimated range of approximately 20° to the left and right)

0.349 is radians, about 20°, representing the coarse search half-range on both sides of the current estimated 2D scanning orientation. What it searches for ishow many more degrees the estimate still needs to be corrected by, not how many degrees the vehicle is allowed to turn between two frames.

For example, if a normal 30° turn is already correctly reflected in odometry, matching needs no additional 30° correction. Large chassis or gimbal turns do not justify increasing this parameter by the same angle. It also does not handle pitch, roll, slope recognition or gimbal mechanical limits.

1.4.6.4.3.coarse_angle_resolution (coarse search step approximately 2°, which also affects the fine search range)

The current coarse search ranges from approximately −20° to +20°, taking one candidate every approximately 2°, for a total of 21 angles; then refinement is performed within half a coarse step on each side of the coarse result, that is, within approximately ±1°.

When tuning, the first two items should be considered together: if this item increases, the coarse candidates decrease, but the internal fine search range widens; if this item decreases, the coarse candidates increase, but the fine search range narrows. The source code takes the number of candidates as round(total range / step size) + 1, so it is advisable to keep the range and step size segmentable in a reasonable way, and the coarse and fine items must not be treated as mutually independent knobs.

1.4.6.4.4.minimum_angle_penalty (minimum score to retain for angle items)

0.9 meansthe angle penalty term alone can deduct at most 10%. The actual factor is the larger of the formula result and 0.9. A computed 0.98 remains 0.98, rather than always multiplying by 0.9; a computed 0.7 is clamped to 0.9.

It is not an angle threshold or a lower bound on the final matching score. It will later be multiplied by a distance coefficient, so the total score is not guaranteed to retain 90%.

1.4.6.4.5.minimum_distance_penalty (how many points to retain at minimum for the distance term)

Similarly, 0.5 means that the distance penalty alone can deduct at most 50%.Increasing the lower bound will reduce the penalty after hitting the bottom, while decreasing it allows more points to be deducted.

Combined with the previously verified squared denominator, when the current coarse search range for x and y is approximately ±0.25 m each, the distance coefficient is at least about 0.99917; even if the coarse angle is expanded to about ±80°, the angle coefficient is still about 0.9844. Both are higher than the current lower limits of 0.5 and 0.9, so even if normal matching is enabled later, changing only these two lower limits may still produce no visible change. This is a result calculated based on the current search bounds and has not been verified by running.

Both lower bounds take values in the range 0 to 1 under normal scoring semantics. Setting 1 will prevent the corresponding term from incurring any further penalty; setting 0 only allows the coefficient to drop to 0, and does not mean the penalty is disabled. The source code does not perform complete range validation, so values outside the valid range should not be used to express stronger or weaker normal penalties.Scoring coefficient and lower-bound implementation

1.4.6.4.6.use_response_expansion (when the coarse response is close to 0, only expand the angle and retry)

After enabling, the source code first completes the normal coarse search; only when the best coarse response is approximately equal to 0 does it additionally attempt:

  • Each time, increase the coarse search half-range by another 20°, up to a maximum of 3 times. Currently it starts at about ±20°, then tries approximately ±40°, ±60°, and ±80° in sequence.
  • Once the coarse response is no longer approximately 0, stop adding further angle expansion; do not keep expanding just because it remains below the closed-loop 0.35/0.45 score threshold.
  • The translation range, angular step, and radar range remain at their original values; it does not search the entire map for a position, nor does it belong to the PCD relocalization of small_gicp.

These angle parameters and extensions can be used for ordinary matching, ordinary nearest-neighbor association, and automatic loop-closure search; the two penalty lower bounds are only used in calls with penalties enabled, while ordinary nearest-neighbor association and loop-closure calls still skip penalties. Approximately ±80° describes the coarse search; subsequent refinement can still slightly exceed the edges, and it must not be treated as a vehicle rotation limit.

Widening the angle may increase time consumption or match similar contours; obtaining a non-zero response does not prove that the localization is correct. If contours are missing in the real object, dynamically occluded, or the 2D contour changes due to pan-tilt rotation or a ramp, expanding the yaw range will not recover the missing information.Zero-response angle widening and stopping conditions

1.4.6.4.7.Reading, tutorial differences, and verification scope

All six values match across hardware and simulation nav2_params.yaml and installed copies, passed with slam_launch to sync_slam_toolbox_node. SMapper::configure reads and directly sets them in Karto. The minimum_distance_penalty ROS-wrapper default is 0.05; this project explicitly overrides it to 0.5.Parameter-reading implementation

fine and coarse step sizes should use finite positive numbers; the reading chain does not automatically fall back for non-positive values, nor does it have a callback to synchronously update the internal matcher after modifying these ROS parameters during runtime. The tutorial's rough_search_angle_offset is not a parameter name actually read here; the current key name is coarse_search_angle_offset; the generalized description of "automatically increasing the grid" should also be understood here as only expanding the angle.

  • Confirmed from the source code: Units are radians. Coarse search is roughly ±20° with 2° steps; fine search roughly ±1° with 0.2° steps. Floors limit maximum penalties. Angles expand only for near-zero response, at most three times, without translation expansion. Automatic matching is currently disabled.
  • Existing verification scope: Only standalone Point-LIO while stationary and during roughly 20 cm of slow back-and-forth motion. This node’s turn matching, angular expansion, loop closure and timings remain unverified.
  • Pending hardware checks: If matching is enabled later, observe residual heading error, false matches between repeated structures, outline changes and computation time. First verify LiDAR, IMU and chassis transformations and point timing. Mechanical relative gimbal angles must not directly replace internal two-dimensional scan heading.