- name
- ros2-micro-ros
- description
- micro-ROS on MCUs — XRCE-DDS agent, rclc static executors, memory pools, transport (UART/UDP/CAN), and host↔MCU graph limits. Use when embedding ROS 2 on microcontrollers, tuning RMW_UXRCE_* limits, Agent sessions, or when the user mentions micro-ROS, Micro XRCE-DDS, rclc, or FreeRTOS/Zephyr ROS.
# micro-ROS
## What it is
**micro-ROS** brings ROS 2 APIs to microcontrollers (typically FreeRTOS / Zephyr / bare metal). It is **not** full `rclcpp` on an MCU.
| Piece | Role |
|-------|------|
| **Client** (MCU) | `rclc` / `rcl` + `rmw_microxrcedds` — pubs/subs/timers/services |
| **Agent** (Linux/companion) | Bridges Micro XRCE-DDS ↔ DDS so the MCU appears on the ROS 2 graph |
| **Transport** | UART, UDP, TCP, CAN, USB serial — Agent ↔ Client |
Host nodes talk normal ROS 2 topics; the Agent makes the MCU a participant. No Agent ⇒ MCU invisible.
## Mental model vs desktop ROS 2
| Desktop | micro-ROS |
|---------|-----------|
| Dynamic alloc common | Prefer **static** pools; tune at **build** time |
| `rclcpp` executors + callback groups | **`rclc_executor`** — fixed `number_of_handles`, C API |
| Full DDS (Cyclone/FastDDS) | **XRCE-DDS** client; Agent speaks DDS on the LAN |
| Large msgs OK-ish | **Tiny** msgs; no images/clouds on the MCU wire |
| QoS rich | Subset; match Agent/Client QoS carefully |
## Executor (`rclc`)
```c
rclc_executor_init(&executor, &support.context, number_of_handles, &allocator);
rclc_executor_add_subscription(...);
rclc_executor_add_timer(...);
rclc_executor_spin(&executor); // or spin_some / spin_period
```
- `number_of_handles` = max subscriptions + timers + services + clients + guard conditions (**not** nodes/publishers).
- Aim for **no heap in the hot path**; allocate at init / `rclc_executor_prepare`.
- Order of `add_*` matters for LET-style executors (deterministic run order after wait).
There are **no rclcpp callback groups** on classic micro-ROS. Concurrency = RTOS tasks you create; protect shared data with RTOS mutexes. Do not assume multi-threaded RMW.
## Memory / build tuning
`rmw_microxrcedds` uses **compile-time pools** (via `colcon.meta` / CMake), e.g.:
- `RMW_UXRCE_MAX_PUBLISHERS` / `MAX_SUBSCRIPTIONS` / `MAX_CLIENTS` / `MAX_SERVICES`
- `RMW_UXRCE_MAX_HISTORY` — RX queue depth before user takes
- Entity/session limits, MTU-related buffers
After rebuild, verify `build/rmw_microxrcedds/include/rmw_microxrcedds_c/config.h`. Too-small pools ⇒ silent create failures; too-large ⇒ RAM blowup on the MCU.
## Transports and Agent
- Serial: common for one robot brain ↔ MCU; baud and framing must match Agent args.
- UDP: multi-board LAN; firewall / same subnet; Discovery via Agent, not MCU multicast magic.
- One Agent can serve multiple Clients (keys / ports) — plan `client_key` and endpoints.
- Runtime config APIs exist for Agent IP/port / serial device when not baked into the firmware.
## Best practices
- Keep MCU nodes **drivers / hard RT loops**; put planning/perception on the host.
- Prefer **static** `Type[N]` and small custom msgs (see `ros2-interfaces`); avoid unbounded sequences on the wire.
- Match QoS to what XRCE + Agent actually support; test with `ros2 topic hz` on the host.
- Watchdogs: if Agent dies, MCU session drops — firmware must safe-stop actuators locally (do not rely on host cancel).
- Time: MCU often has no `/clock`; don’t pretend full `use_sim_time` unless you designed for it.
- Debug on host first with Agent + mock; then flash.
## When **not** to use micro-ROS
- Need MoveIt/Nav2-class libraries on the same chip.
- Large type support / dynamic introspection / Python.
- Multi-machine DDS without an Agent architecture.
Use a Linux SBC + normal ROS 2 instead, and keep the MCU on a bare protocol if XRCE is overkill.
Auf GitHub ansehen