Skip to content

Add support for docking through nav2#215

Open
aionescu-cpr wants to merge 2 commits intoopen-rmf:mainfrom
aionescu-cpr:andrei/add_nav2_docking
Open

Add support for docking through nav2#215
aionescu-cpr wants to merge 2 commits intoopen-rmf:mainfrom
aionescu-cpr:andrei/add_nav2_docking

Conversation

@aionescu-cpr
Copy link
Copy Markdown

New feature implementation

Implemented feature

This change adds docking support using Nav2 as requested here: #187

Implementation description

The main logic change is done in the Nav2RobotAdapter's navigate function, where rather than only sending a robot to a destination, a check was added to determine whether a dock was specified in the destination. If a dock was specified then the robot is sent a DockRobot action goal, otherwise the robot is given the default action of NavigateToPose.

As part of the change, the ros2_types.py was modified to add translation for the related DockRobot_* action classes. The default zenoh config was also modified to allow the .*/dock_robot action topics. A nav2send_dock_robot.py example was also added to allow the zenoh bridge to be tested.

The large change I introduced is a refactoring of the Nav2RobotAdapter as the "navigate_to_pose" and "dock_robot" actions share a lot of the same logic. Rather than duplicate a lot of the existing code and make the adapter larger, I added a NavigationExecutionItem which encapsulates the request being executed, with two classes inheriting from this for each action: NavigateToPoseExecutionItem and DockExecutionItem. This class is responsible for executing the goal, providing updates and stopping it. The handling of these functions were previously all in the Nav2RobotAdapter class, which was simplified to now focus on mainly the control logic.

This is a large change and it may not be in the direction that the maintainers of the repo want the design to go into, so I understand if a simpler approach is requested.

GenAI Use

We follow OSRA's policy on GenAI tools

  • I used a GenAI tool in this PR.
  • I did not use GenAI

Generated-by:

@mxgrey mxgrey added this to PMC Board Aug 18, 2025
@github-project-automation github-project-automation Bot moved this to Inbox in PMC Board Aug 18, 2025
@aionescu-cpr aionescu-cpr marked this pull request as draft August 18, 2025 22:06
@aaronchongth aaronchongth marked this pull request as ready for review August 19, 2025 01:50
@aaronchongth aaronchongth marked this pull request as draft August 19, 2025 01:50
@aaronchongth
Copy link
Copy Markdown
Member

Ignore the change from draft to ready-to-review, I misclicked, I've reverted it.

Comment thread free_fleet_adapter/free_fleet_adapter/nav2_execution_item.py Outdated
Comment thread free_fleet_adapter/free_fleet_adapter/nav2_execution_item.py Outdated
Comment thread free_fleet_adapter/free_fleet_adapter/nav2_execution_item.py Outdated
Copy link
Copy Markdown
Member

@aaronchongth aaronchongth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together @aionescu-cpr! Overall the changes to the abstractions make sense, I like that this opens the door to more configurable behaviors, allowing the use of other BTs than NavigateToPose.

We can probably give more thought to the naming, to prevent confusion with the existing ExecutionHandle. I've added some comments, but overall it looks good.

@aionescu-cpr
Copy link
Copy Markdown
Author

aionescu-cpr commented Aug 25, 2025

Thanks for putting this together @aionescu-cpr! Overall the changes to the abstractions make sense, I like that this opens the door to more configurable behaviors, allowing the use of other BTs than NavigateToPose.

We can probably give more thought to the naming, to prevent confusion with the existing ExecutionHandle. I've added some comments, but overall it looks good.

Thank you for the review and the naming suggestions @aaronchongth. I struggled to find a name that's not confusing, but I'm glad at least it got the point across as my intention was also to be able to extend this to other behaviours as well. I'll use your naming suggestions, update the PR and will now look at the unit tests too and update as needed.

@mxgrey mxgrey moved this from Inbox to In Review in PMC Board Aug 26, 2025
@aaronchongth aaronchongth moved this from In Review to In Progress in PMC Board Dec 16, 2025
Signed-off-by: Andrei Ionescu <aionescu@clearpath.ai>
@aionescu-cpr aionescu-cpr force-pushed the andrei/add_nav2_docking branch 2 times, most recently from 60f51d4 to 85ff6bb Compare February 16, 2026 15:46
@aaronchongth aaronchongth moved this from In Progress to Spotlight in PMC Board Mar 16, 2026
@aionescu-cpr aionescu-cpr force-pushed the andrei/add_nav2_docking branch from 85ff6bb to f28d085 Compare March 31, 2026 16:07
@aionescu-cpr aionescu-cpr marked this pull request as ready for review March 31, 2026 16:08
@aionescu-cpr
Copy link
Copy Markdown
Author

