Open Navigation's Nav2 Docking Framework
GitHub Repo
MIT
July 5, 2026 at 02:22 PM
0 views

Open Navigation's Nav2 Docking Framework

@open-navigationProject Author

Open Navigation’s Nav2 Docking Framework: A Detailed Guide

Overview

Open Navigation’s Nav2 Docking Framework is a complete solution for automatic robot docking and undocking. Built as a plugin-based system, it generalizes to many robot types, kinematic models, charging methods, and sensor modalities. The framework can manage a database of multiple docking locations and dock models, allowing a heterogeneous environment to be navigated with confidence. The task server is designed to be invoked by an application (either a Bluetooth-based controller or autonomy stack) to initiate docking after task completion or when battery levels demand it. Importantly, docking is handled as a separate operation from the navigate-to-pose action; undocking, however, can be invoked from within navigate actions. The project was sponsored by NVIDIA and created by Open Navigation LLC. Beginning in 2024, the capability has been migrated into Nav2 itself, with Nova Carter-specific docking code moved to Nova Carter’s GitHub in August 2024. For users on Humble, refer to this repository’s humble branch.

Image: Nvidia x Open Navigation [Insert image: “NvidiaxOpenNavigation”]

  • Image path: ./docs/nv_on.png

A Four-Package Architecture

Nav2 Docking is distributed across four core packages, with a community extension that demonstrates real-world usage:

  • opennav_docking: The main docking framework, housing the orchestration, state machines, and core logic.
  • opennavdockingmsgs: Action interfaces for docking and undocking; messages that describe requests, feedback, and results.
  • opennavdockingcore: The dock plugin header template that must be implemented for each dock type; it defines the essential API.
  • opennavdockingbt: Behavior Tree nodes and example XML files that illustrate using the docking task server within a BT framework.
  • novacarterdocking: An implementation example that demonstrates docking with the Nvidia Nova Carter robotic platform and its dock. Note: this specific package has migrated into Nova Carter’s GitHub, and if you’re using Humble you should use the humble branch of this repository.

Visual Demos and Resources

  • Click to view extended video of docking in action: the demo GIF embedded in the docs. [Insert image: demo.gif] Image path: ./docs/demo.gif
  • Learn more through community talks and demonstrations:
  • ROSCon 2024 talk on Docking (image linked to the talk): [Insert image alternate text with link to Vimeo] Image path: https://github.com/user-attachments/assets/468bb49c-87de-4c9e-83a8-ad6f14bbd6d3
  • For a corporate overview of the integration with Nvidia technologies, see the Nvidia/Open Navigation collaboration image: [Insert image: “Nvidia x Open Navigation”] Image path: ./docs/nv_on.png

Architecture: The Five Core Components

The Docking Framework is composed of five interlocking components that work together to perform robust docking and undocking:

  • DockingServer: The central action server that orchestrates docking and undocking actions. It handles the lifecycle of a docking attempt, coordinating with plugins, the vision loop, and the posture checks required to declare success or failure.
  • Navigator: A NavigateToPose action client responsible for moving the robot to the dock’s staging pose when necessary. This component ensures that the robot is in the correct area to begin docking, respecting prestaging tolerances.
  • DockDatabase: A persistent catalogue of dock instances and their interfaces. The database can contain many dock types, making the framework adaptable to varied hardware and docking schemes. Any dock entry may be used in a docking request.
  • Controller: A spiral-based, graceful control loop that drives the vision-controlled docking process. This component provides the reactive control necessary to refine the robot’s approach to the docking pose while honoring sensory input.
  • ChargingDock: The plugin layer that describes a particular dock’s model and the transactions needed to detect, connect to, and verify charging. Each dock type is represented by a plugin that knows how to detect and interact with its hardware. The heart of customization lies in the ChargingDock plugins, which enable docking to diverse docks across different robots.

Docking Procedure: From Request to Charging

The docking sequence is defined as a series of well-structured steps. When a docking request arrives, the framework follows a deterministic path to attempt a robust docking: 1) Accept the action request and determine the dock’s plugin and its pose. 2) If the robot is not within the prestaging tolerance of the dock’s staging pose, navigate to the staging pose using the Navigator. 3) Use the dock’s plugin to detect the dock and obtain the docking pose to target. 4) Enter a vision-control loop where the robot incrementally refines its pose to reach the docking pose, guided by visual or sensor feedback. 5) Exit the vision-control loop when contact is detected or charging starts. 6) Wait for charging to begin and report success to the client. If any step fails, the system may retry up to N times by returning to the staging pose and attempting again. If all retries fail, a failure code is returned indicating the type of failure observed.

Undocking is simpler: 1) If the robot is already docked, leverage the known dock information to identify the dock type, or use the undock action’s specified dock type when necessary. 2) Find the staging pose for that dock and back away to that pose. 3) Confirm a successful backout to the staging pose and ensure charging has stopped.

Interfaces: Docking and Undocking Actions Docking Action

  • Use either a dock in the DockDatabase or a dock specified directly in the docking request. The latter is useful for testing or when dock locales are not pre-known.
  • If usedockid is true, the dockid field specifies the dock in the database. Otherwise, populate dockpose and dock_type.
  • If navigatetostaging_pose is true, the server will stage the robot at the dock’s staging pose for you. If not, staging is skipped if the robot is already within prestaging tolerances.
  • maxstagingtime sets the navigation timeout.
  • The response includes numretries, success, and errorcode to convey retry counts, successful docking, and any failure semantics.
  • Feedback during operation exposes the current state, the elapsed docking_time, and the current retry count.
  • See the DockRobot.action for additional detail.

Undocking Action

  • The undocking request includes dock_type (optional if the robot previously docked at a known dock), to resolve multiple possible dock plugins. If unspecified and multiple plugins exist, a default is chosen.
  • A maximum undocking time defines the timeout for the undocking attempt.
  • The result reports success and an error_code with no intermediate feedback.

Reload Database Service

  • A dedicated service to reload the dock database with a new file after loading. Provide the filepath to the new set of docks, and the server updates accordingly.

Dock Specification: Instances vs. Plugins Two distinct elements define the docking capability: dock instances and dock plugins.

  • Dock plugins: The model of a dock type, including how to detect and interface with it. Plugins provide the capabilities to detect, connect, and transact with a given dock. The plugin API is designed so that multiple dock revisions (even with different attributes) can be supported in parallel.
  • Dock instances: Specific occurrences of a dock in your environment. A map may contain many instances of the same dock type, and you can select the exact dock by name for a docking operation. The separation between dock plugin type and dock instances enables scalable management of multiple docks across different revisions and environments.

Configuring Plugins and Docks

Plugins and docks are declared in the parameter file, enabling a plug-and-play approach with minimal code changes when introducing new docks. The dock_plugins section lists the available plugin types, and each dock type name references a corresponding plugin class.

Example: Declaring dock plugins

  • dock_plugins: ["dockv1", "dockv3"]
  • dockv1: plugin: "mycustomdock_ns::Dockv1"
  • dockv3: plugin: "mycustomdock_ns::Dockv3"
  • timeout: 10.0

Example: Declaring docks in the config (inline)

  • docks: ['dock1', 'dock2']
  • dock1: type: "dockv3", frame: map, pose: [0.3, 0.3, 0.0], id: "kitchen_dock"
  • dock2: type: "dockv1", frame: map, pose: [0.0, 0.0, 0.4], id: "42"

Alternatively, you can specify docks in an external YAML file via the dock_database parameter:

  • docks:
  • dock1: type: "dockv3", frame: map, pose: [0.3, 0.3, 0.0], id: "kitchen_dock"
  • dock2: type: "dockv1", frame: map, pose: [0.0, 0.0, 0.4], id: "42" Notes:
  • You may leave the type empty if there is only a single dock type in use.
  • Pose frames may be map, odom, base_link, etc., not restricted to map.
  • The id field is optional and only used if the dock plugin supports an identifying tag (e.g., an AprilTag).

Dock Plugin API: The Core Functions

Plugins implement a set of essential functions to manage poses, detection, and charging feedback. The most important methods include:

  • getStagingPose: Convert the dock’s pose into a staging pose suitable for initiating the docking maneuver. Nav2 can stage the robot to this pose if it is outside prestaging tolerances.
  • getRefinedPose: Refine the pose using sensors. Depending on the robot’s capabilities, this might rely on laser scans or camera data to produce a more accurate docking pose.
  • isDocked: Determine when to stop advancing toward the dock. Dock detection can be achieved via various cues (dock communication before charging starts, contact detection via motor currents or velocity drop, or a simple proximity check).
  • isCharging: The robot is considered charging when the dock reports docking contact and charging has begun. This can be inferred from a BatteryState message or a docking event.
  • disableCharging: Called before undocking to minimize wear on the contact interfaces; if the dock supports turning off charging, do it here.
  • hasStoppedCharging: Called during undocking to determine when charging has ceased and the robot has returned to the staging pose.
  • Quick return: All docking and undocking functions should execute promptly, as they run within the control loop. Importantly, isDocked should return true when isCharging returns true, ensuring a coherent state transition.

Simple Charging Dock Plugin: A Practical Example

The SimpleChargingDock plugin serves as a practical, feature-rich example that covers a wide range of real-world use cases. Its design includes:

  • getStagingPose: Applies a parameterized translational and rotational offset to the dock pose to determine the staging pose.
  • getRefinedPose: Flexible in two modes: 1) Blind approach: return the dock pose from the DockDatabase. This is useful for testing and simulation, albeit with potentially lower accuracy. 2) Sensor-assisted approach: Subscribe to a geometrymsgs/PoseStamped topic named detecteddock_pose to receive poses from an external detector (e.g., AR markers, AprilTag-based detections). This enables docking with additional offset adjustments to align with the robot's docking interface.
  • Two detection options for isDocked: 1) Use joint state feedback (wheel currents or torque) to detect contact with the dock or a significant current surge. 2) Compare the robot’s pose with the docking pose, returning true once the distance is within a defined docking_threshold.
  • Charging feedback options:
  • Subscribe to a sensormsgs/BatteryState topic (batterystate). The robot is considered charging when the current exceeds charging_threshold.
  • Alternatively, declare isDocked() = true to signal charging in early stages or when battery data is unreliable.
  • Visualization aids for debugging (RVIZ):
  • dockpose: The current transformed dock pose (geometrymsgs/PoseStamped)
  • filtereddockpose: The current un-transformed dock pose (geometry_msgs/PoseStamped)
  • stagingpose: The staging pose for the dock (geometrymsgs/PoseStamped)

Key Configuration Parameters (A Snapshot)

The configuration for the docking framework includes a rich set of tunables for both the docking server and the SimpleChargingDock plugin. Here is a condensed view of typical parameters and their purposes:

General controller and navigation

  • controller_frequency: Control loop frequency for the vision-control loop (Hz). Default: 50.0
  • initialperceptiontimeout: Time to wait for initial perception of the dock (s). Default: 5.0
  • waitchargetimeout: Time to wait for charging to start after docking (s). Default: 5.0
  • dockapproachtimeout: Timeout for the vision-control approach loop (s). Default: 30.0

Undocking and staging tolerances

  • undocklineartolerance: Linear tolerance to exit undocking loop at staging pose (m). Default: 0.05
  • undockangulartolerance: Angular tolerance to exit undocking loop at staging pose (rad). Default: 0.05
  • dockprestagingtolerance: L2 distance from the staging pose to skip navigation (m). Default: 0.5

