These projects are to be referenced when developing code for the monorepo. It highlights coding conventions and testing practices.
This project contains three arbitrary ROS2 nodes which communicate with each other via ROS2 publishers and subscribers. The general communication pipeline can be summed up by the image below.
Each ROS2 node is containerized(Producer, Transformer, Aggregator) and communicate with each other using ROS2 publishers and subscribers.
A single ROS2 node in our stack should contain two components, we call this the WATO Core and Node paradigm
. The Core Logic of a node represents the crucial algorithms needed to augment data. This could be a neural network, control framework, RL algorithm, etc. On the other hand, the Node represents any ROS2 interfaces and practices which enable the node to communicate with the rest of the stack. This includes subscribers, publishers, buffers, etc.
At times, the boundary between core logic and node logic may be unclear, so a good rule of thumb is that the core logic does not contain function calls from rclpy
and rclcpp
. It may contain message types. This rule may be broken in rare cases.
The reason why we do this is to make our code more intuitive to read. If any ROS2-related issues exist, we know to only look in the node component of your code, not the core logic. Another reason is for testing. Having core logic and node logic seperate enables us to not only do integration testing of the nodes, but also unit testing on only the node's logic, bypassing the need to spin up ROS2 within pytest
and gtest
. See more about testing here.
Produces unfiltered coordinate data at 500ms intervals and publishes data to the Transformer and Aggregator nodes. The coordinate data will be incremented according to the 'velocity' parameter. This can be dynamically adjusted with, ros2 param set /producer velocity <some value>
.
Collects unfiltered coordinate data from the Producer at regular intervals and filters out messages containing invalid fields. Once 10 messages are collected they are packed into a filtered_array message and published to the Aggregator.
Listens to messages from the Producer and Transfomer nodes and logs the frequency of messages to the console.
Before proceding ensure that you have followed the setup guide(setup)
To configure watod, update watod-config.local.sh
to include the samples module.
#!/bin/bash
from watod-config.sh
ACTIVE_MODULES="samples"
Then bring up the containers with,
watod up
In the Samples Module, you'll see that some of the services are commented out. The Python and C++ nodes are functionally equivalent. That is, if you were to switch out any of the C++ nodes with Python nodes by commenting and uncommenting their respective service, then the overall ROS2 communication pipeline will not change.
Editing the modules of the monorepo can be important during development, especially when you don't want to run the entire system.
The development workflow in ROS2 is similar to ROS, however, it uses a different set of tools. For developing and testing ROS2 nodes the process is as follows.
- Start the service and open a shell into a running Docker container
watod up <SERVICE_NAME>
watod -t <SERVICE_NAME>
- After making changes to source code rebuild the ROS2 package and source the install folder
colcon build
source install/setup.bash
- Test that no breaking changes were introduced and that ROS2 coding conventions were followed
colcon test
colcon test-result --verbose // Get detailed information about failures
When developing your own node, use these samples as reference for setting up ROS2 constructs, configuration parameters, etc.
At this moment, the sample nodes contain unit tests, but not integration tests. As our codebase expands, we will update this section on how to do proper integration testing. See our Testing Documentation for more details.