Upgrading ROS 2, micro-ROS versions

Upgrading ROS 2, micro-ROS versions

Migrating from ROS 2 Galactic to Humble- Part 1

Recently, I migrated the software stack of my robot from ROS 2 Galactic to ROS 2 Humble. I thought it was going to be straightforward - add my Galactic nodes to a new Humble workspace, compile and it will work right away. But I faced a few issues getting my nodes to compile, and in this article, I will detail these issues and how I fixed them.


I did not opt for the standard ROS 2 Humble installation on Ubuntu 22.04. Instead (after being inspired by this ROSCon talk), I decided to use this Raspberry Pi image with Humble installed on a real-time Ubuntu kernel. I followed the steps in the GitHub repository (the image does not include the desktop environment, which I also had to install separately), and used this amazing blog post by RoboFoundry, which helped with initial issues like compile time on the Raspberry Pi.

First I used the following command (from RoboFoundry's blog) to minimize the CPU processing by building each package sequentially. I promptly created an alias for this for future use.

MAKEFLAGS="-j1 -l1" colcon build --symlink-install --executor sequential

Fixing warnings and errors

Next, I used the command to build my workspace which I hadn't changed since Galactic. Most were built successfully, but with loads of warnings. Some failed completely. I started with the warnings and went through them one by one. The first warning can be seen below:

SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.

This turned out to be a known issue, especially with the latest version of setuptools, and the fix involved downgrading setuptools to version 58.2.0, the last version to work with ROS 2 without any warnings. The solution is detailed in this ROS Answers post.

Update: There's an alternative solution to this, where downgrading setuptools is not needed. This warning can instead be suppressed by updating the PYTHONWARNINGSenvironment variable, which can be done by adding the following line to ~/.bashrc:

PYTHONWARNINGS="ignore:setup.py install is deprecated::setuptools.command.install"; export PYTHONWARNINGS

Moving on to the next warning:

WARNING:colcon.colcon_ros.task.ament_python.build:Package 'foobar' doesn't explicitly install a marker in the package index (colcon-ros currently does it implicitly but that fallback will be removed in the future)

Once again, thanks to ROS Answers, I manually created a marker file for the packages where it was missing, and the warning was resolved. The detailed answer can be found here.

Next, having resolved the warnings, I moved on to the build errors. It took me a while, but I eventually found this GitHub issue, which led me to the documentation of ament_cmake_python. One of my Galactic packages (ds4_driver, for use with the PS4 controller) was failing to compile because it was calling rosidl_generate_interfaces and ament_python_install_package in the same CMake project, which apparently does not work with ROS 2 Humble.

The only solution here was to separate the message generation from the node functionality into a separate package. I fixed the issue over the weekend and created a pull request on the ds4_driver project, which has since been reviewed and merged.

With this, everything was building and I was able to run the launch files. So, it was time to test the functionality.


I haven't set up any unit testing for my nodes yet, but ever since I realized that ChatGPT can write unit tests for any given ROS code, I've been meaning to set up testing in my workspace. But for now, it was time to manually test all the functionality. This includes the following components, which can be turned on or off from launch file arguments.

LD06 and Visualization

First, I had just learned about Foxglove's own WebSocket protocol as a more robust alternative to rosbridge_server, so I decided to make the necessary changes to use it. Then, for my first test, I launched the LD06 Lidar, along with ROSBoard and Foxglove visualization using Foxglove's WebSocket. Everything worked smoothly, and I was able to visualize results on Foxglove Studio on Windows and on the ROSBoard portal on my browser. Small success!


Like ROS 2, micro-ROS also has had a lot of changes between Galactic and Humble. The micro-ROS code which was already on the Teensy platform used Galactic libraries, and when I tried it with the micro-ROS agent in Humble, it did not work at all. So, I had to install the Humble libraries on my laptop and compile it, but then I was unable to compile the Arduino code.

I found out that now, the supported method for running micro-ROS on Teensy with Arduino used the Arduino 2.0 IDE and a different process to set up Teensyduino. Once I set everything up, I was able to use the new Humble libraries. However, I had to comment out the Parameter Server. The parameter server is initialized differently in micro-ROS Humble as compared to previous ROS 2 versions.

I made the necessary changes according to the documentation, but I wasn't able to get it working. I was able to upload the code, but the microcontroller always went into the error loop, triggering the onboard LED to flash. After temporarily commenting out the parameter server, the remaining parts worked perfectly. So, when the akros2_teleop launch file is executed, the ds4_driver reads joystick inputs and converts joystick inputs to twist messages, which the Teensy subscribes to in order to drive the motors.

DS4 Driver troubles

When I first launched the updated ds4_driver, it did not work entirely as expected. I was able to read the joystick and button inputs and convert them to twist and mode messages. On the other hand, I was unable to send feedback to the controller to set LED colors or rumble. This was a bit of a bummer, but at that time, I moved on with trying out the micro-ROS node.

Once the micro-ROS node and the rest of the drive functionality were working, some issues started cropping up with the PS4 controller. First, the ds4_twist node stopped publishing twist messages a few minutes after launching. The main ds4_driver node was operational as it was still publishing status messages, but the conversion to twist messages did not work. This, along with the inability to send feedback messages to the PS4 controller was a dealbreaker. For the time being, I decided to use the teleop_twist_keyboard to send twist messages and raised an issue on the ds4_driver repository. I have a sneaky suspicion that these issues are because of the RT kernel, but I am waiting for someone else to try it and verify this assumption.

Meanwhile, here's the robot driving around during one of the few tries where the PS4 controller driver actually worked:

Success with the T265

Finally, I tried the T265 node. I made a fresh install of the realsense_ros drivers to run the device, and to my surprise, everything worked on the first attempt! This never happened in Galactic, where my RPi ended up crashing every time I launched the T265 node. On ROS 1, I also had weird issues with the T265 node not publishing any data after some time of operation. I had only one issue on Humble (just like with previous versions) - the T265 is not recognized when the robot/RPi is turned on for the first time. The device needs to be physically unplugged and re-connected for it to be detected. But this is a known issue that Intel has stated it won't be spending time fixing, especially since the T265 is now discontinued. There was nothing I could do here, so I moved on.

Next up

There are two things I want to accomplish next:

  1. Fixing the ds4_driver issue: The first step would be to figure out why it is failing and see if my suspicion about the RT kernel is true. I'll do that by setting up Humble on a new RPi without the RT kernel and trying the driver there. If nothing works, I have some fallback options - the joy node and teleop_twist_joy for instance. Using these packages, I would also be able to use other controllers like the Stadia controller which I recently updated to Bluetooth mode and had already tested with the RPi on the robot. The Stadia controller is also a fallback option if I find out that something is wrong with the PS4 controller hardware itself.

  2. Fixing the parameter server issue: I only glanced through the documentation and tried to fix it as fast as I could and I clearly missed something. I don't always use the parameter server, I use it only during tuning and calibration to set the PID constants at run-time. But having realized that I hadn't committed the latest PID values to my GitHub repo, I need to tune the motor controllers again, so the parameter server is crucial.

Meanwhile, there's a second robot I'm working on. So far I've only managed to run some LED sequences and an example of Uncanny Eyes on the Wio Terminal.

If you've been following my progress on Twitter, I first planned on using the Arduino Nano RP2040 Connect, but I have now switched to the Wio Terminal. It has got an IMU and a microphone just like the RP2040 Connect, but also a screen, buttons, and a speaker. I'm also using the Wio Terminal Battery Chassis (650 mAh) which also extends the number of Grove connectors and works perfectly with the Grove-based LED strips. Bonus: the Wio Terminal can also run micro-ROS!

That's it for this weekend. Small and steady steps.

Did you find this article valuable?

Support Aditya Kamath by becoming a sponsor. Any amount is appreciated!