Building Arduino firmware with CMake and catkin
The nice part of the ROS community is that many of the significant problems have been solved before, so you can generally get help easily. I needed this community multiple times while setting up, so here’s my process so others can learn.
The first thing to do is look at the dedicated rosserial catkin tutorial. This has the entire process listed, but in order to get my code to work, I had to figure out a number of issues.
The general process is as follows:
- Create a catkin project (probably best to have an Arduino specific project)
- Write your code inside the project’s firmware folder
- Create a CMakeLists.txt file to load the Arduino specific settings
- Create a second CMakeLists.txt file to handle compiling for a specific Arduino board and handle upload
- If your code is clean, upload to the Arduino with USB
If you follow the tutorial with the simple code provided, everything should work as expected. My problem was that I started with my full YardBot code and that means things like 3rd party libraries and ROS packages with custom messages.
Store 3rd party libraries inside firmware/libraries
Originally my Arduino code lived at ~/sketchbook, with all ROS message headers and libraries inside ~/sketchbook/libraries. After moving the code to my ROS workspace, I also copied the libraries. It’s best to remove the ros_lib folder, otherwise there are duplicates, but otherwise it works.
Follow proper coding conventions
With the Arduino, normally you can get away with things like not having function prototypes. The first time I compiled, I hit multiple errors for
function not declared, so I had to go through everything and copy function prototypes to the top of the file. When I did this for the second Arduino’s firmware, it compiled on the first try.
Cleaning the workspace helps
When you add a new component, it’s a good idea to clean the workspace and compile from scratch. This means deleting the
folders of the workspace.
Source before compiling
After cleaning the workspace, I ran into a problem multiple times where my custom message package would not be picked up, and that caused the Arduino header generator to fail. This meant the message definitions weren’t available, and errors were thrown. The forum solutions mostly included sourcing the correct files, so after running
source [workspace]>/install/setup.bash before compiling, everything fell into place. I’ve added that process to my ~/.bashrc file, so hopefully that will always work now.
Have another ROS installation available
If you install the Arduino tools from apt, there shouldn’t really be a problem, but I ran into issues a few times where files that the system thought were there, weren’t. Running an update and upgrade didn’t help, so I ended up copying some files from my ROS desktop.
Choose the correct board definition
The second CMakeLists file includes the USB port and board definition so your code can get to the Arduino properly. Be sure to include the right port and board name. You can find the boards.txt from the Arduino core install, so it’s best to find it and browse to find yours. I used “mega” and “mega2560”.
It was a challenging couple of nights to figure it out, but now that it works, I can update the Arduino firmware without starting my virtual machine or switching USB cables between systems.