The control boundary
ROS 2 is excellent for composing robotics systems, but motor control often belongs on a microcontroller. A good boundary lets the main computer plan and coordinate while the embedded board handles timing-sensitive outputs and safety behavior.
Message flow
A typical mobile platform can use this path:
- Navigation or teleoperation publishes
geometry_msgs/Twist. - A bridge node validates command limits.
- micro-ROS transports velocity commands to the motor controller.
- Firmware converts velocity into driver outputs.
- Encoders or status frames return telemetry.
void onTwist(const geometry_msgs::msg::Twist& msg) {
const float linear = clamp(msg.linear.x, -MAX_LINEAR, MAX_LINEAR);
const float angular = clamp(msg.angular.z, -MAX_ANGULAR, MAX_ANGULAR);
motor_controller_set_velocity(linear, angular);
watchdog_kick();
}
Safety rules
Treat every command as temporary. If fresh velocity commands stop arriving, the embedded board should ramp down and enter a safe state. This is better than relying on the host computer to always send a stop message.
Debugging strategy
Add counters for dropped messages, watchdog timeouts, transport reconnects, and motor driver faults. A small serial diagnostic mode can make field testing much faster.
Takeaway
The strongest ROS 2 and micro-ROS systems use clean responsibility boundaries. The host thinks, plans, and visualizes. The microcontroller enforces timing, safety, and electrical reality.