Skip to content

Nav2 toolkit #5116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Conversation

pranavk-2003
Copy link

@pranavk-2003 pranavk-2003 commented Apr 30, 2025


Basic Info

Info Please fill out this column
Ticket(s) this addresses #5070
Primary OS tested on Ubuntu
Robotic platform tested on Turtlebot gazebo simulation.
Does this PR contain AI generated software? Somewhat

Description of testing performed

Functional tests were conducted on turtlebot3 and are working as expected

Description of contribution in a few bullet points

  • This Contribution adds a new package named nav2_toolkit which has QOL features, which can be handy while working with Nav2 .

Description of documentation updates required from your changes

  • Addition of 3 new parameterauto_start_saving, auto_restore_pose, save_interval_sec, so need to add that to nav2_params and documentation page

Description of how this change was tested

All the changes were tested multiple times in simulation over a course of 3 weeks.


Future work that may be required in bullet points

In total , this package will contain 3 tools i.e

  • pose_saver & pose_restore with added launch file in nav2_bringup.
  • Relocation of BaseFootprintPublisher.
  • A node which can pause and resume nav2 goals.

For Maintainers:

  • Check that any new parameters added are updated in docs.nav2.org
  • Check that any significant change is added to the migration guide
  • Check that any new features OR changes to existing behaviors are reflected in the tuning guide
  • Check that any new functions have Doxygen added
  • Check that any new features have test coverage
  • Check that any new plugins is added to the plugins page
  • If BT Node, Additionally: add to BT's XML index of nodes for groot, BT package's readme table, and BT library lists

Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

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

Good first stab!

Maybe lets wait until some more of this is fixed, but eventually we'll also need to add a configuration guide entry for this package in the docs.nav2.org and a migration guide entry to let folks know about the new features!

Anywhere that "AMCL" in mentioned in logs or naming, we should remove that and generally just talk about the pose publisher (which as an implementation detail is just AMCL for now). That way its not confusing when folks are using something that isn't AMCL, like SLAM Toolbox or another solution like VSLAM.

std::bind(&PoseSaverNode::reset_pose_file_cb, this, std::placeholders::_1, std::placeholders::_2));

if (auto_start) {
saving_active_ = true;
Copy link
Member

Choose a reason for hiding this comment

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

Is saving_active_ needed? If the timer is running shouldn't it always be true? Every time its toggled it should be stopped.

Copy link
Author

Choose a reason for hiding this comment

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

True,but i feel its better having a separate flag which keeps track of it.

Copy link
Member

Choose a reason for hiding this comment

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

It doesn't, please remove. Its another piece of state that could be mishandled and cause bugs

}
}

// Wait for AMCL to subscribe to /initialpose
Copy link
Member

Choose a reason for hiding this comment

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

I think if we abstract out the functionality of restore_service_cb into a new method, that method could just be called here and called in the service callback to share this capability.

Copy link
Author

Choose a reason for hiding this comment

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

Yes good suggestion! Made it.

Copy link
Member

Choose a reason for hiding this comment

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

I dont see it being used in the startup

Copy link
Contributor

mergify bot commented May 6, 2025

@pranavk-2003, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

@SteveMacenski
Copy link
Member

SteveMacenski commented May 7, 2025

@pranavk-2003 let me know when you want me to take a look again! I see you pushed some changes but a number of items are not yet addressed 😄

@pranavk-2003
Copy link
Author

pranavk-2003 commented May 11, 2025

@pranavk-2003 let me know when you want me to take a look again! I see you pushed some changes but a number of items are not yet addressed 😄

Its somewhat figured out,I'll let you know soon , got busy with university stuff ☹ .the few pushed stuff i still have to test.I am right now finding it difficult to get the nav2_package() macro right for nav2_toolkit.

@pranavk-2003
Copy link
Author

pranavk-2003 commented May 12, 2025

Hey @SteveMacenski ,I think i am done with the code updates , you can now have a look again throughout.The doxygen docs is in progress. : ) Also the checks are failing , let me know what has to be done for that too.

@SteveMacenski
Copy link
Member

@pranavk-2003 open the failing jobs and fix the issues they lay out :-) It looks like alot of static code quality issues in linting

Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

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

Needs test coverage as well!

@@ -0,0 +1,11 @@
#include "rclcpp/rclcpp.hpp"
Copy link
Member

Choose a reason for hiding this comment

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

Missing copyright header

</description>


<maintainer email="pranavkolekar13@gmail.com">Pranav</maintainer>
Copy link
Member

Choose a reason for hiding this comment

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

Add me too so I get emails on build issues

@@ -79,7 +79,6 @@ bt_navigator:
- nav_to_pose
Copy link
Member

Choose a reason for hiding this comment

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

Please resolve by adding back in

def generate_launch_description():
bringup_dir = get_package_share_directory('nav2_bringup')
default_params_file = os.path.join(bringup_dir, 'params', 'nav2_params.yaml')
default_pose_file = os.path.join(os.environ['HOME'], 'last_known_pose.yaml')
Copy link
Member

Choose a reason for hiding this comment

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

Remove, this should be considered in the node.

project(nav2_toolkit)