Retries and frames

  • max_retries: Maximum docking/undocking retries (int). Default: 3
  • baseframe: Robot’s base frame for the control law. Default: "baselink"
  • fixed_frame: Fixed frame used for transforms, recommended not being the map frame. Default: "odom"

Docking behavior toggles

  • dock_backwards: Whether docking occurs with the dock behind the robot (bool). Default: false
  • dockcollisionthreshold: Allowed distance from the dock pose to ignore collisions (m). Default: 0.3

Plugin and database requirements

  • dock_plugins: A set of dock plugins to load (vector)
  • dock_database: Path to the external YAML file defining the dock instances (string)
  • docks: Inline dock definitions (vector)
  • navigatorbtxml: BT XML for the Navigator, if non-default (string)
  • controller.kphi, controller.kdelta, controller.beta, controller.lambda: Controller gains and parameters (doubles)
  • controller.vlinearmin, controller.vlinearmax, controller.vangularmax: Vehicle speed limits (doubles)
  • controller.slowdown_radius: Radius within which the robot slows down (double)
  • controller.usecollisiondetection: Enable collision detection with the costmap (bool)
  • controller.costmap_topic: Costmap topic (string)
  • controller.footprint_topic: Robot footprint topic (string)
  • controller.transform_tolerance: Transform post-dating tolerance (double)
  • controller.projection_time: Lookahead time for collisions (s)
  • controller.simulationtimestep: Time step for projections (s)
  • controller.dockcollisionthreshold: Collision threshold near the dock pose (m)

SimpleChargingDock specific

  • usebatterystatus: Use battery state messages for isCharging (bool)
  • useexternaldetection_pose: Use an external detection pose instead of the database pose (bool)
  • externaldetectiontimeout: Timeout after which external detection is considered stale (s)
  • externaldetectiontranslation_x/y: Offsets from detected pose to docking pose (meters)
  • externaldetectionrotation_yaw/pitch/roll: Orientation offsets (radians)
  • filter_coef: Filtering coefficient for external detection (double)
  • charging_threshold: Battery current threshold above which isCharging is true (double)
  • usestalldetection: Enable stall-based detection for isDocked (bool)
  • stalljointnames: Joint names to track for stall detection (vector)
  • stallvelocitythreshold: Velocity threshold to trigger isDocked (double)
  • stalleffortthreshold: Current/motor effort threshold to trigger isDocked (double)
  • docking_threshold: Pose distance threshold to declare isDocked (double)
  • stagingxoffset, stagingyawoffset: Offsets for staging pose relative to dock pose (double)

Etc: On Staging Poses

Staging poses are the critical interface between navigation and docking. The staging pose is a pose near the dock that is close enough for reliable detection yet far enough to allow corrective motion if localization is imperfect. The robot’s charging contacts should be oriented toward the dock in this staging pose to enable efficient global planning and docking maneuvers within the robot’s non-holonomic constraints. The staging pose represents a balance between robust perception and reliable reach to the docking pose.

Two Ways to Populate the Dock Database

  • Inline in the config: The docks and their associated types can be embedded directly in the Docking Server’s configuration file, using a format that mirrors the plugin definitions. This is convenient for small deployments with a few docks.
  • External YAML file: The more scalable approach uses the dock_database parameter to point to an external YAML file. This file contains a structured layout of docks and their properties, enabling easier maintenance as the environment grows.

Docking and Undocking: A Quick Recap

  • Docking:
  • Determine the dock’s plugin and pose
  • Navigate to staging pose if needed
  • Detect the dock and obtain the docking pose
  • Engage the vision-driven approach to refine alignment
  • Detect contact or start charging
  • Wait for charging and declare success, with retries if necessary
  • Undocking:
  • Use known dock or request dock type
  • Back out to staging pose
  • Confirm clearance and charging has stopped
  • Return success or error_code

