neo_docking2 - Contour Matching Based Docking¶
neo_docking2 is a ROS 2 package and the spiritual successor of neo_docking.
Like neo_docking, neo_docking2 enables the Neobotix robot to autonomously dock with the charging station. However, unlike its predecessor, neo_docking2 does not rely on a depth camera or QR tags to detect the coordinates of the charging contacts. Instead, it uses contour matching—based on one of the ICP (Iterative Closest Point) methods—to determine the docking position. It also switches the safety fields of the Flexisoft system to proceed with docking.
Attention
This documentation describes neo_docking2 version 1.0, released in
September 2026. If you need documentation for an older version or
assistance with an upgrade, please contact us directly via email or open an
issue on the
neo_docking2 GitHub repository.
Attention
This package is supported only for Jazzy and above.
The following instructions provide an overview of how the ROX robot docks with the Wallbox.
Attention
It is recommended to read the hardware documentation for the Wallbox before continuing with this tutorial.
Installation¶
Install the ROS 2 PCL libraries. Open a terminal on the ROX robot and run:
sudo apt install ros-$ROS_DISTRO-pcl-ros ros-$ROS_DISTRO-pcl-conversions
Clone the
neo_docking2package:cd ~/ros2_workspace/src git clone https://github.com/neobotix/neo_docking2.gitSwitch to the branch
jazzyNote
In the release version, the checkout step will be removed.
Unzip the
neo_perception2zip file and add the folder containing the binaries to theinstalldirectory of your workspace.
Attention
neo_perception2 is a closed-source package. The version delivered with the Wallbox is restricted to detecting and docking with the Wallbox only.
Source the installation package from the root of your workspace:
cd ~/ros2_workspace . install/setup.baseBuild the package:
colcon build --symlink-install
Adjusting the navigation goal tolerance:
In the navigation configuration, please make sure the
xy_goal_toleranceis set to0.01. The config files can be founder under~/ros2_workspace/src/rox/rox_navigation/configs.
Parameters¶
Important
The platform-specific offset values must be calibrated for the robot and Wallbox installation. Do not copy offsets from another platform.
The parameters are configured in neo_docking2/launch/dock_param.yaml.
Docking parameters¶
scan_topic:sensor_msgs/msg/LaserScantopic used for contour matching.offset_x,offset_y: Hardware-derived position of the docking frame relative to the recorded Wallbox contour, in metres. The values depend on the robot, scanner mounting and Wallbox contact geometry; they are not coordinates in the map frame.offset_yaw: Hardware-derived orientation of the docking frame relative to the recorded contour, in radians.pre_dock_dist: Distance of the second Nav2 pre-docking pose from the docking frame, in metres. It must be greater than zero.approach_distance: Distance at which the node stops the normal approach and requests theAPPROACHINGsafety mode, in metres. It must be greater than zero.distance_tolerance: Non-negative tolerance added toapproach_distance, in metres.undock_dist: Distance travelled while reversing during undocking, in metres. It must be greater than zero.
Contour-matching parameters¶
initial_guess_x,initial_guess_y: Initial contour correction in thebase_linkframe, in metres.initial_guess_yaw: Initial yaw correction in thebase_linkframe, in radians. Quaternion input is no longer required.geometric_validation_enabled: Enables line and corner validation after GICP converges. Keep it enabled when the Wallbox is close to a wall to reject matches against surrounding wall geometry. It can be disabled for an isolated Wallbox after validating the installation.
For a robot that is always parked at approximately the same pose in front of the Wallbox, configure the initial correction directly in YAML:
neo_docking2:
ros__parameters:
initial_guess_x: 0.0
initial_guess_y: -0.4
initial_guess_yaw: 0.0
geometric_validation_enabled: true
The configured initial guess is applied each time the user calls
/perception/start_matching. Internal matching restarts during an active
docking operation retain the last accepted contour pose instead.
Attention
offset_x, offset_y and offset_yaw are calculated from the
hardware dimensions and vary with the ROX platform customization. Always
begin with the platform-specific values supplied by Neobotix. Apply only
small commissioning corrections after confirming that the hardware setup,
scanner transform, contour detection and localization are correct. Contact
the Neobotix support team if the calculated values are unavailable.
Why residual docking errors can remain¶
The calculated offsets describe the nominal rigid geometry of the robot and Wallbox. Small residual errors can remain on the installed system because of:
- manufacturing and assembly tolerances in the robot, Wallbox and charging contacts;
- scanner-bracket mounting tolerances or an inaccurate scanner transform;
- laser range and angular resolution, surface reflectivity and the angle at which the Wallbox contour is observed;
- discretization of the recorded contour and small GICP or line-fitting errors;
- differences between the nominal
base_linkgeometry and the physical chassis or contact position, including load-dependent chassis deflection; - map resolution, Nav2 goal tolerances or unstable localization during the pre-docking stages.
A small error that has approximately the same magnitude and direction over
several tests can be treated as a commissioning calibration residual and
corrected cautiously with offset_x or offset_y. An error that varies
between attempts must not be tuned away with the offsets; investigate the
scanner transform, contour detection, odometry, map and localization instead.
Tuning lateral docking alignment¶
Starting from the calculated platform value, if repeated docking tests still
show a small, consistent lateral displacement in the same direction, fine-tune
offset_y to shift docking_link laterally relative to the recorded
Wallbox contour. This also shifts the second Nav2 pre-docking pose and the line
followed by the final x-only controller.
A typical symptom is that the robot repeatedly stops at the transition to the
final approach and cannot proceed into APPROACHING mode because Flexisoft
does not recognize the expected Wallbox contour. If the scanner view is clear,
the correct safety-field contour is configured and the failure is caused by a
repeatable lateral displacement, fine-tuning offset_y can move the robot to
the position at which the observed contour aligns with the contour expected by
the APPROACHING safety field.
The lateral compensation can be measured mechanically using the two reference lines on the Wallbox and the corresponding two lines on the robot’s charging pad:
- Keep the robot stationary and move the Wallbox close to the charging pad.
- Make sure that the Wallbox and charging pad are parallel; otherwise, a yaw error will affect the lateral measurement.
- Align one Wallbox reference line with the corresponding line on the charging pad.
- Measure the lateral distance between the other pair of reference lines that remain unaligned. This distance is the magnitude of the required compensation.
- Apply the measured value to the calculated
offset_y. Whether it must be added or subtracted depends on the direction of the docking frame’s y-axis.
Perform this measurement only during commissioning, with robot motion disabled, and secure the Wallbox in its intended operating position before testing.
After applying the measured compensation, validate it as follows:
- Confirm that the correct hardware-derived offset is configured, the scanner
transform is correct, the map and localization are stable, and the lateral
error is repeatable. Do not use
offset_yto compensate for an error that changes between docking attempts. - Inspect
docking_linkin RViz or measure the actual y-error in the docking frame. The difference between/docking_statusand the final controller’s x-distance is not, by itself, a lateral-error measurement. - Change
offset_yin small increments, such as 0.01 metres. The required sign depends on the orientation of the docking frame’s y-axis. - Repeat several docking tests and verify both the frame placement and the physical contact alignment before deployment.
initial_guess_y must not be used for this calibration. It provides an
initial correction for contour matching, whereas offset_y defines the
calibrated lateral placement of the docking target.
Tuning longitudinal docking distance¶
The hardware-derived offset_x establishes the nominal stopping position
along the Wallbox approach axis. Starting from that value, if repeated tests
show that the robot reaches or pushes against the Wallbox farther than intended,
increase offset_x so that docking_link and the final stopping position
are placed farther away from it. If the robot consistently stops too far away,
offset_x can be decreased cautiously.
- Confirm that the offset matches the robot’s hardware configuration and that
the scanner transform, contour and
docking_linkare correct in RViz before changing it. - Change
offset_xin small increments, such as 0.01 m. - Repeat several low-speed docking tests after each change and verify the physical clearance or charging-contact engagement.
- Stop increasing or decreasing the offset when the required contact position is reached without the robot pressing against the Wallbox.
Only use offset_x for a consistent, repeatable longitudinal calibration
error. A scanner stop, changing error between attempts or unstable localization
must be diagnosed separately. initial_guess_x changes the contour-matching
initial correction and must not be used to calibrate the stopping distance.
Available Services¶
/perception/start_matching(std_srvs/srv/Empty): Starts a new contour search using the YAML initial guess. It also clears a previously tracked match./perception/stop_matching(std_srvs/srv/Empty): Stops contour matching and invalidates the tracked match./go_and_dockcannot be used again until matching has been started./perception/init_contour_pose(neo_srvs2/srv/InitializeContourMatching): Optionally updates the activex,yandyawcorrection. The values are expressed inbase_linkand yaw is in radians./go_and_dock(std_srvs/srv/Empty): Starts docking only when contour matching is enabled and an accepted contour has produced a usabledocking_linktransform. The request is rejected or aborted if the required matching state or transforms are unavailable./undock_and_arm(std_srvs/srv/Empty): Starts undocking. After a successful undocking operation, matching is stopped and must be explicitly started before the next docking cycle.
Note
Service names are shown for the default node namespace. Add the robot
namespace when neo_docking2 is launched in one.
Available Topics¶
/docking_status(neo_msgs2/msg/DockingStatus): Reports progress for both docking and undocking. The publisher uses reliable, transient-local QoS, so a late subscriber receives the most recently published status.header: Timestamp and reference frame. The current implementation usesbase_footprint.distance_remaining: Remaining distance in metres. During docking it is derived from thebase_footprinttodocking_linktransform. During undocking it decreases fromundock_distto zero. If the required transform is unavailable, the value can beNaN.finished:truewhen the docking controller has finished processing the active docking or undocking operation; otherwisefalse. This does not confirm that the robot physically docked or undocked successfully. For example, the controller can finish after a timeout or scanner stop whiledistance_remainingis still nonzero. Applications must evaluate the remaining distance and, where applicable, the charging or contact state separately.
Monitor the status with:
ros2 topic echo /docking_status
Prerequisites¶
It is highly recommended to have the Wallbox mapped to prevent even minor localization jumps.
Launching the Docking Process¶
Position the Robot
Place the robot in front of the docking station so that its front laser scanners can view the entire contour.
Start the Docking Package
Attention
Ensure that the robot is localized and the necessary navigation bring-up has been completed.
ros2 launch neo_docking2 docking_launch.py
Start Contour Matching
Configure
initial_guess_x,initial_guess_yandinitial_guess_yawfor the expected parked pose, and then call:ros2 service call /perception/start_matching std_srvs/srv/Empty "{}"This service applies the YAML initial guess in
base_linkand starts a fresh search. If a different correction is needed for the current run, it can be supplied after starting matching:ros2 service call /perception/init_contour_pose \ neo_srvs2/srv/InitializeContourMatching \ "{x: 0.0, y: -0.4, yaw: 0.0}"
Wait for an Accepted Contour
Do not call
/go_and_dockimmediately after starting matching. Wait until the Wallbox contour has been accepted anddocking_linkis visible in TF. With geometric validation enabled, the node prints anAccepted contour geometrymessage. Use RViz to confirm that the detected contour and docking frame align with the physical Wallbox.If matching is stopped or no accepted docking transform is available, the robot does not begin docking.
Initiate Docking
Ensure that
docking_linkis correctly oriented as shown below before starting the docking process.
ros2 service call /go_and_dock std_srvs/srv/Empty {}The docking sequence is:
- Nav2 moves the robot towards the first pre-docking pose calculated from the accepted contour.
- Contour matching runs again using the last accepted fixed-frame pose as its initial estimate, refining the Wallbox pose from the closer view.
- The refined docking pose is frozen in
odomso that later map localization corrections cannot move the final target. - Nav2 completes the pre-docking waypoints.
- The final controller drives only along the docking frame’s x-axis. Its remaining distance and stopping decision use odometry and the frozen docking target rather than the map frame.
Note
During the final approach, the robot can trigger a scanner stop. This is expected because the default
NONEsafety mode uses relatively long and wide safety fields. The docking node stops, requests theAPPROACHINGsafety mode, waits for the transition, and then continues at controlled speed.Once docking is complete, the front frame of the robot will be approximately 1 cm from the charging station, with a deviation of ±0.5 cm.
Charging can be started using the service provided by the neo_relayboardv3 node as follows:
ros2 service call /start_charging std_srvs/srv/Empty {}Undocking
Before undocking from the Wallbox it is essential to stop the charging process:
ros2 service call /stop_charging std_srvs/srv/Empty {}Important
Call the undocking service only while the robot is physically docked at the Wallbox. The safety scanners must have an unobstructed view of the Wallbox and must be able to recognize the Wallbox contour that was recorded and configured for the
DEPARTINGsafety field. If the expected contour is not visible or does not match, the safety system can prevent the robot from moving and the undocking controller can finish after a timeout with a nonzero remaining distance.ros2 service call /undock_and_arm std_srvs/srv/Empty {}The robot moves away by the configured
undock_dist. Monitor/docking_statusif another component needs the remaining distance or completion state.Note
During undocking, the node switches the Flexisoft safety mode to
DEPARTING. After undocking, it restoresNONEand stops contour matching. Call/perception/start_matchingand wait for a newly accepted contour before beginning another docking cycle.
Stopping Matching Without Docking¶
To cancel perception before docking, call:
ros2 service call /perception/stop_matching std_srvs/srv/Empty "{}"
This invalidates the tracked contour and prevents a subsequent
/go_and_dock request from starting until /perception/start_matching is
called again and the Wallbox contour is accepted.
Safety Notes¶
Warning
The map must accurately represent a static environment, and localization must remain stable throughout both Nav2 pre-docking stages. A localization jump can cause Nav2 to finish with the robot laterally or angularly misaligned with the Wallbox. The final controller corrects only the docking-frame x-distance and cannot compensate for this misalignment, which may result in a scanner stop or incomplete docking. If localization becomes unstable, relocalize the robot and restart the docking sequence.
Warning
Keep the Wallbox stationary between contour acceptance and docking. The
final target is deliberately frozen in odom after the second contour
matching stage. Moving the Wallbox after that point can make the robot stop
at the wrong physical position.
Warning
At least during initial testing, before deploying docking in an
application, do not rely solely on GICP convergence. Verify the accepted
docking_link pose in RViz, especially after changing scanner mounting,
contour offsets or geometric-validation settings.