Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

nano-ros vs micro-ROS

The closest peer project to nano-ros is micro-ROS. Both ship a full embedded ROS 2 framework — client library + RMW + tooling targeted at MCU-class hardware. This page is an apples-to-apples comparison.

Why not compare to rmw_zenoh or ros2_rust? Scope mismatch. rmw_zenoh is a single RMW backend; nano-ros is a full client stack. ros2_rust (rclrs) targets hosted Linux only — it can’t run on the bare-metal or RTOS targets nano-ros and micro-ROS both address. Comparing nano-ros to either would be misleading.

Side-by-side

Axisnano-rosmicro-ROS
Project homeNEWSLab NTUROS 2 ecosystem (community + Bosch + eProsima)
First release20242019
Primary languageRust (with C + C++ bindings)C (rclc)
User-facing APIsRust + C + C++C only (rclc); experimental C++ in rclcpp_lite
RMW backend choiceZenoh, XRCE-DDS, Cyclone DDS — pick at compile timeXRCE-DDS only
Network modelPeer-to-peer (Zenoh / Cyclone DDS) or agent-based (XRCE)Agent-based only
Bridge process required?No for Zenoh / Cyclone DDS; yes for XRCEYes (Micro-XRCE-DDS Agent)
Supported RTOSesFreeRTOS, NuttX, ThreadX, Zephyr, ESP-IDF, PX4 (NuttX), POSIX, bare-metalFreeRTOS, NuttX, Zephyr, ESP-IDF, POSIX; PX4 is the canonical deployment
no_std coreYes — entire client stack compiles no_std + heaplessNo — rclc requires libc + a heap
Heap usageOptional on bare-metal (XRCE backend is fully static); required for Zenoh / Cyclone DDSRequired (malloc-based DDS-XRCE client)
RT scheduling storySchedContext API: FIFO / EDF / Sporadic / TimeTriggered classes; ARINC-653 cyclic-executive surface; per-callback runtime accounting + overrun detectionrclc executor with priority callbacks; no SchedContext / EDF / TT story
Multi-executor preemptionExecutor::open_threaded per-RTOS via PlatformScheduler traitSingle executor per process
Multi-backend bridge in one binaryYes — Executor::open_with_rmw + multi-NodeNo (single XRCE session per process)
DiscoveryZenoh liveliness, RTPS SPDP, XRCE-via-AgentXRCE-via-Agent
QoS supportBackend-dependent matrix (Zenoh 4/7, XRCE 4/7, Cyclone DDS 7/7)Subset of XRCE QoS
Formal verification160 Kani harnesses + 102 Verus proofs (CDR, scheduling, RMW glue)None published
E2E safety protocolCRC-32/ISO-HDLC + sequence tracking, EN 50159-mapped (safety-e2e feature)None
ROS 2 distro coverageHumble (Iron deferred — type-hash work pending)Humble, Iron, Jazzy
Build systemCargo + CMake + platform tools (west, idf.py, probe-rs) plus just recipes; C/C++ consume via add_subdirectory(<repo>)colcon + CMake; per-RTOS meta-build (create/configure/build/flash_firmware.sh)
Deploy/config modelEntry packages select board/RMW/deploy shape; Bringup packages own launch topology; platform tools build and flashcolcon.meta (hand-tuned static sizing) + configure_firmware.sh -t <transport> flags + hand-coded rclc app
Host-side brokernone (Zenoh P2P / Cyclone DDS brokerless); Agent only for XRCEMicro-XRCE-DDS Agent always required
Release modelSource-only (no crates.io, no precompiled binaries)Source-only + per-distro Debian packages
Code-size (Cortex-M XRCE talker)~75 KB flash (XRCE), ~100 KB+ (Zenoh)~30–50 KB (XRCE + rclc)
LicenseMIT OR Apache-2.0 (dual)Apache-2.0
GovernanceSingle-academic-lab maintainership todayROS 2 community + corporate stewards
Commercial supportNone as of writingBosch + eProsima offer services

Pick nano-ros when…

  • You want Rust as a first-class API, not bolted on. Memory safety + ownership semantics extend to your application code.
  • You want multi-backend flexibility — same binary can speak Zenoh + DDS, or you want to pick Zenoh’s peer-to-peer model over XRCE’s agent dependency.
  • You need scheduling primitives beyond priority callbacks — EDF / Sporadic / ARINC-653 TT classes, per-callback runtime accounting, formal SchedContext API.
  • You’re targeting safety-aware deployments that benefit from the E2E CRC + sequence tracking and the Kani / Verus harness coverage.
  • You want a lean source-only consumption model: git clone + add_subdirectory(<repo>). No crates.io drift, no pre-built per-distro binaries.

Pick micro-ROS when…

  • You’re already in the micro-ROS ecosystem (existing rclc code, established Agent deployment, ROS 2 Jazzy / Iron support).
  • Your toolchain is C-only and you don’t want to introduce Rust into the build pipeline.
  • Your target’s flash budget is tight (~30 KB ceiling) — the rclc + XRCE client is smaller than nano-ros + Zenoh.
  • You need commercial support contracts today (Bosch, eProsima, PIWeb).

Migration sketch

If you’re porting from micro-ROS to nano-ros:

  • rcl_node_initExecutor::create_node (Rust) / nros_executor_node_init (C).
  • rclc_executor_tnros::Executor.
  • rclc_publisher_init_defaultNode::create_publisher::<M> or nros_publisher_init.
  • micro-ROS’s rmw_uros_set_custom_transport → nano-ros’s custom transport pattern via nros_platform_* C ABI (see Custom Transport).
  • XRCE Agent deployment stays the same — point nano-ros’s XRCE backend at the same Agent.

See also