find_package(nav2_common REQUIRED)
nav2_package()
Copy link
Member

Choose a reason for hiding this comment

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

After all find_packages

@@ -0,0 +1,12 @@
# nav2_toolkit

A modular ROS 2 node for persisting and restoring the robot's last known pose using the `/amcl_pose` topic. This is useful in applications where the robot is never manually moved (e.g. warehouse robots), and it enables automatic re-localization.
Copy link
Member

Choose a reason for hiding this comment

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

@pranavk-2003 this wasnt completed

"/amcl_pose", 10,
std::bind(&PoseSaverNode::pose_callback, this, std::placeholders::_1));

initial_pose_pub_ = this->create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>("/initialpose", 10);
Copy link
Member

Choose a reason for hiding this comment

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

Rather than publishing the initial pose whereas you do not know if it was received, using a service means you know it was received properly due to getting a response. If none is given, then you can error handle


void PoseSaverNode::pose_callback(const geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr msg)
{
last_pose_ = std::make_shared<geometry_msgs::msg::PoseWithCovarianceStamped>(*msg);
Copy link
Member

Choose a reason for hiding this comment

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

No, just store the *msg object itself

}
}

// Wait for AMCL to subscribe to /initialpose
Copy link
Member

Choose a reason for hiding this comment

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

I dont see it being used in the startup

std::bind(&PoseSaverNode::reset_pose_file_cb, this, std::placeholders::_1, std::placeholders::_2));

if (auto_start) {
saving_active_ = true;
Copy link
Member

Choose a reason for hiding this comment

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

It doesn't, please remove. Its another piece of state that could be mishandled and cause bugs

if (!saving_active_ || !last_pose_) return;

try {
write_pose_to_file(pose_file_path_);
Copy link
Member

Choose a reason for hiding this comment

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

Why not write to file when AMCL publishes to the pose topic? We could always throttle that to store every N seconds in case it is a fast publishing topic like from VSLAM, but then we could remove this timer entirely.


void PoseSaverNode::pose_callback(const geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr msg)
{
last_pose_ = std::make_shared<geometry_msgs::msg::PoseWithCovarianceStamped>(*msg);
Copy link
Member

Choose a reason for hiding this comment

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

Ex check if we should write by the write frequency when we get a pose here and then write it in this callback if saving_active_

Copy link
Author

@pranavk-2003 pranavk-2003 May 18, 2025

Choose a reason for hiding this comment

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

So what i understood from this is, when everytime amcl publishes a pose, it should be written to the file , instead of every N th second.For fast publishing it shall write every Nth second.But the question i have is , how would we decide when to write using timer and when to write with amcl publish update? A condition?

Copy link
Member

@SteveMacenski SteveMacenski May 20, 2025

Choose a reason for hiding this comment

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

So what i understood from this is, when everytime amcl publishes a pose, it should be written to the file , instead of every N th second.

Each time this callback is triggered, check against the last write time (variable to store) and write if greater than the maximum write frequency. Else, do nothing. That way if this topic publishes very fast, like in VSLAM, we're not doing a ton of IO at 100hz and instead writing to files every 1hz or less to get the general pose of the robot.

rclcpp::Time time_now = now();
if (time_now - last_write_time_ >= write_duration_)
{
  last_write_time_ = time_now;
  // do writing operation
}

@pranavk-2003
Copy link
Author

Needs test coverage as well!

Hey okay, so what shall it be?test as in demos for using the tool?

@pranavk-2003
Copy link
Author

@pranavk-2003 open the failing jobs and fix the issues they lay out :-) It looks like alot of static code quality issues in linting

Okay i understood how to solve those errors, i would solve these after all the code adjustments are done , as the code adjustments would introduce more of them

@SteveMacenski
Copy link
Member

Hey okay, so what shall it be?test as in demos for using the tool?

You should create a unit test that runs the object and then publishes some data to the topic its listening to. Check after awhile that there's a file at the requested location and the data is correct.

Then run another tests with autostart on and test that it correctly reads from that file and publishes / calls the service to set the pose correctly (the test object should expose the service, so nothing else should be running).

Then another test should be with autostart / auto-store off and call the services to start / stop / reset and check that it does what it should do.

Finally, a series of unit tests that checks read_pose_from_file write_pose_to_file individual function's correctness individually

CI should then tell you the coverage metrics in the codecov job - we need it to be at least 90% to be merged

@SteveMacenski
Copy link
Member

Also as a matter of practice, do not resolve the PR topic discussions. I'll hit "resolve" when I verify that it was completed as intended. It makes my life easier as a maintainer to know that I validated each of my previous comments in your updated fixes without having to go back through all of the collapsed tabs each time :-)

Copy link
Contributor

mergify bot commented May 20, 2025

This pull request is in conflict. Could you fix it @pranavk-2003?

@pranavk-2003
Copy link
Author

Resolved the conflicts, @SteveMacenski i'll let you know when i want you to check this PR again.

@pranavk-2003 pranavk-2003 reopened this May 21, 2025
Copy link
Contributor

mergify bot commented May 21, 2025

@pranavk-2003, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

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.

2 participants