@aaronchongth As this PR was open for quite a while I had to rebase it to pull in the latest changes. Since I refactored the code those changes would be in new files, so please take a look to make sure that all the changes are indeed included when reviewing. I went through each commit, but a second set of eyes would be appreciated.

Copy link
Copy Markdown
Member

@aaronchongth aaronchongth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick high level review based on the test failures, I'll do a more indepth review soon

rclpy.init()
cls.node = rclpy.create_node('test_nav2_robot_adapter')
cls.zenoh_session = zenoh.open(zenoh.Config())
# Configure zenoh to connect to localhost router
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will not working within a github workflow. Is there a reason the endpoint needs to be manually defined?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this. I used this only for my local testing but it snuck in with the rest of the commit. I have reverted it.

Signed-off-by: Andrei Ionescu <aionescu@clearpath.ai>
@aionescu-cpr aionescu-cpr force-pushed the andrei/add_nav2_docking branch from f28d085 to ab55a9b Compare April 6, 2026 11:59
@aaronchongth aaronchongth removed this from PMC Board Apr 7, 2026
Copy link
Copy Markdown
Member

@aaronchongth aaronchongth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the huge refactor! I really appreciate the additional testing, mocks and reduction of repeated code throughout.

I left some minor review comments to fix, including linting, but after the linting is fixed, I believe the unit and integration tests should pass too, I've managed to run our usual simulation examples with your refactor.

The implementation of the docking action seem solid, however we currently don't have the setup to test it. Did you test it with any particular setup or sim? If so, could you update this PR's description with it?

I'll update the issue ticket with the scope that will be completed with this ticket, before we look further into RMF's support of the navgation2 docking interface

# See the License for the specific language governing permissions and
# limitations under the License.

import time
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lint: unused import

cls.node = rclpy.create_node('test_ros2_action_interface')
cls.zenoh_session = zenoh.open(zenoh.Config())


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lint: too many blank lines

@@ -0,0 +1,166 @@
#!/usr/bin/env python3

# Copyright 2024 Open Source Robotics Foundation, Inc.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Copyright 2024 Open Source Robotics Foundation, Inc.
# Copyright 2026 Open Source Robotics Foundation, Inc.

@@ -0,0 +1,127 @@
#!/usr/bin/env python3

# Copyright 2024 Open Source Robotics Foundation, Inc.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Copyright 2024 Open Source Robotics Foundation, Inc.
# Copyright 2026 Open Source Robotics Foundation, Inc.

@@ -0,0 +1,381 @@
#!/usr/bin/env python3

# Copyright 2024 Open Source Robotics Foundation, Inc.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Copyright 2024 Open Source Robotics Foundation, Inc.
# Copyright 2026 Open Source Robotics Foundation, Inc.

STATUS_CANCELING: pycdr2.types.int8 = 3
STATUS_SUCCEEDED: pycdr2.types.int8 = 4
STATUS_CANCELED: pycdr2.types.int8 = 5
STATUS_ABORTED: pycdr2.types.int8 = 6
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason for this change? It looks like it was only moved. Was this due to linting errors?
I'd prefer to keep diffs small to make reviewing easier

parser.add_argument('--namespace', '-n', type=str, default='')
parser.add_argument('--frame-id', '-f', type=str, default='map')
parser.add_argument('--dock', type=str, default='')
parser.add_argument('--stage', type=bool, default=True)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iiuc, bool in ArgumentParser has weird behaviors due to strings being evaluated as True in general. Should we use something similar to https://github.com/open-rmf/rmf_demos/blob/main/rmf_demos_tasks/rmf_demos_tasks/dispatch_patrol.py#L86-L90, but store_false instead? The parameter name will probably have to be no-staging or something

...

@abstractmethod
def get_action_string(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def get_action_string(self):
def get_action_name(self):

nit: this is a little bit more semantically correct, the child classes and function calls will need to be updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants