Migration Guide for ROS 2 Users
This page maps standard ROS 2 concepts to their nano-ros equivalents.
It is not an API reference; use it as a checklist when moving an
existing rclcpp, rclc, or rclrs node toward nano-ros.
Concept map
| You have (ROS 2) | You get (nano-ros) | Where |
|---|---|---|
colcon workspace (src/*) | nano-ros workspace: Node pkgs + one declarative Bringup pkg + one Entry pkg per deploy target | Project layout |
package.xml | kept, verbatim — plus a <nano_ros deploy=…/> export for embedded targets | Anatomy |
.launch.xml / .launch.py | kept — nros sync resolves them (RFC-0060) into a SystemModel the Entry binary bakes in | Bringup packages |
ros2 launch pkg file | run the Entry binary (cargo run -p <entry> / ./build/src/<entry>/<entry>) — the launch product is compiled in | Entry packages |
colcon build | cmake / cargo per workspace root; colcon build still works for POSIX C++ workspaces | C/C++ workspaces |
rosdep install | nros setup <board> --rmw <rmw> | Install |
RMW_IMPLEMENTATION=… at runtime | compile-time backend: -DNROS_RMW=… / cargo feature | Switching RMW |
| generated msg packages (ament index) | nros sync writes generated/ crates + the cargo patch table | Message Generation |
find_package(rclcpp) | find_package(nano_ros) — ament-shaped, source-backed | Porting a C++ node |
ament_target_dependencies(t std_msgs) | kept, verbatim (compat shim + Find-stubs) | same page |
Setup
Standard ROS 2 usually starts from a distro install and a runtime RMW choice. nano-ros starts from a source checkout + a compile-time target tuple:
git clone --branch=v<X.Y.Z> https://github.com/NEWSLabNTU/nano-ros.git
cd nano-ros
./scripts/bootstrap.sh # build the nros CLI (no `just` needed)
source ./activate.sh
nros setup native --rmw zenoh # native/ROS/zenoh quick start
Read Setup Compared to Standard ROS 2 before changing package code.
Node Lifecycle
ROS 2 applications typically call rclcpp::init(), create nodes, then
spin. nano-ros opens an executor first; the executor owns the session,
arena, and runtime budget. Nodes and entities are created from it.
See Differences from Standard ROS 2 and Execution Model and Two-Layer API.
Publishers and Subscriptions
Topic names, message names, and CDR wire encoding stay ROS-shaped. The main porting decision is whether to use:
- polling handles from
Node::create_*, or - callback registration through
Executor::register_*.
Use polling for RTIC, Embassy, or tight RT loops. Use callbacks for desktop-style event-driven nodes.
Services and Actions
Service and action names map cleanly, but nano-ros exposes request / reply and goal / feedback / result paths through explicit handles and promises. Manual-poll paths may require explicit result handling in RTOS loops.
Start with the native examples, then check platform-specific examples for FreeRTOS, Zephyr, or bare-metal timing constraints.
QoS and Events
nano-ros keeps DDS-shaped QoS profile fields, but each backend advertises the policies it can enforce. Unsupported QoS is reported at entity creation instead of being silently downgraded.
See QoS, Status Events, and Discovery and Choosing an RMW Backend.
Message Generation
Standard ROS 2 builds generated message libraries as sibling packages. nano-ros generates Rust, C, or C++ bindings into the workspace or build tree and can use a shared generation cache.
See Message Binding Generation.
Backend Selection
Replace runtime RMW_IMPLEMENTATION=... with a compile-time selection:
zenohfor ROS 2 interop throughrmw_zenoh_cpp(default).xrcefor agent-based micro-ROS-style deployments.cycloneddsfor direct DDS/RTPS interop withrmw_cyclonedds_cpp— no router or agent process at all — where the platform supports the required networking and memory model.
Common Porting Traps
- Assuming the backend can change without rebuilding.
- Creating heap-heavy callbacks on
no_stdtargets withoutalloc. - Expecting ROS 2 graph introspection APIs on constrained targets.
- Forgetting to match ROS domain ID, QoS reliability, or zenoh router mode during interop tests.
- Treating a platform guide as optional when cross-compiling for RTOS or bare-metal targets.