zerodds_spatial_ros2/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! SpatialDDS <-> ROS 2 semantic mapping for ZeroDDS.
4//!
5//! Crate `zerodds-spatial-ros2`. Safety classification: **STANDARD**.
6//!
7//! This is the ROS 2 carrier for the [SpatialDDS profile](zerodds_spatial_dds):
8//! it converts the SpatialDDS types to and from the ROS 2 common-interfaces
9//! messages so a ZeroDDS node and a native ROS 2 node share a world model over
10//! standard ROS topics. The other SpatialDDS carriers (MQTT / WebSocket / MCAP)
11//! need no profile code because they are type-agnostic; ROS 2 is the one that
12//! needs a *semantic* map, because ROS and SpatialDDS name and shape the same
13//! concepts differently (`geometry_msgs`/`sensor_msgs`/`vision_msgs`/`tf2_msgs`/
14//! `geographic_msgs`).
15//!
16//! Both sides are ZeroDDS-generated: the ROS 2 message types come from the
17//! vendored [`idl/ros_msgs.idl`] run through ZeroDDS' own IDL->Rust codegen (the
18//! same pipeline that generates the SpatialDDS types), so a converted value
19//! carries the ROS 2 XCDR wire layout directly.
20//!
21//! ## Mappings ([`convert`])
22//!
23//! | SpatialDDS | ROS 2 |
24//! |---|---|
25//! | `spatial::core::FramedPose` | `geometry_msgs/PoseStamped` |
26//! | `spatial::core::FrameTransform` | `geometry_msgs/TransformStamped`, `tf2_msgs/TFMessage` |
27//! | `spatial::core::GeoPose` | `geographic_msgs/GeoPoseStamped` |
28//! | `spatial::semantics::Detection3D` | `vision_msgs/Detection3D` |
29//! | `spatial::semantics::Detection3DSet` | `vision_msgs/Detection3DArray` |
30//! | `spatial::vio::ImuSample` | `sensor_msgs/Imu` |
31//!
32//! Each conversion is bidirectional (`*_to_ros` / `*_from_ros`), with `From`
33//! impls for the SpatialDDS->ROS direction. Field-fidelity notes (what each map
34//! drops) are on [`convert`].
35//!
36//! ## Naming ([`naming`])
37//!
38//! [`naming::RosMessage`] gives the rmw-compatible DDS topic (`rt/…`) and type
39//! name (`pkg::msg::dds_::Type_`) so a converted value publishes on the topic a
40//! native ROS 2 subscriber is listening on.
41
42#![forbid(unsafe_code)]
43#![allow(
44 missing_docs,
45 clippy::all,
46 clippy::pedantic,
47 unused_imports,
48 non_camel_case_types,
49 non_snake_case
50)]
51
52// The generated ROS 2 message modules use crate-relative paths, so they are
53// included at the crate root (exposing `geometry_msgs`, `sensor_msgs`, ...).
54include!(concat!(env!("OUT_DIR"), "/ros_msgs.rs"));
55
56pub mod convert;
57pub mod naming;