GSoC 2023: GPS-Denied Autonomous Exploration with ROS 2

Sure thing! Here’s the list of my current setup:

  • Ubuntu 22.04.2 LTS (Jammy Jellyfish)
  • ROS 2 (Humble Hawksbill) and the associated RVIZ version
  • Gazebo Garden
1 Like

Very Interesting project i am following as well, just started working with autopilot and also trying to set up a working DDS communication with ROS humble in order to pass odometry msgs , if i will have anything to contribute where should i do this ?

BTW did you choose to use Gazebo Garden and Not Fortress ?

A few reasons:

  • Major namespace change between Fortress and Garden which is costly to maintain.
  • Garden has native rendering support for macOS.
  • Better handling of joints in nested models.

The drone community (PX4 and ArduPilot) have settled on the combination of ROS 2 Humble and Gazebo Garden current development.


A good starting point is to set up a developer workspace, @rhys is working on it ardupilot_gz. Feel free to join our weekly meeting as well, more details above.

1 Like

I understand , make sense overall thank you.

Weekly updates June 20th

Coding begins! Now that I’m back from the U.S. (since June 13th) the project should start getting in shape. Progress should be slow until my university break starts (which is when I plan on living and breathing Ardupilot)

I just created a PR in ardupilot_gz to add, which spawns a copter equipped with a laser scan in a maze-like world and connects them to ROS 2.

Adding a lidar to a robot in gazebo classic is very well documented, with numerous examples. In Ignition Gazebo there’s basically nothing… This means that even this early implementation might help someone, so I’m happy.

To run this simulation I’ve had to ditch my crappy laptop and create a dev workspace in my desktop computer. I lost some of time with problems installing ubuntu 22.04 in my ssd and with my nvidia graphics card (classic stuff for linux users), but it was very worth it, my real_time_factor in gazebo tripled.


Weekly updates June 26th and July 4th

I’ve worked on running Cartographer with the simulation environment and it is currently working pretty well! I still have some tweaks to do regarding launch file options and the tf tree, but it is pretty functional for now. Looking into some of their examples and mimicking their rviz setup is also probably worth it.
I’m also going to add foxglove alternatives for visualization

The simulation PR got merged!

Thanks a lot to @rhys for the huge help to get everything perfect.

I’m currently working towards adding pre-commit to ardupilot_gz

@rfriedman is currently working on the external odometry source prerequisite, I will try to help him out as much as I can. @tridge gave me a masterclass on EKF some weeks ago and I’ve used my notes to provide some info.

The GSoC Midterm Evaluation deadline is on July 14th, I will work towards having a PR to Ardupilot_wiki explaining how to setup the simulation and run cartogrpher on it so it is easily accessible for the whole community.

@Ivan_Rulik is currently working on some Ardupilot/ROS 2 documentation so I will take a look at his work and build from there.


July Update

Some small PRs got merged. Thanks to @rfriedman for presenting me to pre-commit and helping me merge this PR to ardupilot_gz

Also updated the README in ardupilot_gz as the Micro XRCE DDS Gen dependency wasn’t listed

This month the first ardupilot_wiki PR regarding ROS 2 was merged, @hwurzburg and @rmackay9 helped me out with it. If you are interested, you can look into the PR or the dev documentation

I’ve had quite some problems to get navigation2 to work properly with the current setup, mostly because of tf tree problems.

In it’s current state, ardupilot_gz is populating the /tf topic using the ros_gz bridge, specifically the gz-sim-pose-publisher-system plugin. What it does is basically create a parent frame with the model name and a bunch of child frames with the model’s links and publish their position relative to each other. This works fine in the iris_runway example, and we can use the /tf information to show successfully the robot position in rviz2.

This is a problem because the tree generated from this plugin serves to simply publish the position of the links of specific models in gazebo, in other words, it doesn’t take into consideration the joint hierarchy. Using cartographer as an odometry source the generated tf tree looks something like this:

This is a problem because ROS REP 105 standardizes the tf relationship between frames earth , map , odom and base_link, which causes big open source ROS projects, like navigation2, to assume this kind of tree architecture. It should be as follows:

Looking into the navigation2 documentation to setup an adequate tf tree, we can see that they don’t use ros_gz and instead choose to go for robot_state_publisher. This results in the following tree:

Which looks amazingly better. Using cartographer as a map->odom->base_link source results in this tf tree:

This tree follows ROS REP 105 standards, which expectedly results in better perfomance with cartographer and navigation2.

Because of all that, I will create a PR to stop ignoring robot_state_publisher’s tf tree and adequate the frame_id’s being published by the sensors in gazebo. @rhys I’d love to hear your thoughts on this.


August Update

This has been the most eventful month of the project, full of PRs and updates.

As mentioned in the post above, I submitted a PR to stop ignoring robot_state_publisher and made it “oficial”, remapping it from /ignore/tf to /ap/tf, this will be very important soon.

Google Cartographer had been working with the simulation for some time, but with the /tf changes merged, I could finally submit a PR for adding the Cartographer integration in Ardupilot, which worked beautifully.

In the meanwhile, @rfriedman offered to start working in the library for Ardupilot to accept an External Odometry Source. This was possible before, with AP_VisualOdom, but the “entry point” to this library was on GCS_Mavlink. In other words, it worked for mavlink and ROS 1 (using mavros), but a reform was needed to get it appropriately working in ROS 2, this was masterfully done in the two PRs linked below. Thanks again Ryan!

This was also an amazing opportunity for me to learn how to code review and serve as a code tester for Open Source. I got some suggestions out in the Pull Requests and also debugged code in calls with Ryan. Up until this point I had only been on the submission end of a PR, so having the opportunity to change roles was amazing for my development as a software developer. I also did a PR to fix a bug we found in his branch:

With Cartographer integrated and Ardupilot accepting External Odometry, I could finally work on more advanced documentation, to start, I’ve updated the documentation to teach the end-user how to send the External Odometry into Ardupilot’s Extended Kalman Filter

In ardupilot_wiki a page for ROS 2 with SITL in Gazebo and another for Cartographer SLAM with ROS 2 in SITL were created, with video demos for both.

I added pre-commit to ardupilot_ros, which was very similar to the PR I had done earlier for ardupilot_gz:

Now for the final step of the project: successfully integrating nav2 to work with Ardupilot. This has been a joint effort the last few weeks.
First, we need a way to control the vehicle’s velocity from ROS 2. @tridge kickstarted a PR for AP_ExternalControl, an Ardupilot library to serve as an “entry point” to external control messages, be it from mavlink, scripting or DDS (ROS 2). Initially both me and @rfriedman served as code reviewers, and I was responsible for testing the code with gazebo using ardupilot_gz, we suggested some changes, and Ryan decided to commit a lot of changes to the PR to get it ready for merge ASAP.

Here’s a little gif of me testing the frame orientations.

After that PR was merged, a little alteration was needed. Aerial vehicles with ROS use body frame conventions for velocity, instead of earth-based frames, according to ROS rep 147. On top of that, nav2 uses Twist message instead of TwistStamped. From this incompatibilities, two PRs were created:

Here’s also the link for the discussion surrounding this in navigation2:

I am now working towards succesfully integrating nav2 with Ardupilot. The path planning and speed control parts are working perfectly, but the obstacle avoidance side of things is still not working. This is the last gap in the project.


Great Work @pedro-fuoco !

1 Like

Done! It works! Finally hahaha
Here is a demo of the copter performing SLAM and Obstacle Avoidance at the same time:

The problem was caused by this issue:

Now the focus is to make it work in the main branches for all the repositories involved, so a bunch of PRs are being created in these last few days. A final update on this post will be made soon.


For anyone following, pretty much everything we need is merged aside from the NAV2 integration. The only issue left (in progress by me) is to add support for TwistStamped in NAV2. I made some progress the last week on the code; just waiting on some feedback from the NAV2 maintainers for the TwistSubscriber class.

Then, it will get backported to humble.

Once that’s in, then the final project tickets (wiki and demo) code can get merged:

1 Like

Hello @pedro-fuoco and @rfriedman I’ve read your project research and it is great! I usually use ROS for my research work and I’m approaching to ROS. I work with ground rovers, do you think your project can also be adapted to work on UGV? I’m looking for a navigation system with NO GPS support, but with a high accuracy.

Yep! We’ve already made basic examples for rover here. Feel free to try it out and provide feedback.

You can do velocity control with rover on master.

Pretty much all the code in ArduPilot for the ROS 2 interface is platform-agnostic anyways. The platform-specific adaptations are very thin.

If you don’t ever have GPS, there are mods you’ll need to do through parameters to disable GPS during pre-arm.

1 Like

Thank you a lot! I can’t use GPS indoor since the signal would be too noisy, so I need to assume I have no GPS sensor.

Sometimes, it can happen that the vehicle will move from outdoor to indoor so in this case I think the navigation wouldn’t be affected too much.

The problem is when the vehicle will start moving directly from an indoor environment since it does not have amy valid GPS position.

Yep, that’s totally fine. You have to provide some sort of yaw alignment. We just made the project easier by adding a GPS to pass pre-arm.

@pedro-fuoco , do you manage to pass all the Ardupilot DDS tests?
colcon test --packages-select ardupilot_dds_tests
colcon test-result --all --verbose

Does this work well outdoors in open terrain? Does it lose accuracy over a long flight and if so, how much? What are its limitations in terms of types of terrain, altitude, etc.? Thank you.

The 2D lidar used in SITL is not suitable for outdoor use and it is small range. It will not work in a flat field with no obstacles. There is not much point to use this technology if you are outdoor - just use GPS.

Outdoor requires a different set of technologies and hardware. To my knowledge, there is not much available in ROS 2 for outdoor GPS denied navigation. Some manufacturers sell integrated solutions with their platforms; I would purchase one of those.

The infrastructure (DDS) build here creates a nice platform to develop against in ROS 2, so if you are have ability to perform work in this open-source for outdoor navigation, please share your findings and code.


Hello @pedro-fuoco, your contributions to the community are truly impressive. I am currently working on a project involving Ardupilot and ROS2 for warehouse applications. The navigation requirements include operating in a 3D environment, as the drone’s goal is to conduct stock counting. Given my relative newness to this field, I would greatly appreciate any recommendations you might have. Thank you!