Key Notes for Practitioners

  • The Docking Framework is designed to be resilient and modular. The plugin architecture allows teams to add new dock models without altering the core server logic.
  • The separation between dock instances and dock plugins enables handling multiple docks with different revisions, as well as future upgrades to dock hardware.
  • The system supports both sensor-driven and marker-based pose estimation strategies, making it adaptable to various sensors, cameras, and markers in the field.
  • The migration to Nav2 in mid-2024 means users can rely on a more integrated experience. If you’re using Humble, align with the humble branch of this repository.

Code Snippets: What You Might See in Configs Dock plugins example

dock_plugins: ["dockv1", "dockv3"]
dockv1:
  plugin: "my_custom_dock_ns::Dockv1"
dockv3:
  plugin: "my_custom_dock_ns::Dockv3"
timeout: 10.0

Inline dock definitions

docks: ['dock1', 'dock2']
dock1:
  type: "dockv3"
  frame: map
  pose: [0.3, 0.3, 0.0]
  id: "kitchen_dock"
dock2:
  type: "dockv1"
  frame: map
  pose: [0.0, 0.0, 0.4]
  id: "42"

External dock database example

docks:
  dock1:
    type: "dockv3"
    frame: map
    pose: [0.3, 0.3, 0.0]
    id: "kitchen_dock"
  dock2:
    type: "dockv1"
    frame: map
    pose: [0.0, 0.0, 0.4]
    id: "42"

Getting Started: Practical Steps

  • Identify your dock types and their sensing capabilities. Decide whether you’ll rely on external detectors (e.g., visual markers) or dock-provided signals for docking confirmation.
  • Implement or adapt a dock plugin for your hardware. The core API is designed to accommodate both simple and advanced sensing approaches.
  • Build and populate your DockDatabase with the docks present in your workspace. Decide whether to store this in the config or an external file.
  • Tune the SimpleChargingDock parameters to match your robot’s mechanical and electrical properties. Start with conservative values for the detection thresholds and gradually increase as you gain confidence.
  • Test in simulation first, then in a controlled environment before deploying in production. Utilize the RVIZ publishers to visualize poses and stages of the docking process.

Conclusion: A Flexible, Navy-Grade Docking Framework

Nav2’s Open Navigation Docking Framework offers a robust, flexible path to automated docking across diverse robots and environments. By combining a centralized DockingServer with modular DockDatabase entries and a pluggable Dock plugin API, teams can rapidly adapt to new docks and evolving hardware. The architecture emphasizes safety, reliability, and clarity, with explicit retry logic and clear success/failure semantics communicated back to the controlling application.

Visuals and learning resources accompany the framework to help operators and developers understand the docking workflow, the role of staging poses, and the interplay between sensing, vision control, and charging state. With the migration to Nav2 and the real-world demonstrations across platforms like Nvidia’s Nova Carter, the Docking Framework stands as a practical, scalable mechanism for autonomous charging and vehicle readiness in complex environments.

Images from the Input in Context

  • Nvidia x Open Navigation [NVIDIA x Open Navigation image] Path: ./docs/nv_on.png
  • Demo video GIF showing docking action Path: ./docs/demo.gif
  • ROSCon 2024 talk teaser image linked to the talk Path: https://github.com/user-attachments/assets/468bb49c-87de-4c9e-83a8-ad6f14bbd6d3

If you’d like deeper dives, the ROSCon 2024 docking talk is a great starting place to see the guidelines and demonstrations that underpin the architecture described here. For ongoing development and troubleshooting, reach out to Open Navigation’s support channels and consult the Humble branch if you’re operating on that release line. This documentation aims to provide a practical, holistic view of the docking framework, its components, and its integration into real-world robotic systems.

Enjoying this project?

Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.

Project
nav2-docking-framework
Created
July 5
Last Updated
July 5, 2026 at 02:22 PM

Find more projects like this

One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.