From 66c6070c1414a45f372bb6c56b510b0e405d5c64 Mon Sep 17 00:00:00 2001 From: cc Date: Sun, 20 Sep 2026 23:33:58 -0700 Subject: [PATCH 01/55] spec: add --- .../.openspec.yaml | 2 + .../replace-lcm-message-encoding/design.md | 155 ++++++++++++++++++ .../replace-lcm-message-encoding/proposal.md | 34 ++++ .../specs/cdr-typed-messaging/spec.md | 49 ++++++ .../demonstrable-message-delivery/spec.md | 32 ++++ .../message-package-distribution/spec.md | 35 ++++ .../spec.md | 40 +++++ .../standalone-message-generation/spec.md | 65 ++++++++ .../replace-lcm-message-encoding/tasks.md | 66 ++++++++ 9 files changed, 478 insertions(+) create mode 100644 openspec/changes/replace-lcm-message-encoding/.openspec.yaml create mode 100644 openspec/changes/replace-lcm-message-encoding/design.md create mode 100644 openspec/changes/replace-lcm-message-encoding/proposal.md create mode 100644 openspec/changes/replace-lcm-message-encoding/specs/cdr-typed-messaging/spec.md create mode 100644 openspec/changes/replace-lcm-message-encoding/specs/demonstrable-message-delivery/spec.md create mode 100644 openspec/changes/replace-lcm-message-encoding/specs/message-package-distribution/spec.md create mode 100644 openspec/changes/replace-lcm-message-encoding/specs/self-describing-message-recordings/spec.md create mode 100644 openspec/changes/replace-lcm-message-encoding/specs/standalone-message-generation/spec.md create mode 100644 openspec/changes/replace-lcm-message-encoding/tasks.md diff --git a/openspec/changes/replace-lcm-message-encoding/.openspec.yaml b/openspec/changes/replace-lcm-message-encoding/.openspec.yaml new file mode 100644 index 00000000000..563fab5abae --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-09-21 diff --git a/openspec/changes/replace-lcm-message-encoding/design.md b/openspec/changes/replace-lcm-message-encoding/design.md new file mode 100644 index 00000000000..1516b356477 --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/design.md @@ -0,0 +1,155 @@ +## Context + +DimOS currently couples message definitions, generated classes, and LCM encoding to `dimos-lcm`. The Python message protocol exposes `lcm_encode`/`lcm_decode`; both LCM and Zenoh typed pub/sub use that codec. C++ defaults to generated LCM codecs. Rust depends on both `lcm-msgs` and a raw `dimos-lcm` transport crate from the same external repository. + +Python message classes also contain geometry, timestamp, NumPy, Open3D, and viewer behavior. Their field shapes are not consistently ROS2 shapes: stamped poses can be flattened, timestamps use convenience fields, and a single transform can be exposed as `TFMessage`. Replacing only the serializer would preserve these inconsistencies and the message-authoring bottleneck. + +The existing native ping-pong examples already run on LCM or Zenoh. The recorder has an MCAP writer, but its current LCM payload channels do not carry the complete ROS2 schemas needed by viewers. Live Rerun and browser decoding are existing consumers that must remain functional. + +## Goals / Non-Goals + +**Goals:** + +- A user adds a namespaced `.msg` locally, builds all three languages, and uses it without a DimOS or `dimos-lcm` PR. +- Definition resolution, code generation, package installation, and ordinary runtime operation work without ROS installed. Native compilers and standalone codec/parser dependencies are acceptable. +- Generated ROS-shaped types and CDR are the common typed-message representation across Python, C++, Rust, LCM, Zenoh, recordings, and visualization adapters. +- Official artifacts are generated in CI; local users run the same workflow. Generated source is absent from Git. +- Each PR provides a working increment, automated tests, and a reproducible human-facing demo. The final stack removes all dependency on the external repository. + +**Non-Goals:** + +- ROS CLI compatibility, a DDS/ROS graph, new ROS network interoperation, or `.srv`/`.action` generation. Existing RPC remains separate. +- Reading old LCM-encoded recordings, mixed old/new deployments, compatibility wrappers, fallback decoders, or data migration tools. +- Runtime schema-hash enforcement, transport hash framing, a remote schema service, a custom package manager, or runtime package downloads. +- A new live Foxglove bridge or automatic semantic visualization of every custom message. + +## Decisions + +### 1. Definitions are the source of truth + +Use ROS2 `.msg` as the authoring format. Vendor the standard Jazzy definitions needed by supported DimOS messages with their transitive dependencies, immutable upstream revisions, and required licenses/notices. Standard schemas include dependencies from both `common_interfaces` and `rcl_interfaces`; do not assume all definitions live in one repository. + +Resolve names as `package/msg/Type` from bundled definitions, the user's package roots, and installed schema packages. Resolve the full dependency closure before emitting code. Reject unresolved references, recursive value layouts, invalid definitions, and conflicting definitions with the same qualified name. Identical repeated definitions can be deduplicated; there is no override precedence for conflicting definitions. + +The initial supported `.msg` surface includes primitive fields, constants, defaults, nested messages, fixed arrays, sequences, and bounded strings/sequences used by Jazzy message definitions. Unsupported syntax must fail at generation with a source location; it must never silently change the wire layout. `.srv` and `.action` are outside the interface. + +**Alternative considered:** installing ROS message packages and invoking their build chain. Rejected because it makes ROS installation part of the user's message-development workflow. A ROS-free parser or a narrowly packaged upstream parser is acceptable. + +### 2. One generation workflow, native outputs for all three languages + +```text +bundled Jazzy .msg + local/installed .msg + | + resolver + normalized definitions + | + +----------+-----------+ + | | + generated C++/Fast CDR generated Rust/Serde + | | + generated pybind11 native CDR backend + | + Python + + All outputs use the same CDR wire contract. +``` + +Use Fast CDR-backed generated C++ serialization and generated pybind11 bindings for Python. Python and C++ share the implementation rather than maintaining separate Python wire layouts. Rust uses generated native types with a Serde-compatible CDR backend. The generator also emits qualified type metadata and complete schema text for recording and introspection. + +The implementation starting point is standalone `.msg` parsing, lowering to IDL for Fast-DDS-Gen without DDS type support, generated pybind11 bindings, and a Rust struct emitter plus `re_cdr`. These are candidates to validate, not a claim that a turnkey three-language generator exists. Stage 1 must pin working versions and document the exact build invocation, generated APIs, namespace handling, bounds/default behavior, and dependency footprint. A backend that cannot satisfy the contract must be replaced or the design revised before stage 1 is accepted; do not proceed with a knowingly temporary codec. + +Use encapsulated plain CDR/XCDR1 with little-endian emission as the initial wire profile; decode the supported big- and little-endian representations according to the encapsulation header and reject unsupported representations. Check layout against ROS2 Jazzy serialization in CI. No LCM fingerprint or DimOS schema-hash prefix is part of the CDR payload. + +Provide transport-neutral Python `encode()` and class-level `decode()` operations, equivalent generated codec operations in C++ and Rust, and immutable type/schema metadata. Keep generated wire types free of visualization or geometry dependencies. Nested fields and sequences must have documented mutation semantics in Python; do not rely on pybind11's implicit STL copies as if they were live views. + +**Alternatives considered:** handwritten codecs, a dynamic Python-only codec system, and a single FFI runtime for all languages. Handwritten layouts recreate the maintenance bottleneck; Python-only generation misses the native-language requirement; sharing the C++ backend with Python while keeping native Rust limits FFI complexity. + +### 3. Standard package systems distribute source schemas and generated artifacts + +Use one documented local generation entry point for all outputs. Application-local and reusable packages use the same definition layout and resolver; publishing is optional. Output generated sources to ignored build directories. + +Distribute Python wheels/sdists, an installable CMake package, and Rust crates through their ordinary tooling. Include source `.msg` resources and schema metadata in the applicable packages. Rust consumers compile crate sources normally; this design does not promise portable precompiled Rust binaries. Source distributions contain the inputs/build dependencies needed for reproducible generation; wheels contain usable compiled bindings. + +Use the existing Python packaging/native-build infrastructure and release matrix. CI runs the same generator, checks deterministic output, builds packages, and supplies build artifacts for review before release publication. Adding schemas to an external application must not require editing DimOS's built-in type registry. Discover installed Python message/schema providers through a `dimos.messages` entry-point group; ordinary known-type use continues to use imports. + +Install dependencies at environment setup or build time. Runtime never downloads schemas or invokes a generator to discover a type. Generation with all dependencies installed must work without network access. + +### 4. Replace message APIs and their consumers together + +Use the actual ROS2 field shapes: `Header.stamp.sec/nanosec`, no ROS1 `Header.seq`, nested `PoseStamped.pose`, and separate single `TransformStamped` versus `TFMessage.transforms`. Represent compressed images as `CompressedImage`, not JPEG bytes disguised as a raw `Image`. Preserve arbitrary `PointCloud2` fields, offsets, strides, and endianness when crossing the wire. + +Move geometry operations, timestamp extraction, NumPy/Open3D conversion, and Rerun mappings into separate modules. Update callers rather than reintroducing old convenience methods on generated types. Timestamp-dependent buffers and recorders use explicit extractors; unstamped messages use reception time where required. + +NumPy helpers return read-only borrowed views when the message layout can be represented without copying, retaining the storage owner for the view lifetime. Reject operations that would resize or invalidate backing storage while a view is borrowed. An explicit copy path supports mutable processing. Layouts that require conversion must document and test the copy; never mislabel an allocating conversion as zero-copy. Stage 1 measures representative image/point-cloud buffers and establishes a reproducible performance baseline, without inventing a throughput target not supplied by the user. + +Update typed pub/sub, native SDKs, SHM typed paths, WebRTC/browser paths, tools, existing ROS bridge conversions, robot/perception/navigation consumers, and examples. Raw-byte transport APIs and separate Python object/pickle paths are not redefined by this change. Audit those paths to remove any actual dependency on LCM message generation without broadening the task into a new object-serialization design. + +### 5. Keep transport routing separate from the CDR payload + +LCM and Zenoh continue to carry opaque payload bytes; typed layers select generated CDR codecs. Preserve topic/type routing using qualified message identity where needed, without adding runtime hash enforcement. Multiplexed browser/WebRTC channels must route by explicit channel/type metadata; attempting multiple CDR decoders until one succeeds is not a valid replacement for LCM fingerprint filtering. + +Reuse the browser's existing schema metadata distribution path with ROS2 definitions and a CDR decoder. External message authors do not generate handwritten TypeScript decoders per message. Rerun conversion is handled by explicit adapters outside generated types. + +For Rust's raw LCM transport, first inspect the existing external implementation and its license/provenance. Prefer moving the narrowly required, reusable transport implementation into a separate in-tree Rust transport crate, preserving notices, rather than rewriting the protocol. Keep it independent of message schemas and code generation. If that cannot be done under its license or build constraints, resolve a maintained raw transport replacement during stage 1. Test native/Python communication and fragmented large payloads before depending on the replacement. This is an early feasibility gate, not a final-stage surprise. + +### 6. MCAP carries the schemas needed by viewers + +Write standard MCAP ROS2-profile channels with message encoding `cdr`, schema encoding `ros2msg`, qualified schema names, and the complete concatenated dependency definitions. Keep the stored payload exactly the generated CDR message. Use MCAP chunk compression rather than wrapping channel payloads in a custom compression codec. Compressed image data remains a standard `CompressedImage` message. + +Feed schema metadata to the recorder through its existing stream startup configuration. Recording an arbitrary custom type requires no recorder-specific generated decoder or rebuild. Existing recognized-type optimizations must preserve the declared schema and message semantics. Use source stamps for supported stamped messages and reception time for otherwise unstamped messages, with recording log time always recording reception. + +First prove viewer interoperability using a standalone producer and recording, then connect the actual recorder and replay paths. Both Foxglove and the repository's pinned Rerun version must inspect custom fields using only embedded definitions. Standard image and pose messages must have semantic visualization; arbitrary custom messages need only field inspection unless an explicit visualization adapter exists. Preserve existing live Rerun behavior; do not add a live Foxglove server in this stack. + +### 7. A cumulative demo is part of every PR + +Use one small hardware-free example project throughout: a custom telemetry message referencing a standard type, synthetic image data, and a moving pose. Early terminal demos show actual fields and mutations; later stages show the same data through packages, transports, viewers, and recording/replay. Name Python demo scripts `demo_*.py` to avoid pytest collection. + +Every PR description includes setup, exact commands, expected visible results, teardown, limitations, test results, and a terminal capture or screen recording. Persist useful outputs as CI artifacts. Automated tests are mandatory and never substitute for the human demo. Avoid building a new demo framework; scripts and a concise README suffice. + +## Risks / Trade-offs + +- **No verified turnkey three-language generator** → Stage 1 is a real production-capable generation/codec gate. Do not cut over the application until the full dependency and conformance checks pass. +- **Python binding copies or unsafe lifetimes** → Exercise nested mutations, sequence edits, read-only buffers, owner lifetime, and realistic image/point-cloud sizes in stage 1, then preserve those checks through packaging and runtime integration. +- **A large consumer refactor** → Inventory consumers early. Keep the public type switch and affected callers in a working change; split stage 4 only along independently runnable boundaries with their own demos, not into broken intermediate commits. +- **MCAP parses but is not useful in a viewer** → Human acceptance requires visible standard-message visualization and custom-field inspection in both viewers, using the same file. +- **Runtime schema mismatches remain possible** → Build-time definition conflicts fail. Runtime schema-hash enforcement is explicitly deferred; do not claim decoding or routing detects all same-name schema conflicts. RIHS01 is the agreed future direction, outside this acceptance gate. +- **Rust transport source remains tied to the old repository** → Inspect and prove the removal route in stage 1 and verify a clean final build with external repository access unavailable. +- **Existing recordings and clients break** → This is an intentional clean replacement. Document the break; do not add fallback readers or migration tooling. + +## Migration Plan + +Deliver a linear PR stack. The bottom branch targets `main`; each later PR is reviewed against its predecessor and ultimately lands on `main` in dependency order. No branches, PRs, releases, or pushes are created by this proposal task. + +| Stage | Outcome | Required human demo | +| --- | --- | --- | +| 1. Generate and exchange | All three languages generate from one definition and use compatible CDR; prove the Rust raw transport exit path early | File-based Python → C++ → Rust → Python relay, printing and changing actual nested/custom fields; demonstrate realistic buffer conversion behavior | +| 2. Package and consume | CI and local builds produce usable standard packages | A separate application adds a field, regenerates, builds all three consumers, and shows the new field in the relay without editing DimOS | +| 3. Inspect recordings | Standalone generated messages produce self-contained MCAP | Open one image/pose/custom-telemetry MCAP in Foxglove and Rerun, with no installed custom message package in either viewer | +| 4. Run DimOS | Generated types and CDR replace runtime message APIs and affected consumers | Hardware-free Python/C++/Rust blueprint over LCM and then Zenoh, with live Rerun and browser decoding | +| 5. Record and replay | Actual recorders/readers use the new representation | Record the blueprint including a custom type, stop it, inspect in both viewers, then replay through DimOS | +| 6. Remove old dependency | No build/runtime dependency on `dimos-lcm` or its message encodings | Clean install/build with external repository access unavailable, dependency inventory, and the full custom-message-to-recording workflow | + +Stages 1–3 establish the new generation workflow in standalone examples before the runtime cutover. This temporary development sequence is not a shipped compatibility layer: migrated runtime paths have a single CDR implementation. Update or replace repository fixtures and their consumers as the corresponding path changes. Stage 4 must include the minimum new-format recorder/reader and replay adaptations required by its type switch; it must not leave existing consumers broken until stage 5. Stage 5 completes generic schema propagation and the integrated recording/viewer/replay workflow, reusing stage 3's MCAP support. Move prerequisite work earlier if the consumer inventory reveals another dependency. All previous demos remain runnable at each accepted stage. + +Rollback is source/release rollback as a unit; old and new processes or recordings are not promised interoperability. Retain demo artifacts as review evidence, not as a promise to decode the obsolete format. + +## Open Questions + +No outstanding product decisions require another user interview. The following engineering checks are mandatory stage-1 work and must be recorded here before later stages proceed: + +1. Exact pinned parser, C++ generator/Fast CDR, pybind11, and Rust codec versions that pass the complete `.msg` and CDR conformance suite without ROS installed. +2. Measured Python buffer-copy and owner-lifetime behavior, with any unavoidable copies documented. +3. The license/provenance and build viability of extracting Rust's existing raw LCM transport, or the concrete maintained replacement if extraction is unsuitable. +4. The consumer inventory and any necessary subdivision of stage 4 into independently runnable PRs, each retaining the demo requirement. + +## Reference material + +These references informed exploration; pinned versions and executable conformance evidence, not current web documentation alone, determine acceptance. + +- [ROS2 interface definition format](https://design.ros2.org/articles/legacy_interface_definition.html) +- [Jazzy common interfaces](https://github.com/ros2/common_interfaces/tree/jazzy) and [Jazzy runtime interfaces](https://github.com/ros2/rcl_interfaces/tree/jazzy) +- [Fast DDS generator](https://fast-dds.docs.eprosima.com/en/3.x/fastdds/dds_layer/topic/fastddsgen/fastddsgen.html) and [Fast CDR](https://github.com/eProsima/Fast-CDR) +- [pybind11 STL conversion semantics](https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html) +- [Rust re_cdr](https://docs.rs/re_cdr/latest/re_cdr/) +- [MCAP schema and encoding registry](https://mcap.dev/spec/registry) +- [Foxglove custom schema encodings](https://docs.foxglove.dev/docs/getting-started/custom/custom-schema-encodings) +- [Rerun 0.32 MCAP message formats](https://github.com/rerun-io/rerun/blob/0.32.0/docs/content/concepts/logging-and-ingestion/mcap/message-formats.md) diff --git a/openspec/changes/replace-lcm-message-encoding/proposal.md b/openspec/changes/replace-lcm-message-encoding/proposal.md new file mode 100644 index 00000000000..7a93d94d08b --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/proposal.md @@ -0,0 +1,34 @@ +## Why + +Adding a DimOS message currently requires generated bindings from the external `dimos-lcm` repository. That makes an upstream PR part of normal application development. Users need to define, build, exchange, and inspect their own messages locally, without installing ROS or changing DimOS. + +## What Changes + +- Introduce one standalone generation workflow for ROS2 `.msg` definitions, producing Python, C++, and Rust types and CDR encode/decode implementations. Bundle pinned ROS2 Jazzy standard definitions and their dependency closure. +- Support application-local definitions and reusable message packages through normal Python, CMake, and Cargo tooling. Generate sources during local builds and CI; do not commit generated sources. +- **BREAKING** Replace handwritten/rich LCM-backed message classes with generated ROS-shaped types. Move geometry, timestamp, NumPy, and visualization behavior into separate utilities and adapters; update all consumers. +- **BREAKING** Replace LCM message encoding with ROS2-compatible CDR throughout typed messaging and recordings. Keep LCM and Zenoh as transports. Remove old wire decoders, compatibility aliases, and obsolete recording paths instead of supporting legacy data. +- Embed complete `ros2msg` schemas in CDR MCAP recordings so Foxglove and Rerun can inspect standard and custom messages without installed message packages. Preserve live Rerun and browser visualization. +- Eliminate all dependencies on the `dimos-lcm` repository, including the Rust raw transport dependency, while retaining LCM transport functionality. +- Deliver six dependent PR stages, each with a runnable human-facing demo, automated tests, and review evidence. Keep all earlier demos working. +- Defer runtime schema-hash enforcement, ROS CLI/network integration, service/action generation, and a new live Foxglove bridge. + +## Capabilities + +### New Capabilities + +- `standalone-message-generation`: ROS-free definition resolution and generated Python/C++/Rust types and compatible CDR codecs. +- `message-package-distribution`: Local and reusable schema packages, installed artifacts, and reproducible CI generation. +- `cdr-typed-messaging`: Generated ROS-shaped types throughout DimOS, transport-independent CDR, separate helpers, and removal of the external repository dependency. +- `self-describing-message-recordings`: Embedded-schema CDR MCAP capture, viewer inspection, and DimOS replay. +- `demonstrable-message-delivery`: Dependent PR stages with cumulative human-facing demos and automated acceptance coverage. + +### Modified Capabilities + +None. This checkout has no existing OpenSpec capability specifications; the new specifications describe the replacement behavior. + +## Impact + +Affected areas include `dimos/msgs`, typed pub/sub and transports, Python module consumers, C++ and Rust SDKs/examples, timestamp and geometry helpers, live Rerun, browser decoding, memory recorders/readers, build manifests, CI, and documentation. Existing ROS bridge consumers must be updated to the generated field shapes; this does not add a new ROS interoperability objective. + +The intended implementation uses Fast CDR-backed C++ codecs and generated pybind11 bindings, plus generated native Rust types with a CDR backend. Stage 1 must validate and pin the standalone generation backends before the application cutover. Native compilation is acceptable for local custom Python message builds. ROS is allowed only in optional integration environments and the CI conformance job, not as a requirement for generation, installation, or ordinary runtime use. diff --git a/openspec/changes/replace-lcm-message-encoding/specs/cdr-typed-messaging/spec.md b/openspec/changes/replace-lcm-message-encoding/specs/cdr-typed-messaging/spec.md new file mode 100644 index 00000000000..3dfbbe45981 --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/specs/cdr-typed-messaging/spec.md @@ -0,0 +1,49 @@ +## ADDED Requirements + +### Requirement: Generated ROS-shaped types replace LCM-backed types + +DimOS typed-message APIs SHALL use the generated field shapes and transport-neutral codecs. Consumers SHALL be updated to ROS2 timestamps, nested stamped types, and correct single-transform versus transform-array types. Rich geometry, timestamp, NumPy/Open3D, and visualization behavior SHALL live in separate utilities/adapters. Obsolete LCM codec methods and convenience wrappers SHALL be removed rather than retained as compatibility aliases. + +#### Scenario: A stamped pose crosses a module boundary +- **WHEN** a producer publishes a generated `PoseStamped` containing a header and nested pose +- **THEN** the receiver and timestamp/geometry helpers consume its ROS2-shaped fields directly +- **AND** the path does not convert through an LCM message object + +#### Scenario: Compressed image publication +- **WHEN** a producer publishes compressed image bytes +- **THEN** it uses the generated `CompressedImage` schema and corresponding viewer adapter rather than disguising compressed bytes as a raw `Image` + +### Requirement: LCM and Zenoh transport the same typed CDR payloads + +The typed layers for Python, C++, and Rust SHALL serialize through generated CDR codecs while retaining raw LCM and Zenoh transport functionality. Type routing SHALL use explicit topic/type metadata where required, without runtime schema-hash enforcement. Migrated paths MUST NOT retain an LCM message-codec fallback. + +#### Scenario: Three-language live relay on each transport +- **WHEN** a hardware-free blueprint exchanges a generated custom message among Python, C++, and Rust using LCM and then Zenoh +- **THEN** the same declared values and language-specific edits are observed on both transports +- **AND** both runs use the generated CDR payload contract + +#### Scenario: Large LCM payload +- **WHEN** the blueprint sends an image large enough to require LCM fragmentation between native and Python processes +- **THEN** receivers reconstruct and decode the complete generated message correctly + +### Requirement: Existing visualization consumers remain usable + +The change SHALL preserve live Rerun through separate generated-type adapters and update browser/WebRTC decoding to CDR with schema metadata. Browser support for a new message SHALL NOT require a handwritten per-message TypeScript decoder. Multiplexed channels SHALL dispatch by explicit channel/type identity rather than probing CDR decoders for success. + +#### Scenario: Synthetic data in existing viewers +- **WHEN** the integrated example publishes a changing pose and synthetic image +- **THEN** live Rerun displays their updates and the browser decodes the advertised generated schema correctly + +#### Scenario: Two types share a multiplexed connection +- **WHEN** two typed channels with different layouts share a WebRTC connection +- **THEN** each message is delivered to the decoder selected by its channel/type metadata +- **AND** decoder success is not used as the type-identification mechanism + +### Requirement: Eliminate the external message repository dependency + +The final stack SHALL remove `dimos-lcm` Python/message dependencies, `lcm-msgs`, native header downloads, and the Rust raw transport dependency sourced from the external repository. A replacement or extracted raw transport SHALL preserve required notices and remain separate from schema generation. LCM transport itself SHALL remain available. Old message encodings and compatibility readers SHALL be removed; runtime schema-hash enforcement is not required. + +#### Scenario: Clean final build without the old repository +- **WHEN** the supported packages and demo are built and installed in a clean environment where access to the `dimos-lcm` repository is unavailable +- **THEN** the generated-message workflow, both transports, and recording/replay operate successfully +- **AND** manifests, lockfiles, build scripts, and installed dependency inventory contain no active dependency on that repository diff --git a/openspec/changes/replace-lcm-message-encoding/specs/demonstrable-message-delivery/spec.md b/openspec/changes/replace-lcm-message-encoding/specs/demonstrable-message-delivery/spec.md new file mode 100644 index 00000000000..bccd156eb73 --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/specs/demonstrable-message-delivery/spec.md @@ -0,0 +1,32 @@ +## ADDED Requirements + +### Requirement: Deliver dependency-ordered working PR stages + +The change SHALL be delivered as a linear stack of working PRs covering generation, packaging, standalone viewer recordings, runtime integration, actual recording/replay, and final dependency removal in that order. Each PR SHALL depend only on its predecessors. The generation stage SHALL resolve backend conformance and the Rust raw transport removal feasibility before the application cutover proceeds. A stage subdivided for reviewability SHALL retain all acceptance requirements for every resulting PR. + +#### Scenario: Review an intermediate branch +- **WHEN** a reviewer checks out any PR branch and its predecessors +- **THEN** that stage's demonstrated workflow runs without requiring a later PR +- **AND** all preceding stage demos remain runnable + +### Requirement: Every PR includes a human-facing demo and automated tests + +Each PR SHALL include a documented, runnable, hardware-free human demo in addition to automated tests. The demo SHALL show real observable data or behavior, not merely a test-suite pass result. Documentation SHALL include setup, exact commands, expected visible results, teardown, and known limitations. PR review evidence SHALL include a terminal capture or screen recording and the automated test results. + +#### Scenario: An infrastructure stage is submitted +- **WHEN** the packaging PR is ready for review +- **THEN** a reviewer can run a separate consumer application, add a field, rebuild all three languages, and observe that field in exchanged messages +- **AND** the PR includes captured evidence and independent automated package/codec checks + +#### Scenario: Automated tests pass without a demo +- **WHEN** a stage passes its tests but lacks a runnable human-facing demo or its review evidence +- **THEN** that stage is not complete + +### Requirement: Use a cumulative example to demonstrate the user workflow + +Stages SHALL evolve one small example project using a custom message with a standard dependency, synthetic image data, and a moving pose. The demos SHALL progress from a visible three-language file relay to an external consumer, a viewer-ready MCAP, a live blueprint on both transports, actual recording/replay, and a clean final installation without the old repository. + +#### Scenario: Final acceptance +- **WHEN** a reviewer follows the final example from a clean environment +- **THEN** they can define a message, generate and build all three consumers, run them on LCM and Zenoh, record and replay them, and inspect the recording in both viewers +- **AND** generation and ordinary runtime use require neither ROS installation nor a `dimos-lcm` PR or dependency diff --git a/openspec/changes/replace-lcm-message-encoding/specs/message-package-distribution/spec.md b/openspec/changes/replace-lcm-message-encoding/specs/message-package-distribution/spec.md new file mode 100644 index 00000000000..4aacbe252ba --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/specs/message-package-distribution/spec.md @@ -0,0 +1,35 @@ +## ADDED Requirements + +### Requirement: Local and reusable definitions use the same workflow + +The tooling SHALL support application-local schema packages and separately distributed schema packages through the same generator and dependency resolver. Adding a message or field MUST NOT require publication, a DimOS source edit, or an external repository PR. + +#### Scenario: Add a field in a downstream application +- **WHEN** a separate example application adds a field to its custom `.msg` and reruns generation and builds +- **THEN** its Python, C++, and Rust consumers expose and exchange that field without editing DimOS + +### Requirement: Consume artifacts through standard language tooling + +The workflow SHALL produce installable Python wheels/sdists, an exported CMake package, and Rust crates, with the definitions and schema metadata needed by downstream generation and recording. Installed Python schema/type providers SHALL be discoverable through `dimos.messages` entry points. Consumers SHALL install dependencies during environment setup or build; runtime MUST NOT download schemas, install packages, or run code generation. + +#### Scenario: Fresh downstream consumers +- **WHEN** the stage's built artifacts are installed into a clean ROS-free environment +- **THEN** a Python program imports its message package, a C++ program consumes it through CMake, and a Rust program consumes its crate through Cargo +- **AND** all three exchange the same custom message + +#### Scenario: Installed external type discovery +- **WHEN** an installed external message package registers its provider +- **THEN** DimOS can resolve its qualified types and schema metadata without a handwritten built-in registry entry + +### Requirement: Reproduce generation locally and in CI + +CI SHALL run the same pinned generation workflow available locally, produce official build artifacts, and verify deterministic generated source and schema metadata. Generated source SHALL remain outside version control. CI SHALL exercise the existing supported platform build matrix; package contents SHALL include the schema resources and build inputs appropriate to wheels, source distributions, CMake consumers, and crates. + +#### Scenario: Rebuild from packaged inputs +- **WHEN** two clean builds use the same schema inputs and pinned toolchain +- **THEN** their generated sources and schema metadata are identical +- **AND** the resulting packages contain the inputs/outputs required by their documented consumption route + +#### Scenario: Generate without network access after setup +- **WHEN** toolchain dependencies and schema packages are already installed and network access is unavailable +- **THEN** local generation and the three-language example build do not attempt to retrieve message definitions at runtime diff --git a/openspec/changes/replace-lcm-message-encoding/specs/self-describing-message-recordings/spec.md b/openspec/changes/replace-lcm-message-encoding/specs/self-describing-message-recordings/spec.md new file mode 100644 index 00000000000..9bfffec3570 --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/specs/self-describing-message-recordings/spec.md @@ -0,0 +1,40 @@ +## ADDED Requirements + +### Requirement: Record standard CDR and complete embedded schemas + +MCAP recordings SHALL use the ROS2 profile, `cdr` message encoding, and `ros2msg` schemas with qualified type names and the complete transitive dependency definitions. Stored payloads SHALL be the generated encapsulated CDR bytes. Compression SHALL use MCAP chunk compression or a standard compressed-message schema, not a private wrapper around the channel's declared CDR encoding. + +#### Scenario: Custom type with nested standard definitions +- **WHEN** a generated custom message containing a standard header and a nested custom message is recorded +- **THEN** the MCAP embeds the definitions needed to decode the complete message independently of installed message packages +- **AND** the channel's payload matches its declared CDR schema + +### Requirement: Inspect one recording in Foxglove and Rerun + +The demonstration recording SHALL be usable in Foxglove and the repository's pinned Rerun version without installing its custom message package in either viewer. Standard image and pose messages SHALL be visually demonstrated. Custom messages SHALL support inspection of their decoded fields; automatic semantic visualization of every custom type is not required. + +#### Scenario: Same file opened by both viewers +- **WHEN** a reviewer opens the demonstration MCAP containing an image, moving pose, and custom telemetry in each viewer +- **THEN** the image and pose can be visualized and the custom telemetry fields can be inspected using the embedded definitions + +### Requirement: Record arbitrary registered messages without native decoder changes + +The runtime SHALL supply stream schemas to the recorder through its existing startup/configuration path. Recording an externally defined message SHALL NOT require adding handwritten recorder decoding logic or rebuilding the recorder for that message. The recorder SHALL use source timestamps for supported stamped types and reception time for unstamped/unknown timestamp layouts; MCAP log time SHALL represent reception time. + +#### Scenario: Newly generated external telemetry +- **WHEN** an application installs a custom message package and records its stream with an otherwise unchanged recorder +- **THEN** the recorder stores its payload and full schema and viewers can inspect its fields + +#### Scenario: Stamped and unstamped streams +- **WHEN** a recording receives a supported stamped message and an unstamped custom message +- **THEN** their publish times use the source stamp and reception time respectively +- **AND** their log times reflect reception time + +### Requirement: Replay new recordings through typed streams + +DimOS recording/read/replay paths SHALL support the replacement generated-message representation. Replay into typed application consumers SHALL use installed matching message packages and preserve field values and recorded ordering/timing according to the replay API. The change SHALL remove obsolete LCM-backed recording paths rather than providing a legacy migration or fallback reader. + +#### Scenario: Record, stop, and replay the example +- **WHEN** a reviewer records the integrated blueprint, stops its producers, and replays with the matching message packages installed +- **THEN** typed consumers receive the recorded image, pose, and custom telemetry values without an LCM codec +- **AND** the resulting viewer output visibly corresponds to the recorded sequence diff --git a/openspec/changes/replace-lcm-message-encoding/specs/standalone-message-generation/spec.md b/openspec/changes/replace-lcm-message-encoding/specs/standalone-message-generation/spec.md new file mode 100644 index 00000000000..5c6629290bb --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/specs/standalone-message-generation/spec.md @@ -0,0 +1,65 @@ +## ADDED Requirements + +### Requirement: Generate three languages without a ROS installation + +The tooling SHALL provide one documented generation workflow accepting ROS2 `.msg` package roots and emitting Python, C++, and Rust types and encode/decode implementations. Generation and ordinary runtime use MUST NOT require ROS installation, a ROS environment, a DimOS source change, publication, or a `dimos-lcm` PR. Native compilation and standalone build dependencies are permitted. + +#### Scenario: Local custom message with a standard dependency +- **WHEN** an application defines a custom message containing `std_msgs/Header`, a string, a numeric sequence, and a nested application message in an environment without ROS +- **THEN** the workflow generates buildable outputs for all three languages using the bundled standard dependency closure +- **AND** all three outputs expose the declared fields and codec operations + +### Requirement: Resolve pinned definitions deterministically + +The tooling SHALL bundle the required Jazzy standard definitions with immutable upstream revisions and licenses/notices. It SHALL resolve complete transitive dependencies from bundled, local, and installed definitions by qualified name. It SHALL reject conflicting definitions sharing a qualified name, unresolved references, invalid syntax, and recursive value layouts with actionable source diagnostics. + +#### Scenario: Transitive standard dependency +- **WHEN** a custom definition references `sensor_msgs/Image` +- **THEN** resolution includes its `std_msgs/Header` and `builtin_interfaces/Time` dependencies without fetching or installing ROS + +#### Scenario: Conflicting installed and local definitions +- **WHEN** two inputs provide different definitions of the same qualified type +- **THEN** generation fails identifying the type and both sources rather than choosing an override + +#### Scenario: Missing nested type +- **WHEN** a definition references a type absent from the available package roots +- **THEN** generation fails with the referencing definition and missing qualified dependency + +### Requirement: Preserve supported message semantics + +Generated types SHALL preserve the supported ROS2 `.msg` field names, order, types, constants, defaults, nested types, fixed arrays, sequences, and bounds. The initial supported surface SHALL cover these constructs as used by bundled Jazzy definitions. Unsupported constructs SHALL fail explicitly during generation. Service and action definitions are outside this capability. + +#### Scenario: Defaults and bounded fields +- **WHEN** a definition declares defaults, a fixed array, a bounded string, and a bounded sequence +- **THEN** generated types initialize the declared defaults and encode valid values consistently across languages +- **AND** invalid fixed-array lengths or bounds violations are rejected rather than truncated or emitted with a different layout + +### Requirement: Use a common ROS2-compatible CDR wire profile + +Generated codecs SHALL emit encapsulated plain CDR/XCDR1 with little-endian encoding and decode supported little- and big-endian representations. They SHALL reject unsupported representation headers and malformed/truncated messages. The CDR payload MUST NOT contain an LCM fingerprint or custom schema-hash prefix. Conformance SHALL cover all nine Python/C++/Rust encoder-decoder combinations and an independent Jazzy reference in CI. + +#### Scenario: Every language decodes every producer +- **WHEN** each language serializes fixtures containing nested types, empty and nonempty arrays, strings, numeric boundaries, and alignment-sensitive fields +- **THEN** every language recovers the same field values from each producer's bytes +- **AND** emitted bytes match the chosen profile's independent Jazzy reference fixtures + +#### Scenario: Unsupported or incomplete payload +- **WHEN** a decoder receives an unsupported encapsulation or truncated field data +- **THEN** decoding reports an error and does not return a partially decoded message as valid + +### Requirement: Python bindings have safe documented buffer behavior + +Python generated types SHALL use generated native codecs with documented nested-field and sequence mutation behavior. NumPy helpers SHALL provide read-only borrowed views where the layout permits, retaining the storage owner for the view lifetime, and an explicit copy path for mutable processing. Operations that would resize or invalidate borrowed backing storage SHALL be rejected while a view exists. Conversions requiring copies SHALL document that fact. Wire types MUST NOT import geometry or visualization libraries. + +#### Scenario: Image view outlives its Python message variable +- **WHEN** a supported image buffer is exposed as a borrowed NumPy view and the caller releases its message variable +- **THEN** the view retains valid storage and remains read-only for its lifetime +- **AND** requesting a mutable copy produces independent writable storage + +#### Scenario: Nested and sequence mutation +- **WHEN** a caller edits a nested field or sequence through the documented Python API and serializes the message +- **THEN** C++ and Rust decode the edited values rather than values from an unnoticed temporary copy + +#### Scenario: Resize while storage is borrowed +- **WHEN** a caller attempts to resize an exported message buffer while a borrowed view exists +- **THEN** the operation fails explicitly and the existing view remains valid diff --git a/openspec/changes/replace-lcm-message-encoding/tasks.md b/openspec/changes/replace-lcm-message-encoding/tasks.md new file mode 100644 index 00000000000..48c8814d28c --- /dev/null +++ b/openspec/changes/replace-lcm-message-encoding/tasks.md @@ -0,0 +1,66 @@ +## 1. PR 1 — Generate and exchange messages without ROS + +- [ ] 1.1 Inventory message definitions and consumers across Python, C++, Rust, recordings, SHM, WebRTC/browser, live Rerun, and the existing ROS bridge; record required standard/custom types and any working subdivisions of the runtime cutover in design.md. +- [ ] 1.2 Inspect the external Rust raw LCM implementation and license; prove an extraction or maintained-replacement route with native/Python raw-byte and fragmented-payload checks, and record the choice before advancing the stack. +- [ ] 1.3 Pin and vendor the required Jazzy `.msg` dependency closure with immutable upstream revisions, licenses, and notices. +- [ ] 1.4 Implement standalone package resolution and parsing, including qualified names, transitive dependencies, defaults/bounds, conflict rejection, and source diagnostics for unsupported or invalid definitions. +- [ ] 1.5 Validate and pin the C++ generator/Fast CDR pipeline without ROS or DDS runtime requirements; generate buildable types and encapsulated XCDR1 codecs rather than handwritten message layouts. +- [ ] 1.6 Generate pybind11 bindings sharing the C++ codecs, with transport-neutral encode/decode, nested-field/sequence mutation semantics, and type/schema metadata. +- [ ] 1.7 Validate and pin the native Rust generation/CDR backend, emit equivalent types/metadata/codecs, and document any rejected candidates with evidence in design.md. +- [ ] 1.8 Implement and verify read-only image/point-cloud buffer views, explicit mutable copies, owner lifetimes, and rejection of storage-invalidating mutations while views exist; capture representative buffer performance and copying behavior. +- [ ] 1.9 Add all nine language encoder/decoder conformance combinations, endian/alignment cases, defaults, bounds, fixed/dynamic arrays, nested standard/custom messages, malformed inputs, and independent ROS2 Jazzy reference checks in a separate CI job. +- [ ] 1.10 Provide one documented generation entry point and an ignored output directory; demonstrate generation/build/runtime with ROS absent and preinstalled dependencies available offline. +- [ ] 1.11 Create the cumulative example definitions and a runnable `demo_` file relay: Python → C++ → Rust → Python, printing decoded fields and each process's edits; include realistic buffer-view behavior in its terminal demo. +- [ ] 1.12 Add exact demo setup/run/teardown instructions, capture visible output and automated results for PR review, and resolve the stage-1 engineering gates in design.md before accepting PR 1. + +## 2. PR 2 — Package and consume messages outside DimOS + +- [ ] 2.1 Add Python wheel/sdist generation using the existing native-build infrastructure; include schema resources and the inputs needed to reproduce source builds. +- [ ] 2.2 Add an installable/exported CMake message package and a consumable generated Rust crate with schema metadata and dependency declarations. +- [ ] 2.3 Register installed Python schema/type providers through `dimos.messages`; support external packages without editing the built-in message registry. +- [ ] 2.4 Wire the same pinned local generation into CI and release packaging, preserving the supported build matrix; upload review artifacts and publish official packages through the normal release workflow. +- [ ] 2.5 Verify deterministic generated sources/metadata, packaged schema closure, clean wheel/sdist/CMake/Cargo consumers, and absence of generated source from version control. +- [ ] 2.6 Extend the demo into a separate application: install built packages, add a field to a local custom `.msg`, regenerate/build all three consumers, and visibly exchange the new field without changing DimOS or publishing a package. +- [ ] 2.7 Document exact external-project commands and setup-time dependencies, verify no runtime downloading/generation, capture demo evidence, and rerun PR 1's demo and automated checks. + +## 3. PR 3 — Inspect the same MCAP in Foxglove and Rerun + +- [ ] 3.1 Generate complete concatenated `ros2msg` definitions and qualified schema metadata for every demo type, including transitive standard and custom dependencies. +- [ ] 3.2 Add reusable MCAP writing support for the ROS2 profile, `cdr` channels, embedded `ros2msg` schemas, and MCAP chunk compression without private payload wrappers. +- [ ] 3.3 Extend the example with a deterministic synthetic image, moving pose, and custom telemetry producer writing generated CDR directly to one MCAP artifact. +- [ ] 3.4 Add automated checks for schema dependency closure, channel encodings, independently decodable payloads, source/log timestamps, and standard compressed-image representation. +- [ ] 3.5 Open the same artifact in Foxglove and pinned Rerun with the custom message package absent from the viewer environment; demonstrate image/pose visualization and custom-field inspection, recording exact UI steps and screen evidence. +- [ ] 3.6 Publish the demo MCAP as a review artifact, document reproduction and cleanup, and rerun all preceding demos and automated checks. + +## 4. PR 4 — Run DimOS on generated messages and CDR + +- [ ] 4.1 Generate the complete inventory of standard and DimOS custom messages; replace the message protocol and generated-type discovery with the transport-neutral codec and schema contract. +- [ ] 4.2 Extract geometry, timestamp, NumPy/Open3D, and Rerun helpers; update callers to nested ROS2 fields, sec/nanosec timestamps, and distinct TransformStamped/TFMessage representations without compatibility wrappers. +- [ ] 4.3 Update Python typed LCM/Zenoh pub/sub and typed SHM paths to CDR, preserving raw transport and separate Python-object serialization behavior. +- [ ] 4.4 Update C++ and Rust SDK codecs, native examples, and typed worker/module configuration to the generated types; integrate the proven Rust raw transport replacement with preserved provenance. +- [ ] 4.5 Update image and point-cloud producers/consumers to generated fields, proper CompressedImage use, arbitrary PointCloud2 layouts, and explicit conversion helpers. +- [ ] 4.6 Update remaining robot/perception/navigation/tool consumers and existing optional ROS bridge conversions; replace affected repository fixtures rather than retaining LCM fallback decoding. +- [ ] 4.7 Adapt existing recorder/reader and replay consumers minimally to the new message APIs/codecs in this PR so the type cutover does not leave them broken pending PR 5. +- [ ] 4.8 Move live Rerun mappings outside generated types; update browser schema advertisement, CDR decoding, and explicit multiplexed channel/type dispatch without fingerprint probing or runtime hash enforcement. +- [ ] 4.9 Add integration checks for three-language typed streams on both transports, large fragmented LCM messages, helper semantics, browser multiplexing, existing consumer behavior, and live viewer adapters. +- [ ] 4.10 Extend the human demo to a hardware-free Python/C++/Rust blueprint over LCM and then Zenoh; show changing custom fields, live Rerun image/pose updates, and browser decoding; capture terminal and screen evidence. +- [ ] 4.11 Run affected automated checks and all earlier demos; keep any inventory-driven subdivision independently runnable with its own human demo and tests. + +## 5. PR 5 — Record and replay the running system + +- [ ] 5.1 Pass complete generated stream schemas to recorder startup configuration and register MCAP schemas/channels using PR 3's reusable support. +- [ ] 5.2 Support arbitrary installed custom messages without recorder-specific generated decoders or rebuilds; preserve declared schema semantics in recognized-type image/transform processing. +- [ ] 5.3 Complete Python/Rust recorder and reader changes, including new-format SQLite codec paths where applicable, stamped/unstamped timing behavior, and removal of obsolete LCM storage wrappers. +- [ ] 5.4 Complete typed replay with matching installed message packages and verify recorded fields, ordering, and existing replay timing semantics. +- [ ] 5.5 Add end-to-end capture/read/replay checks for standard and external custom messages, schema closure, timestamp behavior, compressed/raw images, and both transport inputs. +- [ ] 5.6 Demonstrate recording the cumulative blueprint, stopping producers, opening its MCAP in both viewers, and replaying through DimOS with visibly matching image/pose/telemetry output. +- [ ] 5.7 Capture the recording and screen/terminal evidence, document exact steps and cleanup, and rerun all preceding demos and automated checks. + +## 6. PR 6 — Remove the external repository dependency completely + +- [ ] 6.1 Remove remaining `dimos-lcm`/`lcm-msgs` dependencies, native header fetches, build/lockfile references, obsolete LCM message codecs, old convenience APIs, and unused generation assets; retain raw LCM transport. +- [ ] 6.2 Remove remaining legacy-format fixtures/readers and update all message-authoring, native-module, transport, viewer, recording, and release documentation to the supported workflow. +- [ ] 6.3 Add a dependency audit and clean build/install check with old repository access unavailable, ensuring no preexisting generated artifacts or dependency caches mask an active dependency. +- [ ] 6.4 Run the supported packaging/build matrix, full affected regression checks, and all cumulative demos against the final installed artifacts. +- [ ] 6.5 Demonstrate the full clean-environment workflow: add a local message, generate/install all three outputs, exchange it on both transports, record/replay it, and inspect the MCAP in both viewers; show the dependency inventory. +- [ ] 6.6 Attach final human demo evidence and automated results, document the intentional API/wire break and deferred features, and verify every PR's acceptance requirements before marking the change implemented. From 4cebee82533df2e3cfe5ef26a6e98e888775f531 Mon Sep 17 00:00:00 2001 From: cc Date: Mon, 21 Sep 2026 10:03:22 -0700 Subject: [PATCH 02/55] feat: generate native CDR messages without ROS --- .../message-codegen-reference.Dockerfile | 10 + .github/workflows/message-codegen.yml | 74 ++ .pre-commit-config.yaml | 2 +- Cargo.lock | 9 + Cargo.toml | 1 + dimos/message_codegen/README.md | 47 + dimos/message_codegen/__init__.py | 0 dimos/message_codegen/_vendor/__init__.py | 0 .../message_codegen/_vendor/rosidl_parser.py | 912 ++++++++++++++++++ .../message_codegen/_vendor/rosidl_parser.pyi | 30 + dimos/message_codegen/cpp.py | 273 ++++++ dimos/message_codegen/definitions.py | 193 ++++ dimos/message_codegen/generate.py | 98 ++ dimos/message_codegen/python.py | 130 +++ dimos/message_codegen/rust.py | 218 +++++ .../builtin_interfaces/msg/Duration.msg | 12 + .../schemas/builtin_interfaces/msg/Time.msg | 11 + .../schemas/builtin_interfaces/package.xml | 29 + .../foxglove_msgs/msg/CompressedVideo.msg | 44 + .../schemas/geometry_msgs/LICENSE | 202 ++++ .../schemas/geometry_msgs/msg/Accel.msg | 3 + .../geometry_msgs/msg/AccelStamped.msg | 3 + .../geometry_msgs/msg/AccelWithCovariance.msg | 9 + .../msg/AccelWithCovarianceStamped.msg | 3 + .../schemas/geometry_msgs/msg/Inertia.msg | 16 + .../geometry_msgs/msg/InertiaStamped.msg | 4 + .../schemas/geometry_msgs/msg/Point.msg | 4 + .../schemas/geometry_msgs/msg/Point32.msg | 11 + .../geometry_msgs/msg/PointStamped.msg | 4 + .../schemas/geometry_msgs/msg/Polygon.msg | 3 + .../geometry_msgs/msg/PolygonInstance.msg | 5 + .../msg/PolygonInstanceStamped.msg | 5 + .../geometry_msgs/msg/PolygonStamped.msg | 4 + .../schemas/geometry_msgs/msg/Pose.msg | 4 + .../schemas/geometry_msgs/msg/Pose2D.msg | 10 + .../schemas/geometry_msgs/msg/PoseArray.msg | 5 + .../schemas/geometry_msgs/msg/PoseStamped.msg | 4 + .../geometry_msgs/msg/PoseWithCovariance.msg | 9 + .../msg/PoseWithCovarianceStamped.msg | 4 + .../schemas/geometry_msgs/msg/Quaternion.msg | 6 + .../geometry_msgs/msg/QuaternionStamped.msg | 4 + .../schemas/geometry_msgs/msg/Transform.msg | 4 + .../geometry_msgs/msg/TransformStamped.msg | 19 + .../schemas/geometry_msgs/msg/Twist.msg | 4 + .../geometry_msgs/msg/TwistStamped.msg | 4 + .../geometry_msgs/msg/TwistWithCovariance.msg | 9 + .../msg/TwistWithCovarianceStamped.msg | 4 + .../schemas/geometry_msgs/msg/Vector3.msg | 9 + .../geometry_msgs/msg/Vector3Stamped.msg | 7 + .../geometry_msgs/msg/VelocityStamped.msg | 8 + .../msg/VelocityWithCovarianceStamped.msg | 17 + .../schemas/geometry_msgs/msg/Wrench.msg | 4 + .../geometry_msgs/msg/WrenchStamped.msg | 4 + .../schemas/geometry_msgs/package.xml | 32 + .../schemas/licenses/foxglove_schemas/LICENSE | 21 + .../ros-perception_vision_msgs/LICENSE | 201 ++++ .../schemas/licenses/ros2_geometry2/LICENSE | 29 + .../licenses/ros2_rcl_interfaces/LICENSE | 202 ++++ .../schemas/licenses/ros2_rosidl/LICENSE | 202 ++++ .../message_codegen/schemas/nav_msgs/LICENSE | 202 ++++ .../schemas/nav_msgs/msg/Goals.msg | 12 + .../schemas/nav_msgs/msg/GridCells.msg | 12 + .../schemas/nav_msgs/msg/MapMetaData.msg | 17 + .../schemas/nav_msgs/msg/OccupancyGrid.msg | 13 + .../schemas/nav_msgs/msg/Odometry.msg | 15 + .../schemas/nav_msgs/msg/Path.msg | 7 + .../schemas/nav_msgs/msg/Trajectory.msg | 7 + .../schemas/nav_msgs/msg/TrajectoryPoint.msg | 16 + .../schemas/nav_msgs/package.xml | 34 + .../schemas/rosidl_adapter/package.xml | 36 + .../schemas/sensor_msgs/LICENSE | 202 ++++ .../schemas/sensor_msgs/msg/BatteryState.msg | 54 ++ .../schemas/sensor_msgs/msg/CameraInfo.msg | 131 +++ .../sensor_msgs/msg/ChannelFloat32.msg | 24 + .../sensor_msgs/msg/CompressedImage.msg | 41 + .../schemas/sensor_msgs/msg/FluidPressure.msg | 12 + .../schemas/sensor_msgs/msg/Illuminance.msg | 20 + .../schemas/sensor_msgs/msg/Image.msg | 26 + .../schemas/sensor_msgs/msg/Imu.msg | 24 + .../schemas/sensor_msgs/msg/JointState.msg | 25 + .../schemas/sensor_msgs/msg/Joy.msg | 10 + .../schemas/sensor_msgs/msg/JoyFeedback.msg | 14 + .../sensor_msgs/msg/JoyFeedbackArray.msg | 2 + .../schemas/sensor_msgs/msg/LaserEcho.msg | 5 + .../schemas/sensor_msgs/msg/LaserScan.msg | 30 + .../schemas/sensor_msgs/msg/MagneticField.msg | 21 + .../sensor_msgs/msg/MultiDOFJointState.msg | 26 + .../sensor_msgs/msg/MultiEchoLaserScan.msg | 32 + .../schemas/sensor_msgs/msg/NavSatFix.msg | 45 + .../schemas/sensor_msgs/msg/NavSatStatus.msg | 24 + .../schemas/sensor_msgs/msg/PointCloud.msg | 17 + .../schemas/sensor_msgs/msg/PointCloud2.msg | 26 + .../schemas/sensor_msgs/msg/PointField.msg | 16 + .../schemas/sensor_msgs/msg/Range.msg | 42 + .../sensor_msgs/msg/RegionOfInterest.msg | 19 + .../sensor_msgs/msg/RelativeHumidity.msg | 13 + .../schemas/sensor_msgs/msg/Temperature.msg | 8 + .../schemas/sensor_msgs/msg/TimeReference.msg | 7 + .../schemas/sensor_msgs/package.xml | 37 + .../schemas/shape_msgs/LICENSE | 202 ++++ .../schemas/shape_msgs/msg/Mesh.msg | 7 + .../schemas/shape_msgs/msg/MeshTriangle.msg | 3 + .../schemas/shape_msgs/msg/Plane.msg | 7 + .../schemas/shape_msgs/msg/SolidPrimitive.msg | 50 + .../schemas/shape_msgs/package.xml | 31 + .../message_codegen/schemas/std_msgs/LICENSE | 202 ++++ .../schemas/std_msgs/msg/Bool.msg | 6 + .../schemas/std_msgs/msg/Byte.msg | 6 + .../schemas/std_msgs/msg/ByteMultiArray.msg | 10 + .../schemas/std_msgs/msg/Char.msg | 6 + .../schemas/std_msgs/msg/ColorRGBA.msg | 4 + .../schemas/std_msgs/msg/Empty.msg | 0 .../schemas/std_msgs/msg/Float32.msg | 6 + .../std_msgs/msg/Float32MultiArray.msg | 10 + .../schemas/std_msgs/msg/Float64.msg | 6 + .../std_msgs/msg/Float64MultiArray.msg | 10 + .../schemas/std_msgs/msg/Header.msg | 9 + .../schemas/std_msgs/msg/Int16.msg | 6 + .../schemas/std_msgs/msg/Int16MultiArray.msg | 10 + .../schemas/std_msgs/msg/Int32.msg | 6 + .../schemas/std_msgs/msg/Int32MultiArray.msg | 10 + .../schemas/std_msgs/msg/Int64.msg | 6 + .../schemas/std_msgs/msg/Int64MultiArray.msg | 10 + .../schemas/std_msgs/msg/Int8.msg | 6 + .../schemas/std_msgs/msg/Int8MultiArray.msg | 10 + .../std_msgs/msg/MultiArrayDimension.msg | 8 + .../schemas/std_msgs/msg/MultiArrayLayout.msg | 31 + .../schemas/std_msgs/msg/String.msg | 6 + .../schemas/std_msgs/msg/UInt16.msg | 6 + .../schemas/std_msgs/msg/UInt16MultiArray.msg | 10 + .../schemas/std_msgs/msg/UInt32.msg | 6 + .../schemas/std_msgs/msg/UInt32MultiArray.msg | 10 + .../schemas/std_msgs/msg/UInt64.msg | 6 + .../schemas/std_msgs/msg/UInt64MultiArray.msg | 10 + .../schemas/std_msgs/msg/UInt8.msg | 6 + .../schemas/std_msgs/msg/UInt8MultiArray.msg | 10 + .../schemas/std_msgs/package.xml | 31 + .../schemas/tf2_msgs/msg/TF2Error.msg | 10 + .../schemas/tf2_msgs/msg/TFMessage.msg | 1 + .../schemas/tf2_msgs/package.xml | 36 + .../schemas/trajectory_msgs/LICENSE | 202 ++++ .../trajectory_msgs/msg/JointTrajectory.msg | 11 + .../msg/JointTrajectoryPoint.msg | 26 + .../msg/MultiDOFJointTrajectory.msg | 10 + .../msg/MultiDOFJointTrajectoryPoint.msg | 11 + .../schemas/trajectory_msgs/package.xml | 34 + .../schemas/vision_msgs/msg/BoundingBox2D.msg | 13 + .../vision_msgs/msg/BoundingBox2DArray.msg | 2 + .../schemas/vision_msgs/msg/BoundingBox3D.msg | 10 + .../vision_msgs/msg/BoundingBox3DArray.msg | 2 + .../vision_msgs/msg/Classification.msg | 17 + .../schemas/vision_msgs/msg/Detection2D.msg | 23 + .../vision_msgs/msg/Detection2DArray.msg | 7 + .../schemas/vision_msgs/msg/Detection3D.msg | 23 + .../vision_msgs/msg/Detection3DArray.msg | 7 + .../schemas/vision_msgs/msg/LabelInfo.msg | 25 + .../vision_msgs/msg/ObjectHypothesis.msg | 12 + .../msg/ObjectHypothesisWithPose.msg | 16 + .../schemas/vision_msgs/msg/Point2D.msg | 5 + .../schemas/vision_msgs/msg/Pose2D.msg | 4 + .../schemas/vision_msgs/msg/VisionClass.msg | 12 + .../schemas/vision_msgs/msg/VisionInfo.msg | 40 + .../schemas/vision_msgs/package.xml | 37 + .../schemas/visualization_msgs/LICENSE | 202 ++++ .../visualization_msgs/msg/ImageMarker.msg | 36 + .../msg/InteractiveMarker.msg | 26 + .../msg/InteractiveMarkerControl.msg | 77 ++ .../msg/InteractiveMarkerFeedback.msg | 42 + .../msg/InteractiveMarkerInit.msg | 14 + .../msg/InteractiveMarkerPose.msg | 10 + .../msg/InteractiveMarkerUpdate.msg | 32 + .../schemas/visualization_msgs/msg/Marker.msg | 81 ++ .../visualization_msgs/msg/MarkerArray.msg | 1 + .../visualization_msgs/msg/MenuEntry.msg | 54 ++ .../visualization_msgs/msg/MeshFile.msg | 8 + .../visualization_msgs/msg/UVCoordinate.msg | 4 + .../schemas/visualization_msgs/package.xml | 35 + dimos/message_codegen/sources.json | 201 ++++ dimos/message_codegen/templates/codec.rs | 56 ++ dimos/message_codegen/templates/dimos_cdr.hpp | 71 ++ .../templates/dimos_python.hpp | 151 +++ dimos/message_codegen/test_definitions.py | 136 +++ dimos/message_codegen/test_native.py | 183 ++++ examples/message-codegen/EVIDENCE.md | 78 ++ examples/message-codegen/README.md | 119 +++ examples/message-codegen/demo_buffers.py | 88 ++ examples/message-codegen/demo_conformance.py | 123 +++ .../message-codegen/demo_msgs/CMakeLists.txt | 14 + .../demo_msgs/msg/ImageEnvelope.msg | 2 + .../message-codegen/demo_msgs/msg/Reading.msg | 4 + .../demo_msgs/msg/Telemetry.msg | 9 + .../message-codegen/demo_msgs/package.xml | 16 + examples/message-codegen/demo_relay.py | 66 ++ .../message-codegen/demo_ros_reference.py | 56 ++ examples/message-codegen/demo_transport.py | 66 ++ examples/message-codegen/relay.cpp | 52 + examples/message-codegen/relay.rs | 43 + native/rust/dimos-lcm-transport/Cargo.toml | 11 + native/rust/dimos-lcm-transport/README.md | 27 + .../dimos-lcm-transport/examples/interop.rs | 46 + native/rust/dimos-lcm-transport/src/lib.rs | 41 + .../rust/dimos-lcm-transport/src/transport.rs | 395 ++++++++ .../replace-lcm-message-encoding/design.md | 33 +- .../replace-lcm-message-encoding/tasks.md | 24 +- pyproject.toml | 1 + scripts/setup_message_codegen.sh | 17 + scripts/test_message_codegen.sh | 30 + scripts/vendor_message_definitions.py | 97 ++ 208 files changed, 8756 insertions(+), 16 deletions(-) create mode 100644 .github/docker/message-codegen-reference.Dockerfile create mode 100644 .github/workflows/message-codegen.yml create mode 100644 dimos/message_codegen/README.md create mode 100644 dimos/message_codegen/__init__.py create mode 100644 dimos/message_codegen/_vendor/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl_parser.py create mode 100644 dimos/message_codegen/_vendor/rosidl_parser.pyi create mode 100644 dimos/message_codegen/cpp.py create mode 100644 dimos/message_codegen/definitions.py create mode 100644 dimos/message_codegen/generate.py create mode 100644 dimos/message_codegen/python.py create mode 100644 dimos/message_codegen/rust.py create mode 100644 dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg create mode 100644 dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg create mode 100644 dimos/message_codegen/schemas/builtin_interfaces/package.xml create mode 100644 dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg create mode 100644 dimos/message_codegen/schemas/geometry_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE create mode 100644 dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE create mode 100644 dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE create mode 100644 dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE create mode 100644 dimos/message_codegen/schemas/nav_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Path.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg create mode 100644 dimos/message_codegen/schemas/nav_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/rosidl_adapter/package.xml create mode 100644 dimos/message_codegen/schemas/sensor_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg create mode 100644 dimos/message_codegen/schemas/sensor_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/shape_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg create mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg create mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg create mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg create mode 100644 dimos/message_codegen/schemas/shape_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/std_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Bool.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Byte.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Char.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Empty.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float32.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float64.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Header.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int16.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int32.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int64.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int8.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/String.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg create mode 100644 dimos/message_codegen/schemas/std_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg create mode 100644 dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg create mode 100644 dimos/message_codegen/schemas/tf2_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/trajectory_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg create mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg create mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg create mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg create mode 100644 dimos/message_codegen/schemas/trajectory_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg create mode 100644 dimos/message_codegen/schemas/vision_msgs/package.xml create mode 100644 dimos/message_codegen/schemas/visualization_msgs/LICENSE create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg create mode 100644 dimos/message_codegen/schemas/visualization_msgs/package.xml create mode 100644 dimos/message_codegen/sources.json create mode 100644 dimos/message_codegen/templates/codec.rs create mode 100644 dimos/message_codegen/templates/dimos_cdr.hpp create mode 100644 dimos/message_codegen/templates/dimos_python.hpp create mode 100644 dimos/message_codegen/test_definitions.py create mode 100644 dimos/message_codegen/test_native.py create mode 100644 examples/message-codegen/EVIDENCE.md create mode 100644 examples/message-codegen/README.md create mode 100644 examples/message-codegen/demo_buffers.py create mode 100644 examples/message-codegen/demo_conformance.py create mode 100644 examples/message-codegen/demo_msgs/CMakeLists.txt create mode 100644 examples/message-codegen/demo_msgs/msg/ImageEnvelope.msg create mode 100644 examples/message-codegen/demo_msgs/msg/Reading.msg create mode 100644 examples/message-codegen/demo_msgs/msg/Telemetry.msg create mode 100644 examples/message-codegen/demo_msgs/package.xml create mode 100644 examples/message-codegen/demo_relay.py create mode 100644 examples/message-codegen/demo_ros_reference.py create mode 100644 examples/message-codegen/demo_transport.py create mode 100644 examples/message-codegen/relay.cpp create mode 100644 examples/message-codegen/relay.rs create mode 100644 native/rust/dimos-lcm-transport/Cargo.toml create mode 100644 native/rust/dimos-lcm-transport/README.md create mode 100644 native/rust/dimos-lcm-transport/examples/interop.rs create mode 100644 native/rust/dimos-lcm-transport/src/lib.rs create mode 100644 native/rust/dimos-lcm-transport/src/transport.rs create mode 100644 scripts/setup_message_codegen.sh create mode 100644 scripts/test_message_codegen.sh create mode 100644 scripts/vendor_message_definitions.py diff --git a/.github/docker/message-codegen-reference.Dockerfile b/.github/docker/message-codegen-reference.Dockerfile new file mode 100644 index 00000000000..69770075d64 --- /dev/null +++ b/.github/docker/message-codegen-reference.Dockerfile @@ -0,0 +1,10 @@ +FROM ros:jazzy-ros-base + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential cmake python3-colcon-common-extensions \ + ros-jazzy-common-interfaces ros-jazzy-rosidl-default-generators \ + && rm -rf /var/lib/apt/lists/* + +# This image is an independent conformance oracle. DimOS builds and users do not +# depend on it or install ROS to generate or use messages. +ENTRYPOINT ["/bin/bash", "-c"] diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml new file mode 100644 index 00000000000..59085c86b28 --- /dev/null +++ b/.github/workflows/message-codegen.yml @@ -0,0 +1,74 @@ +name: message-codegen + +on: + pull_request: + paths: + - dimos/message_codegen/** + - examples/message-codegen/** + - native/rust/dimos-lcm-transport/** + - scripts/*message*codegen* + - scripts/vendor_message_definitions.py + - .github/workflows/message-codegen.yml + - .github/docker/message-codegen-reference.Dockerfile + - Cargo.toml + - Cargo.lock + workflow_dispatch: + +permissions: + contents: read + +jobs: + standalone: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v10.0.1 + - uses: dtolnay/rust-toolchain@stable + - name: Set up a ROS-free Python environment + run: | + test ! -d /opt/ros + uv venv .venv --python 3.12 + uv pip install --python .venv/bin/python pybind11==3.0.1 rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env lcm-dimos-fork + .venv/bin/python -c "import importlib.util; assert importlib.util.find_spec('rclpy') is None" + - name: Build the pinned standalone CDR library + run: bash scripts/setup_message_codegen.sh + - name: Generate, build, test, and demonstrate all three languages + run: bash scripts/test_message_codegen.sh + - name: Retain executable demo evidence + if: always() + uses: actions/upload-artifact@v7 + with: + name: message-codegen-evidence + path: build/message-codegen/demo/evidence/ + if-no-files-found: error + + jazzy-reference: + needs: standalone + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/download-artifact@v8 + with: + name: message-codegen-evidence + path: build/message-codegen/demo/evidence/ + - name: Build independent ROS2 reference environment + run: docker build -f .github/docker/message-codegen-reference.Dockerfile -t dimos-cdr-jazzy-reference .github/docker + - name: Compare native payloads with independently generated ROS2 types + run: | + docker run --rm \ + -v "$PWD:/source:ro" \ + -v "$PWD/build/message-codegen/demo:/demo" \ + dimos-cdr-jazzy-reference ' + set -e + source /opt/ros/jazzy/setup.bash + mkdir -p /tmp/reference/src + cp -r /source/examples/message-codegen/demo_msgs /tmp/reference/src/ + cd /tmp/reference + colcon build --packages-select demo_msgs --event-handlers console_direct+ + source install/setup.bash + python3 /source/examples/message-codegen/demo_ros_reference.py --build /demo + ' | tee build/message-codegen/demo/evidence/jazzy-reference.txt + - uses: actions/upload-artifact@v7 + with: + name: message-codegen-jazzy-reference + path: build/message-codegen/demo/evidence/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6e117d5d33c..5f40a4ee635 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ default_stages: [pre-commit] default_install_hook_types: [pre-commit, commit-msg] -exclude: (dimos/models/.*)|(deprecated) +exclude: (dimos/models/.*)|(deprecated)|(^dimos/message_codegen/(_vendor|schemas)/) repos: - repo: https://github.com/Lucas-C/pre-commit-hooks diff --git a/Cargo.lock b/Cargo.lock index 5b05f816169..36eba2f6905 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,6 +657,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "dimos-lcm-transport" +version = "0.1.0" +dependencies = [ + "byteorder", + "socket2 0.5.10", + "tokio", +] + [[package]] name = "dimos-livox" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 33236ae92da..da1f355be5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "dimos/experimental/memory/rust", "native/rust/dimos-module", "native/rust/dimos-module-macros", + "native/rust/dimos-lcm-transport", "dimos/mapping/ray_tracing/rust", "dimos/mapping/ray_tracing/rust/py", "dimos/navigation/global_planner/mls_planner/rust", diff --git a/dimos/message_codegen/README.md b/dimos/message_codegen/README.md new file mode 100644 index 00000000000..36d85ec18fe --- /dev/null +++ b/dimos/message_codegen/README.md @@ -0,0 +1,47 @@ +# Standalone ROS2 message generation + +This package reads ROS2 `.msg` files without importing or installing ROS. A pinned +upstream `rosidl_adapter` parser validates syntax. DimOS resolves package names and +dependencies, then emits C++ value types and Fast CDR customizations, Python +bindings to those types, and native Rust types using Serde and `re_cdr`. + +```bash +python -m dimos.message_codegen.generate \ + --package-root examples/message-codegen \ + --type demo_msgs/msg/Telemetry \ + --output build/message-codegen/demo +``` + +The output contains `cpp/`, `rust/`, and `schemas.json`. Definitions are resolved +before output is written. Repeat `--package-root` and `--type` for multiple inputs; +omitting `--type` generates all available definitions. The output belongs in an +ignored build directory. Generation never downloads dependencies. + +Python and C++ use Fast CDR 2.4.0; Python bindings use pybind11 3.0.1. Rust uses +`re_cdr` 0.1.0 and `serde-big-array` 0.5.1. The current generator explicitly rejects +`wstring` because the selected Rust backend has no matching wide-string Serde +representation. No bundled definition uses it. Service/action generation is out +of scope. + +The C++ generator emits declarations, defaults, validation, and library calls; +Fast CDR owns sizing, alignment, strings, sequences, primitive representation, +and byte order. The Rust backend delegates those operations to `re_cdr`. Both +emit plain CDR/XCDR1 with its standard four-byte encapsulation. + +## Upstream sources and licenses + +`sources.json` records immutable revisions and SHA-256 hashes for the vendored +files. `schemas/*/package.xml` retains upstream authorship and declared licenses. +`schemas/licenses/` contains upstream license texts, including the Apache 2.0 +license shared by the standard interface packages and parser. The parser's +original copyright header is preserved. `rosidl_parser.pyi` is DimOS's type stub; +the upstream implementation remains unmodified. + +To refresh the pinned inputs intentionally, edit the revisions in +`scripts/vendor_message_definitions.py`, then run that maintenance command with +`requests` installed. Review the source diff and update the conformance evidence. +Applications and builds never run the maintenance downloader. + +This work is being delivered through the `replace-lcm-message-encoding` OpenSpec +change. The generated pipeline is under development; the old runtime message APIs +have not yet been replaced. diff --git a/dimos/message_codegen/__init__.py b/dimos/message_codegen/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dimos/message_codegen/_vendor/__init__.py b/dimos/message_codegen/_vendor/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dimos/message_codegen/_vendor/rosidl_parser.py b/dimos/message_codegen/_vendor/rosidl_parser.py new file mode 100644 index 00000000000..836a3b7519f --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl_parser.py @@ -0,0 +1,912 @@ +# Copyright 2014-2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import re +import sys +import textwrap + +PACKAGE_NAME_MESSAGE_TYPE_SEPARATOR = '/' +COMMENT_DELIMITER = '#' +CONSTANT_SEPARATOR = '=' +ARRAY_UPPER_BOUND_TOKEN = '<=' +STRING_UPPER_BOUND_TOKEN = '<=' + +SERVICE_REQUEST_RESPONSE_SEPARATOR = '---' +SERVICE_REQUEST_MESSAGE_SUFFIX = '_Request' +SERVICE_RESPONSE_MESSAGE_SUFFIX = '_Response' +SERVICE_EVENT_MESSAGE_SUFFIX = '_Event' + +ACTION_REQUEST_RESPONSE_SEPARATOR = '---' +ACTION_GOAL_SUFFIX = '_Goal' +ACTION_RESULT_SUFFIX = '_Result' +ACTION_FEEDBACK_SUFFIX = '_Feedback' + +ACTION_GOAL_SERVICE_SUFFIX = '_Goal' +ACTION_RESULT_SERVICE_SUFFIX = '_Result' +ACTION_FEEDBACK_MESSAGE_SUFFIX = '_Feedback' + +PRIMITIVE_TYPES = [ + 'bool', + 'byte', + 'char', + # TODO reconsider wchar + 'float32', + 'float64', + 'int8', + 'uint8', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'int64', + 'uint64', + 'string', + 'wstring', + # TODO duration and time + 'duration', # for compatibility only + 'time', # for compatibility only +] + +VALID_PACKAGE_NAME_PATTERN = re.compile( + '^' + '(?!.*__)' # no consecutive underscores + '(?!.*_$)' # no underscore at the end + '[a-z]' # first character must be alpha + '[a-z0-9_]*' # followed by alpha, numeric, and underscore + '$') +VALID_FIELD_NAME_PATTERN = VALID_PACKAGE_NAME_PATTERN +# relaxed patterns used for compatibility with ROS 1 messages +# VALID_FIELD_NAME_PATTERN = re.compile('^[A-Za-z][A-Za-z0-9_]*$') +VALID_MESSAGE_NAME_PATTERN = re.compile('^[A-Z][A-Za-z0-9]*$') +# relaxed patterns used for compatibility with ROS 1 messages +# VALID_MESSAGE_NAME_PATTERN = re.compile('^[A-Za-z][A-Za-z0-9]*$') +VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z]([A-Z0-9_]?[A-Z0-9]+)*$') + + +class InvalidSpecification(Exception): + pass + + +class InvalidActionSpecification(InvalidSpecification): + pass + + +class InvalidServiceSpecification(InvalidSpecification): + pass + + +class InvalidResourceName(InvalidSpecification): + pass + + +class InvalidFieldDefinition(InvalidSpecification): + pass + + +class UnknownMessageType(InvalidSpecification): + pass + + +class InvalidValue(Exception): + + def __init__(self, type_, value_string, message_suffix=None): + message = "value '%s' can not be converted to type '%s'" % \ + (value_string, type_) + if message_suffix is not None: + message += ': %s' % message_suffix + super(InvalidValue, self).__init__(message) + + +def is_valid_package_name(name): + try: + m = VALID_PACKAGE_NAME_PATTERN.match(name) + except TypeError: + raise InvalidResourceName(name) + return m is not None and m.group(0) == name + + +def is_valid_field_name(name): + try: + m = VALID_FIELD_NAME_PATTERN.match(name) + except TypeError: + raise InvalidResourceName(name) + return m is not None and m.group(0) == name + + +def is_valid_message_name(name): + try: + prefix = 'Sample_' + if name.startswith(prefix): + name = name[len(prefix):] + suffixes = [ + SERVICE_REQUEST_MESSAGE_SUFFIX, + SERVICE_RESPONSE_MESSAGE_SUFFIX, + ACTION_GOAL_SERVICE_SUFFIX, + ACTION_RESULT_SERVICE_SUFFIX, + ACTION_FEEDBACK_MESSAGE_SUFFIX, + ] + for suffix in suffixes: + if name.endswith(suffix): + name = name[:-len(suffix)] + m = VALID_MESSAGE_NAME_PATTERN.match(name) + except (AttributeError, TypeError): + raise InvalidResourceName(name) + return m is not None and m.group(0) == name + + +def is_valid_constant_name(name): + try: + m = VALID_CONSTANT_NAME_PATTERN.match(name) + except TypeError: + raise InvalidResourceName(name) + return m is not None and m.group(0) == name + + +class BaseType: + + __slots__ = ['pkg_name', 'type', 'string_upper_bound'] + + def __init__(self, type_string, context_package_name=None): + # check for primitive types + if type_string in PRIMITIVE_TYPES: + self.pkg_name = None + self.type = type_string + self.string_upper_bound = None + + elif ( + type_string.startswith('string%s' % STRING_UPPER_BOUND_TOKEN) or + type_string.startswith('wstring%s' % STRING_UPPER_BOUND_TOKEN) + ): + self.pkg_name = None + self.type = type_string.split(STRING_UPPER_BOUND_TOKEN, 1)[0] + upper_bound_string = type_string[len(self.type) + + len(STRING_UPPER_BOUND_TOKEN):] + + ex = TypeError(("the upper bound of the string type '%s' must " + + 'be a valid integer value > 0') % type_string) + try: + self.string_upper_bound = int(upper_bound_string) + except ValueError: + raise ex + if self.string_upper_bound <= 0: + raise ex + + else: + # split non-primitive type information + parts = type_string.split(PACKAGE_NAME_MESSAGE_TYPE_SEPARATOR) + if not (len(parts) == 2 or + (len(parts) == 1 and context_package_name is not None)): + raise InvalidResourceName(type_string) + + if len(parts) == 2: + # either the type string contains the package name + self.pkg_name = parts[0] + self.type = parts[1] + else: + # or the package name is provided by context + self.pkg_name = context_package_name + self.type = type_string + if not is_valid_package_name(self.pkg_name): + raise InvalidResourceName( + "'{}' is an invalid package name. It should have the pattern '{}'".format( + self.pkg_name, VALID_PACKAGE_NAME_PATTERN.pattern)) + if not is_valid_message_name(self.type): + raise InvalidResourceName( + "'{}' is an invalid message name. It should have the pattern '{}'".format( + self.type, VALID_MESSAGE_NAME_PATTERN.pattern)) + + self.string_upper_bound = None + + def is_primitive_type(self): + return self.pkg_name is None + + def __eq__(self, other): + if other is None or not isinstance(other, BaseType): + return False + return self.pkg_name == other.pkg_name and \ + self.type == other.type and \ + self.string_upper_bound == other.string_upper_bound + + def __hash__(self): + return hash(str(self)) + + def __str__(self): + if self.pkg_name is not None: + return '%s/%s' % (self.pkg_name, self.type) + + s = self.type + if self.string_upper_bound: + s += '%s%u' % \ + (STRING_UPPER_BOUND_TOKEN, self.string_upper_bound) + return s + + +class Type(BaseType): + + __slots__ = ['is_array', 'array_size', 'is_upper_bound'] + + def __init__(self, type_string, context_package_name=None): + # check for array brackets + self.is_array = type_string[-1] == ']' + + self.array_size = None + self.is_upper_bound = False + if self.is_array: + try: + index = type_string.rindex('[') + except ValueError: + raise TypeError("the type ends with ']' but does not " + + "contain a '['" % type_string) + array_size_string = type_string[index + 1:-1] + # get array limit + if array_size_string != '': + + # check if the limit is an upper bound + self.is_upper_bound = array_size_string.startswith( + ARRAY_UPPER_BOUND_TOKEN) + if self.is_upper_bound: + array_size_string = array_size_string[ + len(ARRAY_UPPER_BOUND_TOKEN):] + + ex = TypeError(( + "the size of array type '%s' must be a valid integer " + + "value > 0 optionally prefixed with '%s' if it is only " + + 'an upper bound') % + (ARRAY_UPPER_BOUND_TOKEN, type_string)) + try: + self.array_size = int(array_size_string) + except ValueError: + raise ex + # check valid range + if self.array_size <= 0: + raise ex + + type_string = type_string[:index] + + super(Type, self).__init__( + type_string, + context_package_name=context_package_name) + + def is_dynamic_array(self): + return self.is_array and (not self.array_size or self.is_upper_bound) + + def is_fixed_size_array(self): + return self.is_array and self.array_size and not self.is_upper_bound + + def __eq__(self, other): + if other is None or not isinstance(other, Type): + return False + return super(Type, self).__eq__(other) and \ + self.is_array == other.is_array and \ + self.array_size == other.array_size and \ + self.is_upper_bound == other.is_upper_bound + + def __hash__(self): + return hash(str(self)) + + def __str__(self): + s = super(Type, self).__str__() + if self.is_array: + s += '[' + if self.is_upper_bound: + s += ARRAY_UPPER_BOUND_TOKEN + if self.array_size is not None: + s += '%u' % self.array_size + s += ']' + return s + + +class Constant: + + __slots__ = ['type', 'name', 'value', 'annotations'] + + def __init__(self, primitive_type, name, value_string): + if primitive_type not in PRIMITIVE_TYPES: + raise TypeError("the constant type '%s' must be a primitive type" % + primitive_type) + self.type = primitive_type + if not is_valid_constant_name(name): + raise NameError( + "'{}' is an invalid constant name. It should have the pattern '{}'".format( + name, VALID_CONSTANT_NAME_PATTERN.pattern)) + self.name = name + if value_string is None: + raise ValueError("the constant value must not be 'None'") + + self.value = parse_primitive_value_string( + Type(primitive_type), value_string) + + self.annotations = {} + + def __eq__(self, other): + if other is None or not isinstance(other, Constant): + return False + return self.type == other.type and \ + self.name == other.name and \ + self.value == other.value + + def __str__(self): + value = self.value + if self.type in ('string', 'wstring'): + value = "'%s'" % value + return '%s %s=%s' % (self.type, self.name, value) + + +class Field: + + def __init__(self, type_, name, default_value_string=None): + if not isinstance(type_, Type): + raise TypeError( + "the field type '%s' must be a 'Type' instance" % type_) + self.type = type_ + if not is_valid_field_name(name): + raise NameError( + "'{}' is an invalid field name. It should have the pattern '{}'".format( + name, VALID_FIELD_NAME_PATTERN.pattern)) + self.name = name + if default_value_string is None: + self.default_value = None + else: + self.default_value = parse_value_string( + type_, default_value_string) + + self.annotations = {} + + def __eq__(self, other): + if other is None or not isinstance(other, Field): + return False + else: + return self.type == other.type and \ + self.name == other.name and \ + self.default_value == other.default_value + + def __str__(self): + s = '%s %s' % (str(self.type), self.name) + if self.default_value is not None: + if self.type.is_primitive_type() and not self.type.is_array and \ + self.type.type in ('string', 'wstring'): + s += " '%s'" % self.default_value + else: + s += ' %s' % self.default_value + return s + + +class MessageSpecification: + + def __init__(self, pkg_name, msg_name, fields, constants): + self.base_type = BaseType( + pkg_name + PACKAGE_NAME_MESSAGE_TYPE_SEPARATOR + msg_name) + self.msg_name = msg_name + self.annotations = {} + + self.fields = [] + for index, field in enumerate(fields): + if not isinstance(field, Field): + raise TypeError("field %u must be a 'Field' instance" % index) + self.fields.append(field) + # ensure that there are no duplicate field names + field_names = [f.name for f in self.fields] + duplicate_field_names = {n for n in field_names + if field_names.count(n) > 1} + if duplicate_field_names: + raise ValueError( + 'the fields iterable contains duplicate names: %s' % + ', '.join(sorted(duplicate_field_names))) + + self.constants = [] + for index, constant in enumerate(constants): + if not isinstance(constant, Constant): + raise TypeError("constant %u must be a 'Constant' instance" % + index) + self.constants.append(constant) + # ensure that there are no duplicate constant names + constant_names = [c.name for c in self.constants] + duplicate_constant_names = {n for n in constant_names + if constant_names.count(n) > 1} + if duplicate_constant_names: + raise ValueError( + 'the constants iterable contains duplicate names: %s' % + ', '.join(sorted(duplicate_constant_names))) + + def __eq__(self, other): + if not other or not isinstance(other, MessageSpecification): + return False + return self.base_type == other.base_type and \ + len(self.fields) == len(other.fields) and \ + self.fields == other.fields and \ + len(self.constants) == len(other.constants) and \ + self.constants == other.constants + + def __str__(self): + """Output an equivalent .msg IDL string.""" + output = ['# ', str(self.base_type), '\n'] + for constant in self.constants: + output.extend((str(constant), '\n')) + for field in self.fields: + output.extend((str(field), '\n')) + # Get rid of last newline + del output[-1] + return ''.join(output) + + +def parse_message_file(pkg_name, interface_filename): + basename = os.path.basename(interface_filename) + msg_name = os.path.splitext(basename)[0] + with open(interface_filename, 'r', encoding='utf-8') as h: + return parse_message_string( + pkg_name, msg_name, h.read()) + + +def extract_file_level_comments(message_string): + lines = message_string.splitlines() + index = next( + (i for i, v in enumerate(lines) if not v.startswith(COMMENT_DELIMITER)), -1) + if index != -1: + file_level_comments = lines[:index] + file_content = lines[index:] + else: + file_level_comments = lines[:] + file_content = [] + file_level_comments = [line.lstrip(COMMENT_DELIMITER) for line in file_level_comments] + return file_level_comments, file_content + + +def parse_message_string(pkg_name, msg_name, message_string): + fields = [] + constants = [] + last_element = None # either a field or a constant + # replace tabs with spaces + message_string = message_string.replace('\t', ' ') + + current_comments = [] + message_comments, lines = extract_file_level_comments(message_string) + for line in lines: + line = line.rstrip() + + # ignore empty lines + if not line: + # file-level comments stop at the first empty line + continue + + index = line.find(COMMENT_DELIMITER) + + # comment + comment = None + if index >= 0: + comment = line[index:].lstrip(COMMENT_DELIMITER) + line = line[:index] + + if comment is not None: + if line and not line.strip(): + # indented comment line + # append to previous field / constant if available or ignore + if last_element is not None: + comment_lines = last_element.annotations.setdefault( + 'comment', []) + comment_lines.append(comment) + continue + # collect "unused" comments + current_comments.append(comment) + + line = line.rstrip() + if not line: + continue + + type_string, _, rest = line.partition(' ') + rest = rest.lstrip() + if not rest: + print('Error with:', pkg_name, msg_name, line, file=sys.stderr) + raise InvalidFieldDefinition(line) + index = rest.find(CONSTANT_SEPARATOR) + if index == -1: + # line contains a field + field_name, _, default_value_string = rest.partition(' ') + default_value_string = default_value_string.lstrip() + if not default_value_string: + default_value_string = None + try: + fields.append(Field( + Type(type_string, context_package_name=pkg_name), + field_name, default_value_string)) + except Exception as err: + print( + "Error processing '{line}' of '{pkg}/{msg}': '{err}'".format( + line=line, pkg=pkg_name, msg=msg_name, err=err), + file=sys.stderr) + raise + last_element = fields[-1] + + else: + # line contains a constant + name, _, value = rest.partition(CONSTANT_SEPARATOR) + name = name.rstrip() + value = value.lstrip() + constants.append(Constant(type_string, name, value)) + last_element = constants[-1] + + # add "unused" comments to the field / constant + comment_lines = last_element.annotations.setdefault( + 'comment', []) + comment_lines += current_comments + current_comments = [] + + msg = MessageSpecification(pkg_name, msg_name, fields, constants) + msg.annotations['comment'] = message_comments + + # condense comment lines, extract special annotations + process_comments(msg) + for field in fields: + process_comments(field) + for constant in constants: + process_comments(constant) + + return msg + + +def process_comments(instance): + if 'comment' in instance.annotations: + lines = instance.annotations['comment'] + + # look for a unit in brackets + # the unit should not contains a comma since it might be a range + comment = '\n'.join(lines) + pattern = r'(\s*\[([^,\]]+)\])' + matches = re.findall(pattern, comment) + if len(matches) == 1: + instance.annotations['unit'] = matches[0][1] + # remove the unit from the comment + for i, line in enumerate(lines): + lines[i] = line.replace(matches[0][0], '') + + # remove empty leading lines + while lines and lines[0] == '': + del lines[0] + # remove empty trailing lines + while lines and lines[-1] == '': + del lines[-1] + # remove consecutive empty lines + length = len(lines) + i = 1 + while i < length: + if lines[i] == '' and lines[i - 1] == '': + lines[i - 1:i + 1] = [''] + length -= 1 + continue + i += 1 + if lines: + text = '\n'.join(lines) + instance.annotations['comment'] = textwrap.dedent(text).split('\n') + + +def parse_value_string(type_, value_string): + if type_.is_primitive_type() and not type_.is_array: + return parse_primitive_value_string(type_, value_string) + + if type_.is_primitive_type() and type_.is_array: + # check for array brackets + if not value_string.startswith('[') or not value_string.endswith(']'): + raise InvalidValue( + type_, value_string, + "array value must start with '[' and end with ']'") + elements_string = value_string[1:-1] + + if type_.type in ('string', 'wstring'): + # String arrays need special processing as the comma can be part of a quoted string + # and not a separator of array elements + value_strings = parse_string_array_value_string(elements_string, type_.array_size) + else: + value_strings = elements_string.split(',') if elements_string else [] + if type_.array_size: + # check for exact size + if not type_.is_upper_bound and \ + len(value_strings) != type_.array_size: + raise InvalidValue( + type_, value_string, + 'array must have exactly %u elements, not %u' % + (type_.array_size, len(value_strings))) + # check for upper bound + if type_.is_upper_bound and len(value_strings) > type_.array_size: + raise InvalidValue( + type_, value_string, + 'array must have not more than %u elements, not %u' % + (type_.array_size, len(value_strings))) + + # parse all primitive values one by one + values = [] + for index, element_string in enumerate(value_strings): + element_string = element_string.strip() + try: + base_type = Type(BaseType.__str__(type_)) + value = parse_primitive_value_string(base_type, element_string) + except InvalidValue as e: + raise InvalidValue( + type_, value_string, 'element %u with %s' % (index, e)) + values.append(value) + return values + + raise NotImplementedError( + "parsing string values into type '%s' is not supported" % type_) + + +def parse_string_array_value_string(element_string, expected_size): + # Walks the string, if start with quote (' or ") find next unescapted quote, + # returns a list of string elements + value_strings = [] + while len(element_string) > 0: + element_string = element_string.lstrip(' ') + if element_string[0] == ',': + raise ValueError("unxepected ',' at beginning of [%s]" % element_string) + if len(element_string) == 0: + return value_strings + quoted_value = False + for quote in ['"', "'"]: + if element_string.startswith(quote): + quoted_value = True + end_quote_idx = find_matching_end_quote(element_string, quote) + if end_quote_idx == -1: + raise ValueError('string [%s] incorrectly quoted\n%s' % ( + element_string, value_strings)) + else: + value_string = element_string[1:end_quote_idx + 1] + value_string = value_string.replace('\\' + quote, quote) + value_strings.append(value_string) + element_string = element_string[end_quote_idx + 2:] + if not quoted_value: + next_comma_idx = element_string.find(',') + if next_comma_idx == -1: + value_strings.append(element_string) + element_string = '' + else: + value_strings.append(element_string[:next_comma_idx]) + element_string = element_string[next_comma_idx:] + element_string = element_string.lstrip(' ') + if len(element_string) > 0 and element_string[0] == ',': + element_string = element_string[1:] + return value_strings + + +def find_matching_end_quote(string, quote): + # Given a string, walk it and find the next unescapted quote + # returns the index of the ending quote if successful, -1 otherwise + ending_quote_idx = -1 + final_quote_idx = 0 + while len(string) > 0: + ending_quote_idx = string[1:].find(quote) + if ending_quote_idx == -1: + return -1 + if string[ending_quote_idx:ending_quote_idx + 2] != '\\%s' % quote: + # found a matching end quote that is not escaped + return final_quote_idx + ending_quote_idx + else: + string = string[ending_quote_idx + 2:] + final_quote_idx = ending_quote_idx + 2 + return -1 + + +def parse_primitive_value_string(type_, value_string): + if not type_.is_primitive_type() or type_.is_array: + raise ValueError('the passed type must be a non-array primitive type') + primitive_type = type_.type + + if primitive_type == 'bool': + true_values = ['true', '1'] + false_values = ['false', '0'] + if value_string.lower() not in (true_values + false_values): + raise InvalidValue( + primitive_type, value_string, + "must be either 'true' / '1' or 'false' / '0'") + return value_string.lower() in true_values + + if primitive_type in ('byte', 'char'): + # same as uint8 + ex = InvalidValue(primitive_type, value_string, + 'must be a valid integer value >= 0 and <= 255') + try: + value = int(value_string) + except ValueError: + try: + value = int(value_string, 0) + except ValueError: + raise ex + + if value < 0 or value > 255: + raise ex + return value + + if primitive_type in ['float32', 'float64']: + try: + return float(value_string) + except ValueError: + raise InvalidValue( + primitive_type, value_string, + "must be a floating point number using '.' as the separator") + + if primitive_type in [ + 'int8', 'uint8', + 'int16', 'uint16', + 'int32', 'uint32', + 'int64', 'uint64', + ]: + # determine lower and upper bound + is_unsigned = primitive_type.startswith('u') + bits = int(primitive_type[4 if is_unsigned else 3:]) + lower_bound = 0 if is_unsigned else -(2 ** (bits - 1)) + upper_bound = (2 ** (bits if is_unsigned else (bits - 1))) - 1 + + ex = InvalidValue(primitive_type, value_string, + 'must be a valid integer value >= %d and <= %u' % + (lower_bound, upper_bound)) + + try: + value = int(value_string) + except ValueError: + try: + value = int(value_string, 0) + except ValueError: + raise ex + + # check that value is in valid range + if value < lower_bound or value > upper_bound: + raise ex + + return value + + if primitive_type in ('string', 'wstring'): + # remove outer quotes to allow leading / trailing spaces in the string + for quote in ['"', "'"]: + if value_string.startswith(quote) and value_string.endswith(quote): + value_string = value_string[1:-1] + match = re.search(r'(? type_.string_upper_bound: + base_type = Type(BaseType.__str__(type_)) + raise InvalidValue( + base_type, value_string, + 'string must not exceed the maximum length of %u characters' % + type_.string_upper_bound) + + return value_string + + assert False, "unknown primitive type '%s'" % primitive_type + + +def validate_field_types(spec, known_msg_types): + if isinstance(spec, MessageSpecification): + spec_type = 'Message' + fields = spec.fields + elif isinstance(spec, ServiceSpecification): + spec_type = 'Service' + fields = spec.request.fields + spec.response.fields + elif isinstance(spec, ActionSpecification): + spec_type = 'Action' + fields = [] + for service in [spec.goal_service, spec.result_service]: + fields += service.request.fields + fields += service.response.fields + else: + assert False, 'Unknown specification type: %s' % type(spec) + for field in fields: + if field.type.is_primitive_type(): + continue + base_type = BaseType(BaseType.__str__(field.type)) + if base_type not in known_msg_types: + raise UnknownMessageType( + "%s interface '%s' contains an unknown field type: %s" % + (spec_type, base_type, field)) + + +class ServiceSpecification: + + def __init__(self, pkg_name, srv_name, request, response): + self.pkg_name = pkg_name + self.srv_name = srv_name + assert isinstance(request, MessageSpecification) + self.request = request + assert isinstance(response, MessageSpecification) + self.response = response + + def __str__(self): + """Output an equivalent .srv IDL string.""" + output = ['# ', str(self.pkg_name), '/', str(self.srv_name), '\n'] + output.append(str(self.request)) + output.append('\n---\n') + output.append(str(self.response)) + return ''.join(output) + + +def parse_service_file(pkg_name, interface_filename): + basename = os.path.basename(interface_filename) + srv_name = os.path.splitext(basename)[0] + with open(interface_filename, 'r', encoding='utf-8') as h: + return parse_service_string( + pkg_name, srv_name, h.read()) + + +def parse_service_string(pkg_name, srv_name, message_string): + lines = message_string.splitlines() + separator_indices = [ + index for index, line in enumerate(lines) if line == SERVICE_REQUEST_RESPONSE_SEPARATOR] + if not separator_indices: + raise InvalidServiceSpecification( + "Could not find separator '%s' between request and response" % + SERVICE_REQUEST_RESPONSE_SEPARATOR) + if len(separator_indices) != 1: + raise InvalidServiceSpecification( + "Could not find unique separator '%s' between request and response" % + SERVICE_REQUEST_RESPONSE_SEPARATOR) + + request_message_string = '\n'.join(lines[:separator_indices[0]]) + request_message = parse_message_string( + pkg_name, srv_name + SERVICE_REQUEST_MESSAGE_SUFFIX, request_message_string) + + response_message_string = '\n'.join(lines[separator_indices[0] + 1:]) + response_message = parse_message_string( + pkg_name, srv_name + SERVICE_RESPONSE_MESSAGE_SUFFIX, response_message_string) + + return ServiceSpecification(pkg_name, srv_name, request_message, response_message) + + +class ActionSpecification: + + def __init__(self, pkg_name, action_name, goal, result, feedback): + self.pkg_name = pkg_name + self.action_name = action_name + assert isinstance(goal, MessageSpecification) + self.goal = goal + assert isinstance(result, MessageSpecification) + self.result = result + assert isinstance(feedback, MessageSpecification) + self.feedback = feedback + + +def parse_action_file(pkg_name, interface_filename): + basename = os.path.basename(interface_filename) + action_name = os.path.splitext(basename)[0] + with open(interface_filename, 'r', encoding='utf-8') as h: + return parse_action_string(pkg_name, action_name, h.read()) + + +def parse_action_string(pkg_name, action_name, action_string): + lines = action_string.splitlines() + separator_indices = [ + index for index, line in enumerate(lines) if line == ACTION_REQUEST_RESPONSE_SEPARATOR] + if len(separator_indices) != 2: + raise InvalidActionSpecification( + "Number of '%s' separators nonconformant with action definition" % + ACTION_REQUEST_RESPONSE_SEPARATOR) + + goal_string = '\n'.join(lines[:separator_indices[0]]) + result_string = '\n'.join(lines[separator_indices[0] + 1:separator_indices[1]]) + feedback_string = '\n'.join(lines[separator_indices[1] + 1:]) + + goal_message = parse_message_string( + pkg_name, action_name + ACTION_GOAL_SUFFIX, goal_string) + result_message = parse_message_string( + pkg_name, action_name + ACTION_RESULT_SUFFIX, result_string) + feedback_message = parse_message_string( + pkg_name, action_name + ACTION_FEEDBACK_SUFFIX, feedback_string) + # --------------------------------------------------------------------------------------------- + + return ActionSpecification( + pkg_name, action_name, goal_message, result_message, feedback_message) diff --git a/dimos/message_codegen/_vendor/rosidl_parser.pyi b/dimos/message_codegen/_vendor/rosidl_parser.pyi new file mode 100644 index 00000000000..dc42b36503f --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl_parser.pyi @@ -0,0 +1,30 @@ +from typing import Any + +class InvalidSpecification(Exception): ... +class InvalidValue(Exception): ... + +class Type: + pkg_name: str | None + type: str + string_upper_bound: int | None + is_array: bool + array_size: int | None + is_upper_bound: bool + +class Field: + type: Type + name: str + default_value: Any + +class Constant: + type: str + name: str + value: Any + +class MessageSpecification: + fields: list[Field] + constants: list[Constant] + +def parse_message_string( + pkg_name: str, msg_name: str, message_string: str +) -> MessageSpecification: ... diff --git a/dimos/message_codegen/cpp.py b/dimos/message_codegen/cpp.py new file mode 100644 index 00000000000..de665776833 --- /dev/null +++ b/dimos/message_codegen/cpp.py @@ -0,0 +1,273 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate native C++ value types and Fast CDR customization functions.""" + +from __future__ import annotations + +import json +import math +from typing import Any + +from dimos.message_codegen.definitions import FieldType, Message + +PRIMITIVES = { + "bool": "bool", + "byte": "uint8_t", + "char": "uint8_t", + "int8": "int8_t", + "uint8": "uint8_t", + "int16": "int16_t", + "uint16": "uint16_t", + "int32": "int32_t", + "uint32": "uint32_t", + "int64": "int64_t", + "uint64": "uint64_t", + "float32": "float", + "float64": "double", + "string": "std::string", + "wstring": "std::wstring", +} +KEYWORDS = frozenset( + [ + "alignas", + "alignof", + "and", + "and_eq", + "asm", + "auto", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "char", + "char8_t", + "char16_t", + "char32_t", + "class", + "compl", + "concept", + "const", + "consteval", + "constexpr", + "constinit", + "const_cast", + "continue", + "co_await", + "co_return", + "co_yield", + "decltype", + "default", + "delete", + "do", + "double", + "dynamic_cast", + "else", + "enum", + "explicit", + "export", + "extern", + "false", + "float", + "for", + "friend", + "goto", + "if", + "inline", + "int", + "long", + "mutable", + "namespace", + "new", + "noexcept", + "not", + "not_eq", + "nullptr", + "operator", + "or", + "or_eq", + "private", + "protected", + "public", + "register", + "reinterpret_cast", + "requires", + "return", + "short", + "signed", + "sizeof", + "static", + "static_assert", + "static_cast", + "struct", + "switch", + "template", + "this", + "thread_local", + "throw", + "true", + "try", + "typedef", + "typeid", + "typename", + "union", + "unsigned", + "using", + "virtual", + "void", + "volatile", + "wchar_t", + "while", + "xor", + "xor_eq", + ] +) + + +def identifier(name: str) -> str: + return name + "_" if name in KEYWORDS else name + + +def qualified(name: str) -> str: + return "::".join(identifier(part) for part in name.split("/")) + + +def type_name(type_: FieldType) -> str: + scalar = qualified(type_.name) if type_.nested else PRIMITIVES[type_.name] + if type_.sequence: + return f"std::vector<{scalar}>" + if type_.is_array: + return f"std::array<{scalar}, {type_.array_size}>" + return scalar + + +def literal(value: Any, type_name_: str) -> str: + if isinstance(value, tuple): + return "{" + ", ".join(literal(item, type_name_) for item in value) + "}" + if isinstance(value, str): + return ("L" if type_name_ == "wstring" else "") + json.dumps(value, ensure_ascii=True) + if isinstance(value, bool): + return "true" if value else "false" + if isinstance(value, float): + native = PRIMITIVES[type_name_] + if math.isnan(value): + return f"std::numeric_limits<{native}>::quiet_NaN()" + if math.isinf(value): + sign = "-" if value < 0 else "" + return f"{sign}std::numeric_limits<{native}>::infinity()" + return repr(value) + ("f" if type_name_ == "float32" else "") + if type_name_ == "uint64": + return f"{value}ULL" + if type_name_ == "int64" and value == -(2**63): + return "(-9223372036854775807LL - 1)" + return str(value) + + +def validation(message: Message) -> list[str]: + lines = [] + for field in message.fields: + member = identifier(field.name) + type_ = field.type + if type_.array_bounded: + lines.append( + f'if ({member}.size() > {type_.array_size}) throw std::length_error("{field.name} exceeds sequence bound");' + ) + value = "item" if type_.is_array else member + checks = [] + if type_.string_bound is not None: + checks.append( + f'if ({value}.size() > {type_.string_bound}) throw std::length_error("{field.name} exceeds string bound");' + ) + if type_.nested: + checks.append(f"{value}.validate();") + if checks and type_.is_array: + lines.append(f"for (const auto& item : {member}) {{ {' '.join(checks)} }}") + else: + lines.extend(checks) + return lines + + +def generate(messages: tuple[Message, ...]) -> str: + lines = [ + "// Generated from ROS2 .msg definitions. Do not edit.", + "#pragma once", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + '#include "dimos_cdr.hpp"', + ] + for message in messages: + namespace = qualified(message.name.rsplit("/", 1)[0]) + name = identifier(message.short_name) + lines.extend([f"namespace {namespace} {{", f"struct {name} {{"]) + for constant in message.constants: + native = PRIMITIVES[constant.type] + if constant.type in {"string", "wstring"}: + native = "const wchar_t*" if constant.type == "wstring" else "const char*" + lines.append( + f"static constexpr {native} {identifier(constant.name)} = {literal(constant.value, constant.type)};" + ) + for field in message.fields: + if field.default is None: + default = "{}" + elif isinstance(field.default, tuple): + default = literal(field.default, field.type.name) + else: + default = "{" + literal(field.default, field.type.name) + "}" + lines.append(f"{type_name(field.type)} {identifier(field.name)}{default};") + lines.append("void validate() const {") + lines.extend(validation(message)) + lines.extend(["}", f'static constexpr const char* msg_name = "{message.name}";', "};", "}"]) + + lines.append("namespace eprosima::fastcdr {") + for message in messages: + name = qualified(message.name) + lines.extend( + [ + f"template<> inline size_t calculate_serialized_size(CdrSizeCalculator& calculator, const {name}& value, size_t& alignment) {{", + "size_t size = 0;", + ] + ) + for field in message.fields: + lines.append( + f"size += calculator.calculate_serialized_size(value.{identifier(field.name)}, alignment);" + ) + if not message.fields: + lines.append("size += calculator.calculate_serialized_size(uint8_t{0}, alignment);") + lines.extend( + [ + "return size;", + "}", + f"template<> inline void serialize(Cdr& cdr, const {name}& value) {{", + ] + ) + for field in message.fields: + lines.append(f"cdr << value.{identifier(field.name)};") + if not message.fields: + lines.append("cdr << uint8_t{0};") + lines.extend(["}", f"template<> inline void deserialize(Cdr& cdr, {name}& value) {{"]) + for field in message.fields: + lines.append(f"cdr >> value.{identifier(field.name)};") + if not message.fields: + lines.append("uint8_t unused; cdr >> unused;") + lines.extend(["value.validate();", "}"]) + lines.append("}") + return "\n".join(lines) + "\n" diff --git a/dimos/message_codegen/definitions.py b/dimos/message_codegen/definitions.py new file mode 100644 index 00000000000..380d5ac4a56 --- /dev/null +++ b/dimos/message_codegen/definitions.py @@ -0,0 +1,193 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Resolve ROS2 message definitions without a ROS environment or build system.""" + +from __future__ import annotations + +from collections.abc import Iterable +from contextlib import redirect_stderr +from dataclasses import dataclass +from io import StringIO +from pathlib import Path +from typing import Any + +from dimos.message_codegen._vendor.rosidl_parser import ( + InvalidSpecification, + InvalidValue, + parse_message_string, +) + +BUNDLED_SCHEMAS = Path(__file__).with_name("schemas") + + +@dataclass(frozen=True) +class FieldType: + """A scalar, fixed array, or sequence; bounds are separate from wire type.""" + + name: str + is_array: bool = False + array_size: int | None = None + array_bounded: bool = False + string_bound: int | None = None + + @property + def nested(self) -> bool: + return "/" in self.name + + @property + def sequence(self) -> bool: + return self.is_array and (self.array_size is None or self.array_bounded) + + +@dataclass(frozen=True) +class Field: + name: str + type: FieldType + default: Any = None + + +@dataclass(frozen=True) +class Constant: + name: str + type: str + value: Any + + +@dataclass(frozen=True) +class Message: + name: str + fields: tuple[Field, ...] + constants: tuple[Constant, ...] + source: Path + text: str + + @property + def package(self) -> str: + return self.name.split("/")[0] + + @property + def short_name(self) -> str: + return self.name.split("/")[-1] + + @property + def dependencies(self) -> tuple[str, ...]: + return tuple(sorted({field.type.name for field in self.fields if field.type.nested})) + + +def parse_message(path: Path) -> Message: + """Read a package/msg/Type.msg, retaining its original text for viewers.""" + if path.parent.name != "msg" or path.suffix != ".msg": + raise ValueError(f"{path}: expected package/msg/Type.msg") + package = path.parent.parent.name + text = path.read_text(encoding="utf-8") + try: + with redirect_stderr(StringIO()): + parsed = parse_message_string(package, path.stem, text) + except (ValueError, TypeError, NameError, InvalidSpecification, InvalidValue) as exc: + # The upstream parser reports the bad declaration, but not its line. + # Re-parse declarations only on failure to provide source diagnostics. + for line_number, line in enumerate(text.splitlines(), 1): + if not line.strip() or line.lstrip().startswith("#"): + continue + try: + with redirect_stderr(StringIO()): + parse_message_string(package, path.stem, line) + except (ValueError, TypeError, NameError, InvalidSpecification, InvalidValue): + raise ValueError(f"{path}:{line_number}: {exc}") from exc + raise ValueError(f"{path}: {exc}") from exc + + fields = [] + for field in parsed.fields: + type_ = field.type + if type_.type in {"time", "duration"} and type_.pkg_name is None: + raise ValueError( + f"{path}: use builtin_interfaces/{type_.type.title()}, not ROS1 {type_.type}" + ) + name = f"{type_.pkg_name}/msg/{type_.type}" if type_.pkg_name else type_.type + default = field.default_value + fields.append( + Field( + field.name, + FieldType( + name, + type_.is_array, + type_.array_size, + type_.is_upper_bound, + type_.string_upper_bound, + ), + tuple(default) if isinstance(default, list) else default, + ) + ) + return Message( + f"{package}/msg/{path.stem}", + tuple(fields), + tuple(Constant(value.name, value.type, value.value) for value in parsed.constants), + path, + text, + ) + + +class Definitions: + """A closed set of local definitions with dependency-first resolution.""" + + def __init__(self, roots: Iterable[Path], *, bundled: bool = True) -> None: + self._messages: dict[str, Message] = {} + for root in ([BUNDLED_SCHEMAS] if bundled else []) + list(roots): + if not root.is_dir(): + raise ValueError(f"Schema root does not exist: {root}") + for path in sorted(root.rglob("*.msg")): + message = parse_message(path) + previous = self._messages.get(message.name) + if previous is not None: + if (previous.fields, previous.constants) != (message.fields, message.constants): + raise ValueError( + f"Conflicting definition {message.name}: {previous.source} and {path}" + ) + continue + self._messages[message.name] = message + + def resolve(self, names: Iterable[str] | None = None) -> tuple[Message, ...]: + """Return the full dependency closure, with dependencies before users.""" + result: dict[str, Message] = {} + visiting: list[str] = [] + + def visit(name: str) -> None: + if name in result: + return + if name in visiting: + raise ValueError(f"Recursive message definition: {' -> '.join([*visiting, name])}") + if name not in self._messages: + origin = self._messages[visiting[-1]].source if visiting else "requested root" + raise ValueError(f"{origin}: unresolved message dependency {name}") + visiting.append(name) + message = self._messages[name] + for dependency in message.dependencies: + visit(dependency) + visiting.pop() + result[name] = message + + for name in sorted(self._messages if names is None else names): + visit(name) + return tuple(result.values()) + + def schema(self, name: str) -> str: + """ROS2 MCAP schema text, including every transitive dependency once.""" + closure = self.resolve([name]) + root = self._messages[name] + sections = [root.text.rstrip() + "\n"] + for message in sorted(closure, key=lambda item: item.name): + if message.name != name: + sections.append(f"{'=' * 80}\nMSG: {message.name}\n{message.text.rstrip()}\n") + return "".join(sections) diff --git a/dimos/message_codegen/generate.py b/dimos/message_codegen/generate.py new file mode 100644 index 00000000000..6ee47e1443a --- /dev/null +++ b/dimos/message_codegen/generate.py @@ -0,0 +1,98 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""One offline generation entry point for Python, C++, Rust, and viewer schemas.""" + +from __future__ import annotations + +import argparse +import json +import keyword +from pathlib import Path +import re +import shutil + +from dimos.message_codegen import cpp, python, rust +from dimos.message_codegen.definitions import Definitions + +TEMPLATES = Path(__file__).with_name("templates") + + +def generate( + roots: list[Path], output: Path, names: list[str] | None = None, module: str = "dimos_generated" +) -> tuple[str, ...]: + """Emit all three native language outputs, resolving dependencies first.""" + if not re.fullmatch(r"[a-z][a-z0-9_]*", module) or keyword.iskeyword(module): + raise ValueError(f"Invalid Python extension module name: {module}") + definitions = Definitions(roots) + messages = definitions.resolve(names) + for message in messages: + for field in message.fields: + if field.type.name == "wstring": + raise ValueError( + f"{message.source}: wstring is not yet supported by the Rust CDR backend" + ) + output.mkdir(parents=True, exist_ok=True) + native = output / "cpp" + native.mkdir(exist_ok=True) + (native / "messages.hpp").write_text(cpp.generate(messages)) + shutil.copyfile(TEMPLATES / "dimos_cdr.hpp", native / "dimos_cdr.hpp") + shutil.copyfile(TEMPLATES / "dimos_python.hpp", native / "dimos_python.hpp") + bindings = python.generate(messages, definitions, module) + for name, content in bindings.items(): + (native / name).write_text(content) + sources = " ".join(sorted(bindings)) + (native / "CMakeLists.txt").write_text( + "cmake_minimum_required(VERSION 3.20)\n" + "project(dimos_generated_messages LANGUAGES CXX)\n" + "find_package(fastcdr 2.4.0 EXACT REQUIRED)\n" + "find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)\n" + 'execute_process(COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir OUTPUT_VARIABLE pybind11_DIR OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)\n' + "find_package(pybind11 3.0.1 EXACT REQUIRED)\n" + f"pybind11_add_module({module} NO_EXTRAS {sources})\n" + f"target_compile_features({module} PRIVATE cxx_std_17)\n" + f"target_link_libraries({module} PRIVATE fastcdr)\n" + ) + crate = output / "rust" + (crate / "src").mkdir(parents=True, exist_ok=True) + (crate / "src" / "lib.rs").write_text(rust.generate(messages, definitions)) + shutil.copyfile(TEMPLATES / "codec.rs", crate / "src" / "codec.rs") + (crate / "Cargo.toml").write_text( + '[package]\nname = "dimos-generated-messages"\nversion = "0.1.0"\nedition = "2024"\n' + '[workspace]\n[dependencies]\nserde = { version = "1.0", features = ["derive"] }\n' + 'serde-big-array = "=0.5.1"\nre_cdr = "=0.1.0"\n' + ) + metadata = {message.name: definitions.schema(message.name) for message in messages} + (output / "schemas.json").write_text(json.dumps(metadata, indent=2, sort_keys=True) + "\n") + return tuple(message.name for message in messages) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--package-root", type=Path, action="append", default=[]) + parser.add_argument( + "--type", dest="names", action="append", help="Root package/msg/Type (repeatable)" + ) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--python-module", default="dimos_generated") + args = parser.parse_args() + try: + names = generate(args.package_root, args.output, args.names, args.python_module) + except ValueError as exc: + parser.error(str(exc)) + print(f"Generated {len(names)} message types for Python, C++, and Rust in {args.output}") + + +if __name__ == "__main__": + main() diff --git a/dimos/message_codegen/python.py b/dimos/message_codegen/python.py new file mode 100644 index 00000000000..4a653aa64e3 --- /dev/null +++ b/dimos/message_codegen/python.py @@ -0,0 +1,130 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate Python bindings to the same native types/codecs used by C++.""" + +from __future__ import annotations + +import json + +from dimos.message_codegen import cpp +from dimos.message_codegen.definitions import Definitions, Message + + +def string_literal(value: str) -> str: + delimiter = "msg" + while f'){delimiter}"' in value: + delimiter += "_" + return f'R"{delimiter}({value}){delimiter}"' + + +def generate( + messages: tuple[Message, ...], definitions: Definitions, module: str +) -> dict[str, str]: + sources: dict[str, str] = {} + containers = sorted( + { + cpp.type_name(field.type) + for message in messages + for field in message.fields + if field.type.is_array + } + ) + container_names = {native: f"_Sequence{index}" for index, native in enumerate(containers)} + functions = [] + for offset in range(0, len(messages), 10): + function = f"bind_{offset // 10}" + functions.append(function) + lines = [ + "// Generated from ROS2 .msg definitions. Do not edit.", + "#include ", + "#include ", + '#include "messages.hpp"', + '#include "dimos_python.hpp"', + "namespace py = pybind11;", + f"void {function}(py::module_& root) {{", + ] + for message in messages[offset : offset + 10]: + native = cpp.qualified(message.name) + lines.extend( + [ + "{", + f'auto package = py::hasattr(root, "{message.package}") ? root.attr("{message.package}").cast() : root.def_submodule("{message.package}");', + 'auto module = py::hasattr(package, "msg") ? package.attr("msg").cast() : package.def_submodule("msg");', + f'auto cls = py::class_<{native}>(module, "{message.short_name}", py::dynamic_attr(), py::module_local());', + f"cls.def(py::init([](py::kwargs kwargs) {{ {native} value{{}};", + "for (auto item : kwargs) { auto key = py::cast(item.first);", + ] + ) + for index, field in enumerate(message.fields): + condition = "if" if index == 0 else "else if" + cast = "dimos::python::sequence_from_python" if field.type.is_array else "py::cast" + lines.append( + f'{condition} (key == "{field.name}") value.{cpp.identifier(field.name)} = {cast}<{cpp.type_name(field.type)}>(item.second);' + ) + fallback = "else " if message.fields else "" + lines.append(f'{fallback}throw py::type_error("Unknown message field: " + key);') + lines.extend(["}", "value.validate(); return value; }));"]) + for field in message.fields: + field_native = cpp.type_name(field.type) + member = f"self.cast<{native}&>().{cpp.identifier(field.name)}" + if field.type.is_array: + lines.extend( + [ + f'dimos::python::bind_sequence<{field_native}>(root, "{container_names[field_native]}");', + f'cls.def_property("{field.name}", [](py::object self) {{ return dimos::python::Sequence<{field_native}>{{ &{member}, dimos::python::owner_root(self) }}; }},', + f"[](py::object self, py::handle input) {{ dimos::python::require_unborrowed(self); {member} = dimos::python::sequence_from_python<{field_native}>(input); }});", + ] + ) + elif field.type.nested: + lines.extend( + [ + f'cls.def_property("{field.name}", [](py::object self) {{ auto child = py::cast(&{member}, py::return_value_policy::reference_internal, self); child.attr("__dimos_owner") = dimos::python::owner_root(self); return child; }},', + f"[](py::object self, const {field_native}& input) {{ dimos::python::require_unborrowed(self); {member} = input; }});", + ] + ) + else: + lines.append( + f'cls.def_readwrite("{field.name}", &{native}::{cpp.identifier(field.name)});' + ) + for constant in message.constants: + lines.append( + f'cls.attr("{constant.name}") = py::cast({native}::{cpp.identifier(constant.name)});' + ) + lines.extend( + [ + f'cls.def("encode", [](const {native}& value, bool little_endian) {{ auto bytes = dimos::cdr::encode(value, little_endian); return py::bytes(reinterpret_cast(bytes.data()), bytes.size()); }}, py::arg("little_endian") = true);', + f'cls.def_static("decode", [](py::bytes input) {{ std::string bytes = input; return dimos::cdr::decode<{native}>(reinterpret_cast(bytes.data()), bytes.size()); }});', + f"cls.def(py::pickle([](const {native}& value) {{ auto bytes = dimos::cdr::encode(value); return py::bytes(reinterpret_cast(bytes.data()), bytes.size()); }}, [](py::bytes input) {{ std::string bytes = input; return dimos::cdr::decode<{native}>(reinterpret_cast(bytes.data()), bytes.size()); }}));", + f'cls.attr("msg_name") = {json.dumps(message.name)};', + f'cls.attr("schema") = {string_literal(definitions.schema(message.name))};', + "}", + ] + ) + lines.append("}") + sources[function + ".cpp"] = "\n".join(lines) + "\n" + sources["bindings.cpp"] = ( + "\n".join( + [ + "// Generated from ROS2 .msg definitions. Do not edit.", + "#include ", + *(f"void {function}(pybind11::module_&);" for function in functions), + f"PYBIND11_MODULE({module}, root) {{", + *(f"{function}(root);" for function in functions), + "}", + ] + ) + + "\n" + ) + return sources diff --git a/dimos/message_codegen/rust.py b/dimos/message_codegen/rust.py new file mode 100644 index 00000000000..7c237d3861b --- /dev/null +++ b/dimos/message_codegen/rust.py @@ -0,0 +1,218 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate native Rust types with Serde-backed CDR codecs.""" + +from __future__ import annotations + +from collections import defaultdict +import json +import math +import re +from typing import Any + +from dimos.message_codegen.definitions import Definitions, FieldType, Message + +PRIMITIVES = { + "bool": "bool", + "byte": "u8", + "char": "u8", + "int8": "i8", + "uint8": "u8", + "int16": "i16", + "uint16": "u16", + "int32": "i32", + "uint32": "u32", + "int64": "i64", + "uint64": "u64", + "float32": "f32", + "float64": "f64", + "string": "::std::string::String", +} +KEYWORDS = frozenset( + [ + "as", + "async", + "await", + "break", + "const", + "continue", + "crate", + "dyn", + "else", + "enum", + "extern", + "false", + "fn", + "for", + "if", + "impl", + "in", + "let", + "loop", + "match", + "mod", + "move", + "mut", + "pub", + "ref", + "return", + "self", + "Self", + "static", + "struct", + "super", + "trait", + "true", + "type", + "unsafe", + "use", + "where", + "while", + "abstract", + "become", + "box", + "do", + "final", + "gen", + "macro", + "override", + "priv", + "try", + "typeof", + "unsized", + "virtual", + "yield", + ] +) + + +def identifier(name: str) -> str: + return name + "_" if name in KEYWORDS else name + + +def type_name(type_: FieldType) -> str: + if type_.nested: + scalar = "crate::" + "::".join(identifier(part) for part in type_.name.split("/")) + else: + scalar = PRIMITIVES[type_.name] + if type_.sequence: + return f"::std::vec::Vec<{scalar}>" + if type_.is_array: + return f"[{scalar}; {type_.array_size}]" + return scalar + + +def string_literal(value: str) -> str: + return re.sub(r"\\u([0-9a-fA-F]{4})", r"\\u{\1}", json.dumps(value, ensure_ascii=False)) + + +def literal(value: Any, type_: FieldType) -> str: + if isinstance(value, tuple): + values = ", ".join(literal(item, FieldType(type_.name)) for item in value) + return ("vec!" if type_.sequence else "") + f"[{values}]" + if isinstance(value, str): + return string_literal(value) + ".to_owned()" + if isinstance(value, bool): + return "true" if value else "false" + if isinstance(value, float): + if math.isnan(value): + return PRIMITIVES[type_.name] + "::NAN" + if math.isinf(value): + return PRIMITIVES[type_.name] + ("::NEG_INFINITY" if value < 0 else "::INFINITY") + return repr(value) + return str(value) + + +def generate(messages: tuple[Message, ...], definitions: Definitions) -> str: + packages: dict[str, list[Message]] = defaultdict(list) + for message in messages: + packages[message.package].append(message) + lines = ["// Generated from ROS2 .msg definitions. Do not edit.", "pub mod codec;"] + for package, contents in sorted(packages.items()): + lines.append(f"pub mod {identifier(package)} {{ pub mod msg {{") + for message in contents: + name = identifier(message.short_name) + lines.extend( + [ + "#[derive(Debug, Clone, PartialEq, ::serde::Serialize, ::serde::Deserialize)]", + f"pub struct {name} {{", + ] + ) + for field in message.fields: + if field.type.is_array and not field.type.sequence: + lines.append('#[serde(with = "serde_big_array::BigArray")]') + if identifier(field.name) != field.name: + lines.append(f'#[serde(rename = "{field.name}")]') + lines.append(f"pub {identifier(field.name)}: {type_name(field.type)},") + if not message.fields: + lines.extend(["#[serde(default)]", "_unused: u8,"]) + lines.extend( + ["}", f"impl ::std::default::Default for {name} {{ fn default() -> Self {{ Self {{"] + ) + for field in message.fields: + if field.default is not None: + default = literal(field.default, field.type) + elif field.type.is_array and not field.type.sequence: + default = "::std::array::from_fn(|_| ::std::default::Default::default())" + else: + default = "::std::default::Default::default()" + lines.append(f"{identifier(field.name)}: {default},") + if not message.fields: + lines.append("_unused: 0,") + lines.extend( + [ + "} } }", + f"impl crate::codec::Message for {name} {{", + f'const NAME: &\'static str = "{message.name}";', + f"const SCHEMA: &'static str = {string_literal(definitions.schema(message.name))};", + "fn validate(&self) -> ::std::result::Result<(), ::std::string::String> {", + ] + ) + for field in message.fields: + member = "self." + identifier(field.name) + if field.type.array_bounded: + lines.append( + f'if {member}.len() > {field.type.array_size} {{ return Err("{field.name} exceeds sequence bound".into()); }}' + ) + checks = [] + value = "item" if field.type.is_array else member + if field.type.string_bound is not None: + checks.append( + f'if {value}.len() > {field.type.string_bound} {{ return Err("{field.name} exceeds string bound".into()); }}' + ) + if field.type.nested: + checks.append(f"crate::codec::Message::validate(&{value})?;") + if checks and field.type.is_array: + lines.append( + f"for item in &{member} {{ {' '.join(checks).replace('&item', 'item')} }}" + ) + else: + lines.extend(checks) + lines.extend(["Ok(())", "}", "}"]) + if message.constants: + lines.append(f"impl {name} {{") + for constant in message.constants: + native = ( + "&'static str" if constant.type == "string" else PRIMITIVES[constant.type] + ) + value = ( + string_literal(constant.value) + if constant.type == "string" + else literal(constant.value, FieldType(constant.type)) + ) + lines.append(f"pub const {identifier(constant.name)}: {native} = {value};") + lines.append("}") + lines.append("} }") + return "\n".join(lines) + "\n" diff --git a/dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg b/dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg new file mode 100644 index 00000000000..dc9e8f5a2bc --- /dev/null +++ b/dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg @@ -0,0 +1,12 @@ +# Duration defines a period between two time points. +# Messages of this datatype are of ROS Time following this design: +# https://design.ros2.org/articles/clock_and_time.html + +# The seconds component, valid over all int32 values. +int32 sec + +# The nanoseconds component, valid in the range [0, 1e9), to be added to the seconds component. +# e.g. +# The duration -1.7 seconds is represented as {sec: -2, nanosec: 3e8} +# The duration 1.7 seconds is represented as {sec: 1, nanosec: 7e8} +uint32 nanosec diff --git a/dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg b/dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg new file mode 100644 index 00000000000..03cc83f8622 --- /dev/null +++ b/dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg @@ -0,0 +1,11 @@ +# This message communicates ROS Time defined here: +# https://design.ros2.org/articles/clock_and_time.html + +# The seconds component, valid over all int32 values. +int32 sec + +# The nanoseconds component, valid in the range [0, 1e9), to be added to the seconds component. +# e.g. +# The time -1.7 seconds is represented as {sec: -2, nanosec: 3e8} +# The time 1.7 seconds is represented as {sec: 1, nanosec: 7e8} +uint32 nanosec diff --git a/dimos/message_codegen/schemas/builtin_interfaces/package.xml b/dimos/message_codegen/schemas/builtin_interfaces/package.xml new file mode 100644 index 00000000000..57540d0b204 --- /dev/null +++ b/dimos/message_codegen/schemas/builtin_interfaces/package.xml @@ -0,0 +1,29 @@ + + + + builtin_interfaces + 2.0.4 + A package containing message and service definitions for types defined in the OMG IDL Platform Specific Model. + + Geoffrey Biggs + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + + ament_cmake + + rosidl_core_generators + + rosidl_core_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg b/dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg new file mode 100644 index 00000000000..19041bc924a --- /dev/null +++ b/dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg @@ -0,0 +1,44 @@ +# foxglove_msgs/msg/CompressedVideo +# A single frame of a compressed video bitstream + +# Generated by https://github.com/foxglove/foxglove-sdk + +# Timestamp of video frame +builtin_interfaces/Time timestamp + +# Frame of reference for the video. +# +# The origin of the frame is the optical center of the camera. +x points to the right in the video, +y points down, and +z points into the plane of the video. +string frame_id + +# Compressed video frame data. +# +# For packet-based video codecs this data must begin and end on packet boundaries (no partial packets), and must contain enough video packets to decode exactly one image (either a keyframe or delta frame). Note: Foxglove does not support video streams that include B frames because they require lookahead. +# +# Specifically, the requirements for different `format` values are: +# +# - `h264` +# - Use Annex B formatted data +# - Each CompressedVideo message should contain enough NAL units to decode exactly one video frame +# - Each message containing a key frame (IDR) must also include a SPS NAL unit +# +# - `h265` (HEVC) +# - Use Annex B formatted data +# - Each CompressedVideo message should contain enough NAL units to decode exactly one video frame +# - Each message containing a key frame (IRAP) must also include relevant VPS/SPS/PPS NAL units +# +# - `vp9` +# - Each CompressedVideo message should contain exactly one video frame +# +# - `av1` +# - Use the "Low overhead bitstream format" (section 5.2) +# - Each CompressedVideo message should contain enough OBUs to decode exactly one video frame +# - Each message containing a key frame must also include a Sequence Header OBU +uint8[] data + +# Video format. +# +# Supported values: `h264`, `h265`, `vp9`, `av1`. +# +# Note: compressed video support is subject to hardware limitations and patent licensing, so not all encodings may be supported on all platforms. See more about [H.265 support](https://caniuse.com/hevc), [VP9 support](https://caniuse.com/webm), and [AV1 support](https://caniuse.com/av1). +string format diff --git a/dimos/message_codegen/schemas/geometry_msgs/LICENSE b/dimos/message_codegen/schemas/geometry_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg new file mode 100644 index 00000000000..19fef1411b7 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg @@ -0,0 +1,3 @@ +# This expresses acceleration in free space broken into its linear and angular parts. +Vector3 linear +Vector3 angular diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg new file mode 100644 index 00000000000..9283fbbd377 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg @@ -0,0 +1,3 @@ +# An accel with reference coordinate frame and timestamp +std_msgs/Header header +Accel accel diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg new file mode 100644 index 00000000000..fb9674d3061 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg @@ -0,0 +1,9 @@ +# This expresses acceleration in free space with uncertainty. + +Accel accel + +# Row-major representation of the 6x6 covariance matrix +# The orientation parameters use a fixed-axis representation. +# In order, the parameters are: +# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis) +float64[36] covariance diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg new file mode 100644 index 00000000000..90acd6edc5f --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg @@ -0,0 +1,3 @@ +# This represents an estimated accel with reference coordinate frame and timestamp. +std_msgs/Header header +AccelWithCovariance accel diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg new file mode 100644 index 00000000000..912aa9530f2 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg @@ -0,0 +1,16 @@ +# Mass [kg] +float64 m + +# Center of mass [m] +geometry_msgs/Vector3 com + +# Inertia Tensor [kg-m^2] about the center of mass +# | ixx ixy ixz | +# I = | ixy iyy iyz | +# | ixz iyz izz | +float64 ixx +float64 ixy +float64 ixz +float64 iyy +float64 iyz +float64 izz diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg new file mode 100644 index 00000000000..7da2662b572 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg @@ -0,0 +1,4 @@ +# An Inertia with a time stamp and reference frame. + +std_msgs/Header header +Inertia inertia diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg new file mode 100644 index 00000000000..f1d3a71a853 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg @@ -0,0 +1,4 @@ +# This contains the position of a point in free space +float64 x +float64 y +float64 z diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg new file mode 100644 index 00000000000..a7f5dc41354 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg @@ -0,0 +1,11 @@ +# This contains the position of a point in free space(with 32 bits of precision). +# It is recommended to use Point wherever possible instead of Point32. +# +# This recommendation is to promote interoperability. +# +# This message is designed to take up less space when sending +# lots of points at once, as in the case of a PointCloud. + +float32 x +float32 y +float32 z diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg new file mode 100644 index 00000000000..32a734cc5e9 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg @@ -0,0 +1,4 @@ +# This represents a Point with reference coordinate frame and timestamp + +std_msgs/Header header +Point point diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg new file mode 100644 index 00000000000..47aeb74db29 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg @@ -0,0 +1,3 @@ +# A specification of a polygon where the first and last points are assumed to be connected + +Point32[] points diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg new file mode 100644 index 00000000000..61d6af5b905 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg @@ -0,0 +1,5 @@ +# A specification of a polygon where the first and last points are assumed to be connected +# It includes a unique identification field for disambiguating multiple instances + +geometry_msgs/Polygon polygon +int64 id diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg new file mode 100644 index 00000000000..cefda8de0f2 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg @@ -0,0 +1,5 @@ +# This represents a Polygon with reference coordinate frame and timestamp +# It includes a unique identification field for disambiguating multiple instances + +std_msgs/Header header +geometry_msgs/PolygonInstance polygon diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg new file mode 100644 index 00000000000..3b87ac14c59 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg @@ -0,0 +1,4 @@ +# This represents a Polygon with reference coordinate frame and timestamp + +std_msgs/Header header +Polygon polygon diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg new file mode 100644 index 00000000000..277e2f0179a --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg @@ -0,0 +1,4 @@ +# A representation of pose in free space, composed of position and orientation. + +Point position +Quaternion orientation diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg new file mode 100644 index 00000000000..e9cf0166685 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg @@ -0,0 +1,10 @@ +# Deprecated as of Foxy and will potentially be removed in any following release. +# Please use the full 3D pose. + +# In general our recommendation is to use a full 3D representation of everything and for 2D specific applications make the appropriate projections into the plane for their calculations but optimally will preserve the 3D information during processing. + +# If we have parallel copies of 2D datatypes every UI and other pipeline will end up needing to have dual interfaces to plot everything. And you will end up with not being able to use 3D tools for 2D use cases even if they're completely valid, as you'd have to reimplement it with different inputs and outputs. It's not particularly hard to plot the 2D pose or compute the yaw error for the Pose message and there are already tools and libraries that can do this for you.# This expresses a position and orientation on a 2D manifold. + +float64 x +float64 y +float64 theta diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg new file mode 100644 index 00000000000..80386e088e2 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg @@ -0,0 +1,5 @@ +# An array of poses with a header for global reference. + +std_msgs/Header header + +Pose[] poses diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg new file mode 100644 index 00000000000..2b43935ed33 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg @@ -0,0 +1,4 @@ +# A Pose with reference coordinate frame and timestamp + +std_msgs/Header header +Pose pose diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg new file mode 100644 index 00000000000..86bc45adbb5 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg @@ -0,0 +1,9 @@ +# This represents a pose in free space with uncertainty. + +Pose pose + +# Row-major representation of the 6x6 covariance matrix +# The orientation parameters use a fixed-axis representation. +# In order, the parameters are: +# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis) +float64[36] covariance diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg new file mode 100644 index 00000000000..d439cdf75b7 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg @@ -0,0 +1,4 @@ +# This expresses an estimated pose with a reference coordinate frame and timestamp + +std_msgs/Header header +PoseWithCovariance pose diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg new file mode 100644 index 00000000000..96d392779a2 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg @@ -0,0 +1,6 @@ +# This represents an orientation in free space in quaternion form. + +float64 x 0 +float64 y 0 +float64 z 0 +float64 w 1 diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg new file mode 100644 index 00000000000..f192883220f --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg @@ -0,0 +1,4 @@ +# This represents an orientation with reference coordinate frame and timestamp. + +std_msgs/Header header +Quaternion quaternion diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg new file mode 100644 index 00000000000..f605c85ea8e --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg @@ -0,0 +1,4 @@ +# This represents the transform between two coordinate frames in free space. + +Vector3 translation +Quaternion rotation diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg new file mode 100644 index 00000000000..24e97b80b39 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg @@ -0,0 +1,19 @@ +# This expresses a transform from coordinate frame header.frame_id +# to the coordinate frame child_frame_id at the time of header.stamp +# +# This message is mostly used by the +# tf2 package. +# See its documentation for more information. +# +# The child_frame_id is necessary in addition to the frame_id +# in the Header to communicate the full reference for the transform +# in a self contained message. + +# The frame id in the header is used as the reference frame of this transform. +std_msgs/Header header + +# The frame id of the child frame to which this transform points. +string child_frame_id + +# Translation and rotation in 3-dimensions of child_frame_id from header.frame_id. +Transform transform diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg new file mode 100644 index 00000000000..ede73597b90 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg @@ -0,0 +1,4 @@ +# This expresses velocity in free space broken into its linear and angular parts. + +Vector3 linear +Vector3 angular diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg new file mode 100644 index 00000000000..2dcbeac1b07 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg @@ -0,0 +1,4 @@ +# A twist with reference coordinate frame and timestamp + +std_msgs/Header header +Twist twist diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg new file mode 100644 index 00000000000..111a19c5f7d --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg @@ -0,0 +1,9 @@ +# This expresses velocity in free space with uncertainty. + +Twist twist + +# Row-major representation of the 6x6 covariance matrix +# The orientation parameters use a fixed-axis representation. +# In order, the parameters are: +# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis) +float64[36] covariance diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg new file mode 100644 index 00000000000..90b65b1f3e9 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg @@ -0,0 +1,4 @@ +# This represents an estimated twist with reference coordinate frame and timestamp. + +std_msgs/Header header +TwistWithCovariance twist diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg new file mode 100644 index 00000000000..b54588e117c --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg @@ -0,0 +1,9 @@ +# This represents a vector in free space. + +# This is semantically different than a point. +# A vector is always anchored at the origin. +# When a transform is applied to a vector, only the rotational component is applied. + +float64 x +float64 y +float64 z diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg new file mode 100644 index 00000000000..aab1e0a9860 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg @@ -0,0 +1,7 @@ +# This represents a Vector3 with reference coordinate frame and timestamp + +# Note that this follows vector semantics with it always anchored at the origin, +# so the rotational elements of a transform are the only parts applied when transforming. + +std_msgs/Header header +Vector3 vector diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg new file mode 100644 index 00000000000..ff61c6ea244 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg @@ -0,0 +1,8 @@ +# This expresses the timestamped velocity vector of a frame 'body_frame_id' in the reference frame 'reference_frame_id' expressed from arbitrary observation frame 'header.frame_id'. +# - If the 'body_frame_id' and 'header.frame_id' are identical, the velocity is observed and defined in the local coordinates system of the body +# which is the usual use-case in mobile robotics and is also known as a body twist. + +std_msgs/Header header +string body_frame_id +string reference_frame_id +Twist velocity diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg new file mode 100644 index 00000000000..391557a4b54 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg @@ -0,0 +1,17 @@ +# A timestamped velocity of a body whose frame is 'body_frame_id', measured +# relative to the reference frame 'reference_frame_id', with the velocity and +# covariance both expressed in the basis of the observation frame +# 'header.frame_id'. +# +# - If 'body_frame_id' and 'header.frame_id' are identical, the velocity and +# covariance are expressed in the body's own basis. This is functionally +# equivalent to the body-twist convention used by +# 'geometry_msgs/TwistStamped'. +# +# This message is the covariance-bearing analogue of +# 'geometry_msgs/VelocityStamped'. + +std_msgs/Header header +string body_frame_id +string reference_frame_id +TwistWithCovariance velocity diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg new file mode 100644 index 00000000000..0b8efccbe33 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg @@ -0,0 +1,4 @@ +# This represents force in free space, separated into its linear and angular parts. + +Vector3 force +Vector3 torque diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg new file mode 100644 index 00000000000..0d5ebd9674a --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg @@ -0,0 +1,4 @@ +# A wrench with reference coordinate frame and timestamp + +std_msgs/Header header +Wrench wrench diff --git a/dimos/message_codegen/schemas/geometry_msgs/package.xml b/dimos/message_codegen/schemas/geometry_msgs/package.xml new file mode 100644 index 00000000000..66313657cc7 --- /dev/null +++ b/dimos/message_codegen/schemas/geometry_msgs/package.xml @@ -0,0 +1,32 @@ + + + + geometry_msgs + 5.3.8 + A package containing some geometry related message definitions. + + Tully Foote + + Apache License 2.0 + + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + William Woodall + + ament_cmake + + rosidl_default_generators + + std_msgs + + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE b/dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE new file mode 100644 index 00000000000..0aa593ea8c2 --- /dev/null +++ b/dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Foxglove Technologies Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE b/dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE b/dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE new file mode 100644 index 00000000000..d79557eefaf --- /dev/null +++ b/dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2008, Willow Garage, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE b/dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE b/dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/nav_msgs/LICENSE b/dimos/message_codegen/schemas/nav_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg new file mode 100644 index 00000000000..f07f5a8c317 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg @@ -0,0 +1,12 @@ +# An array of navigation goals + + +# This header will store the time at which the poses were computed (not to be confused with the stamps of the poses themselves) +# In the case that individual poses do not have their frame_id set or their timetamp set they will use the default value here. +std_msgs/Header header + +# An array of goals to for navigation to achieve. +# The goals should be executed in the order of the array. +# The header and stamp are intended to be used for computing the position of the goals. +# They may vary to support cases of goals that are moving with respect to the robot. +geometry_msgs/PoseStamped[] goals diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg b/dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg new file mode 100644 index 00000000000..7154e6c57a6 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg @@ -0,0 +1,12 @@ +# An array of cells in a 2D grid + +std_msgs/Header header + +# Width of each cell +float32 cell_width + +# Height of each cell +float32 cell_height + +# Each cell is represented by the Point at the center of the cell +geometry_msgs/Point[] cells diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg b/dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg new file mode 100644 index 00000000000..1c11e290e22 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg @@ -0,0 +1,17 @@ +# This hold basic information about the characteristics of the OccupancyGrid + +# The time at which the map was loaded +builtin_interfaces/Time map_load_time + +# The map resolution [m/cell] +float32 resolution + +# Map width [cells] +uint32 width + +# Map height [cells] +uint32 height + +# The origin of the map [m, m, rad]. This is the real-world pose of the +# bottom left corner of cell (0,0) in the map. +geometry_msgs/Pose origin diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg b/dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg new file mode 100644 index 00000000000..abbd189bd85 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg @@ -0,0 +1,13 @@ +# This represents a 2-D grid map +std_msgs/Header header + +# MetaData for the map +MapMetaData info + +# The map data, in row-major order, starting with (0,0). +# Cell (1, 0) will be listed second, representing the next cell in the x direction. +# Cell (0, 1) will be at the index equal to info.width, followed by (1, 1). +# The values inside are application dependent, but frequently, +# 0 represents unoccupied, 1 represents definitely occupied, and +# -1 represents unknown. +int8[] data diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg new file mode 100644 index 00000000000..7186f064bf6 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg @@ -0,0 +1,15 @@ +# This represents an estimate of a position and velocity in free space. +# The pose in this message should be specified in the coordinate frame given by header.frame_id +# The twist in this message should be specified in the coordinate frame given by the child_frame_id + +# Includes the frame id of the pose parent. +std_msgs/Header header + +# Frame id the pose points to. The twist is in this coordinate frame. +string child_frame_id + +# Estimated pose that is typically relative to a fixed world frame. +geometry_msgs/PoseWithCovariance pose + +# Estimated linear and angular velocity relative to child_frame_id. +geometry_msgs/TwistWithCovariance twist diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Path.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Path.msg new file mode 100644 index 00000000000..8be8de72916 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/Path.msg @@ -0,0 +1,7 @@ +# An array of poses that represents a Path for a robot to follow. + +# Indicates the frame_id of the path. +std_msgs/Header header + +# Array of poses to follow. +geometry_msgs/PoseStamped[] poses diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg new file mode 100644 index 00000000000..cb796629465 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg @@ -0,0 +1,7 @@ +# An array of trajectory points that represents a trajectory for a robot to follow. + +# Indicates the frame_id in which the planner ran and timestamp represents when the trajectory was generated. +std_msgs/Header header + +# Array of trajectory points to follow. +TrajectoryPoint[] points diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg b/dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg new file mode 100644 index 00000000000..dde4b17fbc6 --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg @@ -0,0 +1,16 @@ +# Trajectory point state + +# Absolute time and frame of reference of the point along a trajectory +std_msgs/Header header + +# Pose of the trajectory sample. +geometry_msgs/Pose pose + +# Velocity of the trajectory sample. +geometry_msgs/Twist velocity + +# Acceleration of the trajectory (optional, linear.x component is NaN if not set). +geometry_msgs/Accel acceleration + +# Force/Torque to apply at trajectory sample (optional, force.x component is NaN if not set). +geometry_msgs/Wrench effort diff --git a/dimos/message_codegen/schemas/nav_msgs/package.xml b/dimos/message_codegen/schemas/nav_msgs/package.xml new file mode 100644 index 00000000000..20e73abba5f --- /dev/null +++ b/dimos/message_codegen/schemas/nav_msgs/package.xml @@ -0,0 +1,34 @@ + + + + nav_msgs + 5.3.8 + A package containing some navigation related message and service definitions. + + Tully Foote + + Apache License 2.0 + + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + William Woodall + + ament_cmake + + rosidl_default_generators + + builtin_interfaces + geometry_msgs + std_msgs + + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/rosidl_adapter/package.xml b/dimos/message_codegen/schemas/rosidl_adapter/package.xml new file mode 100644 index 00000000000..49ac663bf15 --- /dev/null +++ b/dimos/message_codegen/schemas/rosidl_adapter/package.xml @@ -0,0 +1,36 @@ + + + + rosidl_adapter + 4.6.9 + + API and scripts to parse .msg/.srv/.action files and convert them to .idl. + + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + + ament_cmake_core + python3 + + ament_cmake + + python3-empy + rosidl_cli + + ament_cmake_pytest + ament_lint_common + ament_lint_auto + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/sensor_msgs/LICENSE b/dimos/message_codegen/schemas/sensor_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg new file mode 100644 index 00000000000..c42ed6e1133 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg @@ -0,0 +1,54 @@ + +# Constants are chosen to match the enums in the linux kernel +# defined in include/linux/power_supply.h as of version 3.7 +# The one difference is for style reasons the constants are +# all uppercase not mixed case. + +# Power supply status constants +uint8 POWER_SUPPLY_STATUS_UNKNOWN = 0 +uint8 POWER_SUPPLY_STATUS_CHARGING = 1 +uint8 POWER_SUPPLY_STATUS_DISCHARGING = 2 +uint8 POWER_SUPPLY_STATUS_NOT_CHARGING = 3 +uint8 POWER_SUPPLY_STATUS_FULL = 4 + +# Power supply health constants +uint8 POWER_SUPPLY_HEALTH_UNKNOWN = 0 +uint8 POWER_SUPPLY_HEALTH_GOOD = 1 +uint8 POWER_SUPPLY_HEALTH_OVERHEAT = 2 +uint8 POWER_SUPPLY_HEALTH_DEAD = 3 +uint8 POWER_SUPPLY_HEALTH_OVERVOLTAGE = 4 +uint8 POWER_SUPPLY_HEALTH_UNSPEC_FAILURE = 5 +uint8 POWER_SUPPLY_HEALTH_COLD = 6 +uint8 POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE = 7 +uint8 POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE = 8 + +# Power supply technology (chemistry) constants +uint8 POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0 # Unknown battery technology +uint8 POWER_SUPPLY_TECHNOLOGY_NIMH = 1 # Nickel-Metal Hydride battery +uint8 POWER_SUPPLY_TECHNOLOGY_LION = 2 # Lithium-ion battery +uint8 POWER_SUPPLY_TECHNOLOGY_LIPO = 3 # Lithium Polymer battery +uint8 POWER_SUPPLY_TECHNOLOGY_LIFE = 4 # Lithium Iron Phosphate battery +uint8 POWER_SUPPLY_TECHNOLOGY_NICD = 5 # Nickel-Cadmium battery +uint8 POWER_SUPPLY_TECHNOLOGY_LIMN = 6 # Lithium Manganese Dioxide battery +uint8 POWER_SUPPLY_TECHNOLOGY_TERNARY = 7 # Ternary Lithium battery +uint8 POWER_SUPPLY_TECHNOLOGY_VRLA = 8 # Valve Regulated Lead-Acid battery + +std_msgs/Header header +float32 voltage # Voltage in Volts (Mandatory) +float32 temperature # Temperature in Degrees Celsius (If unmeasured NaN) +float32 current # Negative when discharging (A) (If unmeasured NaN) +float32 charge # Current charge in Ah (If unmeasured NaN) +float32 capacity # Capacity in Ah (last full capacity) (If unmeasured NaN) +float32 design_capacity # Capacity in Ah (design capacity) (If unmeasured NaN) +float32 percentage # Charge percentage on 0 to 1 range (If unmeasured NaN) +uint8 power_supply_status # The charging status as reported. Values defined above +uint8 power_supply_health # The battery health metric. Values defined above +uint8 power_supply_technology # The battery chemistry. Values defined above +bool present # True if the battery is present + +float32[] cell_voltage # An array of individual cell voltages for each cell in the pack + # If individual voltages unknown but number of cells known set each to NaN +float32[] cell_temperature # An array of individual cell temperatures for each cell in the pack + # If individual temperatures unknown but number of cells known set each to NaN +string location # The location into which the battery is inserted. (slot number or plug) +string serial_number # The best approximation of the battery serial number diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg new file mode 100644 index 00000000000..f2e7b0608df --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg @@ -0,0 +1,131 @@ +# This message defines meta information for a camera. It should be in a +# camera namespace on topic "camera_info" and accompanied by up to five +# image topics named: +# +# image_raw - raw data from the camera driver, possibly Bayer encoded +# image - monochrome, distorted +# image_color - color, distorted +# image_rect - monochrome, rectified +# image_rect_color - color, rectified +# +# The image_pipeline contains packages (image_proc, stereo_image_proc) +# for producing the four processed image topics from image_raw and +# camera_info. The meaning of the camera parameters are described in +# detail at http://www.ros.org/wiki/image_pipeline/CameraInfo. +# +# The image_geometry package provides a user-friendly interface to +# common operations using this meta information. If you want to, e.g., +# project a 3d point into image coordinates, we strongly recommend +# using image_geometry. +# +# If the camera is uncalibrated, the matrices D, K, R, P should be left +# zeroed out. In particular, clients may assume that K[0] == 0.0 +# indicates an uncalibrated camera. + +####################################################################### +# Image acquisition info # +####################################################################### + +# Time of image acquisition, camera coordinate frame ID +std_msgs/Header header # Header timestamp should be acquisition time of image + # Header frame_id should be optical frame of camera + # origin of frame should be optical center of camera + # +x should point to the right in the image + # +y should point down in the image + # +z should point into the plane of the image + + +####################################################################### +# Calibration Parameters # +####################################################################### +# These are fixed during camera calibration. Their values will be the # +# same in all messages until the camera is recalibrated. Note that # +# self-calibrating systems may "recalibrate" frequently. # +# # +# The internal parameters can be used to warp a raw (distorted) image # +# to: # +# 1. An undistorted image (requires D and K) # +# 2. A rectified image (requires D, K, R) # +# The projection matrix P projects 3D points into the rectified image.# +####################################################################### + +# The image dimensions with which the camera was calibrated. +# Normally this will be the full camera resolution in pixels. +uint32 height +uint32 width + +# The distortion model used. Supported models are listed in +# sensor_msgs/distortion_models.hpp. For most cameras, "plumb_bob" - a +# simple model of radial and tangential distortion - is sufficent. +string distortion_model + +# The distortion parameters, size depending on the distortion model. +# For "plumb_bob", the 5 parameters are: (k1, k2, t1, t2, k3). +float64[] d + +# Intrinsic camera matrix for the raw (distorted) images. +# [fx 0 cx] +# K = [ 0 fy cy] +# [ 0 0 1] +# Projects 3D points in the camera coordinate frame to 2D pixel +# coordinates using the focal lengths (fx, fy) and principal point +# (cx, cy). +float64[9] k # 3x3 row-major matrix + +# Rectification matrix (stereo cameras only) +# A rotation matrix aligning the camera coordinate system to the ideal +# stereo image plane so that epipolar lines in both stereo images are +# parallel. +float64[9] r # 3x3 row-major matrix + +# Projection/camera matrix +# [fx' 0 cx' Tx] +# P = [ 0 fy' cy' Ty] +# [ 0 0 1 0] +# By convention, this matrix specifies the intrinsic (camera) matrix +# of the processed (rectified) image. That is, the left 3x3 portion +# is the normal camera intrinsic matrix for the rectified image. +# It projects 3D points in the camera coordinate frame to 2D pixel +# coordinates using the focal lengths (fx', fy') and principal point +# (cx', cy') - these may differ from the values in K. +# For monocular cameras, Tx = Ty = 0. Normally, monocular cameras will +# also have R = the identity and P[1:3,1:3] = K. +# For a stereo pair, the fourth column [Tx Ty 0]' is related to the +# position of the optical center of the second camera in the first +# camera's frame. We assume Tz = 0 so both cameras are in the same +# stereo image plane. The first camera always has Tx = Ty = 0. For +# the right (second) camera of a horizontal stereo pair, Ty = 0 and +# Tx = -fx' * B, where B is the baseline between the cameras. +# Given a 3D point [X Y Z]', the projection (x, y) of the point onto +# the rectified image is given by: +# [u v w]' = P * [X Y Z 1]' +# x = u / w +# y = v / w +# This holds for both images of a stereo pair. +float64[12] p # 3x4 row-major matrix + + +####################################################################### +# Operational Parameters # +####################################################################### +# These define the image region actually captured by the camera # +# driver. Although they affect the geometry of the output image, they # +# may be changed freely without recalibrating the camera. # +####################################################################### + +# Binning refers here to any camera setting which combines rectangular +# neighborhoods of pixels into larger "super-pixels." It reduces the +# resolution of the output image to +# (width / binning_x) x (height / binning_y). +# The default values binning_x = binning_y = 0 is considered the same +# as binning_x = binning_y = 1 (no subsampling). +uint32 binning_x +uint32 binning_y + +# Region of interest (subwindow of full camera resolution), given in +# full resolution (unbinned) image coordinates. A particular ROI +# always denotes the same window of pixels on the camera sensor, +# regardless of binning settings. +# The default setting of roi (all values 0) is considered the same as +# full resolution (roi.width = width, roi.height = height). +RegionOfInterest roi diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg new file mode 100644 index 00000000000..0518d8d45e1 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg @@ -0,0 +1,24 @@ +# This message is used by the PointCloud message to hold optional data +# associated with each point in the cloud. The length of the values +# array should be the same as the length of the points array in the +# PointCloud, and each value should be associated with the corresponding +# point. +# +# Channel names in existing practice include: +# "u", "v" - row and column (respectively) in the left stereo image. +# This is opposite to usual conventions but remains for +# historical reasons. The newer PointCloud2 message has no +# such problem. +# "rgb" - For point clouds produced by color stereo cameras. uint8 +# (R,G,B) values packed into the least significant 24 bits, +# in order. +# "intensity" - laser or pixel intensity. +# "distance" + +# The channel name should give semantics of the channel (e.g. +# "intensity" instead of "value"). +string name + +# The values array should be 1-1 with the elements of the associated +# PointCloud. +float32[] values diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg new file mode 100644 index 00000000000..12a724d5647 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg @@ -0,0 +1,41 @@ +# This message contains a compressed image. + +std_msgs/Header header # Header timestamp should be acquisition time of image + # Header frame_id should be optical frame of camera + # origin of frame should be optical center of cameara + # +x should point to the right in the image + # +y should point down in the image + # +z should point into to plane of the image + +string format # Specifies the format of the data + # Acceptable values differ by the image transport used: + # - compressed_image_transport: + # ORIG_PIXFMT; CODEC compressed [COMPRESSED_PIXFMT] + # where: + # - ORIG_PIXFMT is pixel format of the raw image, i.e. + # the content of sensor_msgs/Image/encoding with + # values from include/sensor_msgs/image_encodings.h + # - CODEC is one of [jpeg, png, tiff] + # - COMPRESSED_PIXFMT is only appended for color images + # and is the pixel format used by the compression + # algorithm. Valid values for jpeg encoding are: + # [bgr8, rgb8]. Valid values for png encoding are: + # [bgr8, rgb8, bgr16, rgb16]. + # If the field is empty or does not correspond to the + # above pattern, the image is treated as bgr8 or mono8 + # jpeg image (depending on the number of channels). + # - compressed_depth_image_transport: + # ORIG_PIXFMT; compressedDepth CODEC + # where: + # - ORIG_PIXFMT is pixel format of the raw image, i.e. + # the content of sensor_msgs/Image/encoding with + # values from include/sensor_msgs/image_encodings.h + # It is usually one of [16UC1, 32FC1]. + # - CODEC is one of [png, rvl] + # If the field is empty or does not correspond to the + # above pattern, the image is treated as png image. + # - Other image transports can store whatever values they + # need for successful decoding of the image. Refer to + # documentation of the other transports for details. + +uint8[] data # Compressed image buffer diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg new file mode 100644 index 00000000000..2350d615ea8 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg @@ -0,0 +1,12 @@ +# Single pressure reading. This message is appropriate for measuring the +# pressure inside of a fluid (air, water, etc). This also includes +# atmospheric or barometric pressure. +# +# This message is not appropriate for force/pressure contact sensors. + +std_msgs/Header header # timestamp of the measurement + # frame_id is the location of the pressure sensor + +float64 fluid_pressure # Absolute pressure reading in Pascals. + +float64 variance # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg new file mode 100644 index 00000000000..43cd8e7196e --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg @@ -0,0 +1,20 @@ +# Single photometric illuminance measurement. Light should be assumed to be +# measured along the sensor's x-axis (the area of detection is the y-z plane). +# The illuminance should have a 0 or positive value and be received with +# the sensor's +X axis pointing toward the light source. +# +# Photometric illuminance is the measure of the human eye's sensitivity of the +# intensity of light encountering or passing through a surface. +# +# All other Photometric and Radiometric measurements should not use this message. +# This message cannot represent: +# - Luminous intensity (candela/light source output) +# - Luminance (nits/light output per area) +# - Irradiance (watt/area), etc. + +std_msgs/Header header # timestamp is the time the illuminance was measured + # frame_id is the location and direction of the reading + +float64 illuminance # Measurement of the Photometric Illuminance in Lux. + +float64 variance # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg new file mode 100644 index 00000000000..c13efdf78ed --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg @@ -0,0 +1,26 @@ +# This message contains an uncompressed image +# (0, 0) is at top-left corner of image + +std_msgs/Header header # Header timestamp should be acquisition time of image + # Header frame_id should be optical frame of camera + # origin of frame should be optical center of cameara + # +x should point to the right in the image + # +y should point down in the image + # +z should point into to plane of the image + # If the frame_id here and the frame_id of the CameraInfo + # message associated with the image conflict + # the behavior is undefined + +uint32 height # image height, that is, number of rows +uint32 width # image width, that is, number of columns + +# The legal values for encoding are in file include/sensor_msgs/image_encodings.hpp +# If you want to standardize a new string format, join +# ros-users@lists.ros.org and send an email proposing a new encoding. + +string encoding # Encoding of pixels -- channel meaning, ordering, size + # taken from the list of strings in include/sensor_msgs/image_encodings.hpp + +uint8 is_bigendian # is this data bigendian? +uint32 step # Full row length in bytes +uint8[] data # actual matrix data, size is (step * rows) diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg new file mode 100644 index 00000000000..8d8a6bdaf34 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg @@ -0,0 +1,24 @@ +# This is a message to hold data from an IMU (Inertial Measurement Unit) +# +# Accelerations should be in m/s^2 (not in g's), and rotational velocity should be in rad/sec +# +# If the covariance of the measurement is known, it should be filled in (if all you know is the +# variance of each measurement, e.g. from the datasheet, just put those along the diagonal) +# A covariance matrix of all zeros will be interpreted as "covariance unknown", and to use the +# data a covariance will have to be assumed or gotten from some other source +# +# If you have no estimate for one of the data elements (e.g. your IMU doesn't produce an +# orientation estimate), please set element 0 of the associated covariance matrix to -1 +# If you are interpreting this message, please check for a value of -1 in the first element of each +# covariance matrix, and disregard the associated estimate. + +std_msgs/Header header + +geometry_msgs/Quaternion orientation +float64[9] orientation_covariance # Row major about x, y, z axes + +geometry_msgs/Vector3 angular_velocity +float64[9] angular_velocity_covariance # Row major about x, y, z axes + +geometry_msgs/Vector3 linear_acceleration +float64[9] linear_acceleration_covariance # Row major x, y z diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg new file mode 100644 index 00000000000..ffaa9bfb005 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg @@ -0,0 +1,25 @@ +# This is a message that holds data to describe the state of a set of torque controlled joints. +# +# The state of each joint (revolute or prismatic) is defined by: +# * the position of the joint (rad or m), +# * the velocity of the joint (rad/s or m/s) and +# * the effort that is applied in the joint (Nm or N). +# +# Each joint is uniquely identified by its name +# The header specifies the time at which the joint states were recorded. All the joint states +# in one message have to be recorded at the same time. +# +# This message consists of a multiple arrays, one for each part of the joint state. +# The goal is to make each of the fields optional. When e.g. your joints have no +# effort associated with them, you can leave the effort array empty. +# +# All arrays in this message should have the same size, or be empty. +# This is the only way to uniquely associate the joint name with the correct +# states. + +std_msgs/Header header + +string[] name +float64[] position +float64[] velocity +float64[] effort diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg new file mode 100644 index 00000000000..ca7801fe286 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg @@ -0,0 +1,10 @@ +# Reports the state of a joystick's axes and buttons. + +# The timestamp is the time at which data is received from the joystick. +std_msgs/Header header + +# The axes measurements from a joystick. +float32[] axes + +# The buttons measurements from a joystick. +int32[] buttons diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg new file mode 100644 index 00000000000..153cc093359 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg @@ -0,0 +1,14 @@ +# Declare of the type of feedback +uint8 TYPE_LED = 0 +uint8 TYPE_RUMBLE = 1 +uint8 TYPE_BUZZER = 2 + +uint8 type + +# This will hold an id number for each type of each feedback. +# Example, the first led would be id=0, the second would be id=1 +uint8 id + +# Intensity of the feedback, from 0.0 to 1.0, inclusive. If device is +# actually binary, driver should treat 0<=x<0.5 as off, 0.5<=x<=1 as on. +float32 intensity diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg new file mode 100644 index 00000000000..f6981b8c48b --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg @@ -0,0 +1,2 @@ +# This message publishes values for multiple feedback at once. +JoyFeedback[] array diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg new file mode 100644 index 00000000000..cefdecfe0f2 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg @@ -0,0 +1,5 @@ +# This message is a submessage of MultiEchoLaserScan and is not intended +# to be used separately. + +float32[] echoes # Multiple values of ranges or intensities. + # Each array represents data from the same angle increment. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg new file mode 100644 index 00000000000..6e5c2a1c7cd --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg @@ -0,0 +1,30 @@ +# Single scan from a planar laser range-finder +# +# If you have another ranging device with different behavior (e.g. a sonar +# array), please find or create a different message, since applications +# will make fairly laser-specific assumptions about this data + +std_msgs/Header header # timestamp in the header is the acquisition time of + # the first ray in the scan. + # + # in frame frame_id, angles are measured around + # the positive Z axis (counterclockwise, if Z is up) + # with zero angle being forward along the x axis + +float32 angle_min # start angle of the scan [rad] +float32 angle_max # end angle of the scan [rad] +float32 angle_increment # angular distance between measurements [rad] + +float32 time_increment # time between measurements [seconds] - if your scanner + # is moving, this will be used in interpolating position + # of 3d points +float32 scan_time # time between scans [seconds] + +float32 range_min # minimum range value [m] +float32 range_max # maximum range value [m] + +float32[] ranges # range data [m] + # (Note: values < range_min or > range_max should be discarded) +float32[] intensities # intensity data [device-specific units]. If your + # device does not provide intensities, please leave + # the array empty. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg new file mode 100644 index 00000000000..a0468fa7c21 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg @@ -0,0 +1,21 @@ +# Measurement of the Magnetic Field vector at a specific location. +# +# If the covariance of the measurement is known, it should be filled in. +# If all you know is the variance of each measurement, e.g. from the datasheet, +# just put those along the diagonal. +# A covariance matrix of all zeros will be interpreted as "covariance unknown", +# and to use the data a covariance will have to be assumed or gotten from some +# other source. + +std_msgs/Header header # timestamp is the time the + # field was measured + # frame_id is the location and orientation + # of the field measurement + +geometry_msgs/Vector3 magnetic_field # x, y, and z components of the + # field vector in Tesla + # If your sensor does not output 3 axes, + # put NaNs in the components not reported. + +float64[9] magnetic_field_covariance # Row major about x, y, z axes + # 0 is interpreted as variance unknown \ No newline at end of file diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg new file mode 100644 index 00000000000..59edcefbb17 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg @@ -0,0 +1,26 @@ +# Representation of state for joints with multiple degrees of freedom, +# following the structure of JointState which can only represent a single degree of freedom. +# +# It is assumed that a joint in a system corresponds to a transform that gets applied +# along the kinematic chain. For example, a planar joint (as in URDF) is 3DOF (x, y, yaw) +# and those 3DOF can be expressed as a transformation matrix, and that transformation +# matrix can be converted back to (x, y, yaw) +# +# Each joint is uniquely identified by its name +# The header specifies the time at which the joint states were recorded. All the joint states +# in one message have to be recorded at the same time. +# +# This message consists of a multiple arrays, one for each part of the joint state. +# The goal is to make each of the fields optional. When e.g. your joints have no +# wrench associated with them, you can leave the wrench array empty. +# +# All arrays in this message should have the same size, or be empty. +# This is the only way to uniquely associate the joint name with the correct +# states. + +std_msgs/Header header + +string[] joint_names +geometry_msgs/Transform[] transforms +geometry_msgs/Twist[] twist +geometry_msgs/Wrench[] wrench diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg new file mode 100644 index 00000000000..47d1b9f7169 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg @@ -0,0 +1,32 @@ +# Single scan from a multi-echo planar laser range-finder +# +# If you have another ranging device with different behavior (e.g. a sonar +# array), please find or create a different message, since applications +# will make fairly laser-specific assumptions about this data + +std_msgs/Header header # timestamp in the header is the acquisition time of + # the first ray in the scan. + # + # in frame frame_id, angles are measured around + # the positive Z axis (counterclockwise, if Z is up) + # with zero angle being forward along the x axis + +float32 angle_min # start angle of the scan [rad] +float32 angle_max # end angle of the scan [rad] +float32 angle_increment # angular distance between measurements [rad] + +float32 time_increment # time between measurements [seconds] - if your scanner + # is moving, this will be used in interpolating position + # of 3d points +float32 scan_time # time between scans [seconds] + +float32 range_min # minimum range value [m] +float32 range_max # maximum range value [m] + +LaserEcho[] ranges # range data [m] + # (Note: NaNs, values < range_min or > range_max should be discarded) + # +Inf measurements are out of range + # -Inf measurements are too close to determine exact distance. +LaserEcho[] intensities # intensity data [device-specific units]. If your + # device does not provide intensities, please leave + # the array empty. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg new file mode 100644 index 00000000000..3c4e9770a5d --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg @@ -0,0 +1,45 @@ +# Navigation Satellite fix for any Global Navigation Satellite System +# +# Specified using the WGS 84 reference ellipsoid + +# header.stamp specifies the ROS time for this measurement (the +# corresponding satellite time may be reported using the +# sensor_msgs/TimeReference message). +# +# header.frame_id is the frame of reference reported by the satellite +# receiver, usually the location of the antenna. This is a +# Euclidean frame relative to the vehicle, not a reference +# ellipsoid. +std_msgs/Header header + +# Satellite fix status information. +NavSatStatus status + +# Latitude [degrees]. Positive is north of equator; negative is south. +float64 latitude + +# Longitude [degrees]. Positive is east of prime meridian; negative is west. +float64 longitude + +# Altitude [m]. Positive is above the WGS 84 ellipsoid +# (quiet NaN if no altitude is available). +float64 altitude + +# Position covariance [m^2] defined relative to a tangential plane +# through the reported position. The components are East, North, and +# Up (ENU), in row-major order. +# +# Beware: this coordinate system exhibits singularities at the poles. +float64[9] position_covariance + +# If the covariance of the fix is known, fill it in completely. If the +# GPS receiver provides the variance of each measurement, put them +# along the diagonal. If only Dilution of Precision is available, +# estimate an approximate covariance from that. + +uint8 COVARIANCE_TYPE_UNKNOWN = 0 +uint8 COVARIANCE_TYPE_APPROXIMATED = 1 +uint8 COVARIANCE_TYPE_DIAGONAL_KNOWN = 2 +uint8 COVARIANCE_TYPE_KNOWN = 3 + +uint8 position_covariance_type diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg new file mode 100644 index 00000000000..ae03056d82a --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg @@ -0,0 +1,24 @@ +# Navigation Satellite fix status for any Global Navigation Satellite System. +# +# Whether to output an augmented fix is determined by both the fix +# type and the last time differential corrections were received. A +# fix is valid when status >= STATUS_FIX. + +int8 STATUS_UNKNOWN = -2 # status is not yet set +int8 STATUS_NO_FIX = -1 # unable to fix position +int8 STATUS_FIX = 0 # unaugmented fix +int8 STATUS_SBAS_FIX = 1 # with satellite-based augmentation +int8 STATUS_GBAS_FIX = 2 # with ground-based augmentation + +int8 status -2 # STATUS_UNKNOWN + +# Bits defining which Global Navigation Satellite System signals were +# used by the receiver. + +uint16 SERVICE_UNKNOWN = 0 # Remember service is a bitfield, so checking (service & SERVICE_UNKNOWN) will not work. Use == instead. +uint16 SERVICE_GPS = 1 +uint16 SERVICE_GLONASS = 2 +uint16 SERVICE_COMPASS = 4 # includes BeiDou. +uint16 SERVICE_GALILEO = 8 + +uint16 service diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg new file mode 100644 index 00000000000..a07d45048e6 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg @@ -0,0 +1,17 @@ +## THIS MESSAGE IS DEPRECATED AS OF FOXY +## Please use sensor_msgs/PointCloud2 + +# This message holds a collection of 3d points, plus optional additional +# information about each point. + +# Time of sensor data acquisition, coordinate frame ID. +std_msgs/Header header + +# Array of 3d points. Each Point32 should be interpreted as a 3d point +# in the frame given in the header. +geometry_msgs/Point32[] points + +# Each channel should have the same number of elements as points array, +# and the data in each channel should correspond 1:1 with each point. +# Channel names in common practice are listed in ChannelFloat32.msg. +ChannelFloat32[] channels diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg new file mode 100644 index 00000000000..0b27897ec7c --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg @@ -0,0 +1,26 @@ +# This message holds a collection of N-dimensional points, which may +# contain additional information such as normals, intensity, etc. The +# point data is stored as a binary blob, its layout described by the +# contents of the "fields" array. +# +# The point cloud data may be organized 2d (image-like) or 1d (unordered). +# Point clouds organized as 2d images may be produced by camera depth sensors +# such as stereo or time-of-flight. + +# Time of sensor data acquisition, and the coordinate frame ID (for 3d points). +std_msgs/Header header + +# 2D structure of the point cloud. If the cloud is unordered, height is +# 1 and width is the length of the point cloud. +uint32 height +uint32 width + +# Describes the channels and their layout in the binary data blob. +PointField[] fields + +bool is_bigendian # Is this data bigendian? +uint32 point_step # Length of a point in bytes +uint32 row_step # Length of a row in bytes +uint8[] data # Actual point data, size is (row_step*height) + +bool is_dense # True if there are no invalid points diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg new file mode 100644 index 00000000000..920bc4dd6c7 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg @@ -0,0 +1,16 @@ +# This message holds the description of one point entry in the +# PointCloud2 message format. +uint8 INT8 = 1 +uint8 UINT8 = 2 +uint8 INT16 = 3 +uint8 UINT16 = 4 +uint8 INT32 = 5 +uint8 UINT32 = 6 +uint8 FLOAT32 = 7 +uint8 FLOAT64 = 8 + +# Common PointField names are x, y, z, intensity, rgb, rgba +string name # Name of field +uint32 offset # Offset from start of point struct +uint8 datatype # Datatype enumeration, see above +uint32 count # How many elements in the field diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg new file mode 100644 index 00000000000..ed3a93b0661 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg @@ -0,0 +1,42 @@ +# Single range reading from an active ranger that emits energy and reports +# one range reading that is valid along an arc at the distance measured. +# This message is not appropriate for laser scanners. See the LaserScan +# message if you are working with a laser scanner. +# +# This message also can represent a fixed-distance (binary) ranger. This +# sensor will have min_range===max_range===distance of detection. +# These sensors follow REP 117 and will output -Inf if the object is detected +# and +Inf if the object is outside of the detection range. + +std_msgs/Header header # timestamp in the header is the time the ranger + # returned the distance reading + +# Radiation type enums +# If you want a value added to this list, send an email to the ros-users list +uint8 ULTRASOUND=0 +uint8 INFRARED=1 + +uint8 radiation_type # the type of radiation used by the sensor + # (sound, IR, etc) [enum] + +float32 field_of_view # the size of the arc that the distance reading is + # valid for [rad] + # the object causing the range reading may have + # been anywhere within -field_of_view/2 and + # field_of_view/2 at the measured range. + # 0 angle corresponds to the x-axis of the sensor. + +float32 min_range # minimum range value [m] +float32 max_range # maximum range value [m] + # Fixed distance rangers require min_range==max_range + +float32 range # range data [m] + # (Note: values < range_min or > range_max should be discarded) + # Fixed distance rangers only output -Inf or +Inf. + # -Inf represents a detection within fixed distance. + # (Detection too close to the sensor to quantify) + # +Inf represents no detection within the fixed distance. + # (Object out of range) + +float32 variance # variance of the range sensor + # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg new file mode 100644 index 00000000000..c423dcf8895 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg @@ -0,0 +1,19 @@ +# This message is used to specify a region of interest within an image. +# +# When used to specify the ROI setting of the camera when the image was +# taken, the height and width fields should either match the height and +# width fields for the associated image; or height = width = 0 +# indicates that the full resolution image was captured. + +uint32 x_offset # Leftmost pixel of the ROI + # (0 if the ROI includes the left edge of the image) +uint32 y_offset # Topmost pixel of the ROI + # (0 if the ROI includes the top edge of the image) +uint32 height # Height of ROI +uint32 width # Width of ROI + +# True if a distinct rectified ROI should be calculated from the "raw" +# ROI in this message. Typically this should be False if the full image +# is captured (ROI not used), and True if a subwindow is captured (ROI +# used). +bool do_rectify diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg new file mode 100644 index 00000000000..b32398f81e8 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg @@ -0,0 +1,13 @@ +# Single reading from a relative humidity sensor. +# Defines the ratio of partial pressure of water vapor to the saturated vapor +# pressure at a temperature. + +std_msgs/Header header # timestamp of the measurement + # frame_id is the location of the humidity sensor + +float64 relative_humidity # Expression of the relative humidity + # from 0.0 to 1.0. + # 0.0 is no partial pressure of water vapor + # 1.0 represents partial pressure of saturation + +float64 variance # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg new file mode 100644 index 00000000000..ca992850b0e --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg @@ -0,0 +1,8 @@ +# Single temperature reading. + +std_msgs/Header header # timestamp is the time the temperature was measured + # frame_id is the location of the temperature reading + +float64 temperature # Measurement of the Temperature in Degrees Celsius. + +float64 variance # 0 is interpreted as variance unknown. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg new file mode 100644 index 00000000000..6f93c0e2b38 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg @@ -0,0 +1,7 @@ +# Measurement from an external time source not actively synchronized with the system clock. + +std_msgs/Header header # stamp is system time for which measurement was valid + # frame_id is not used + +builtin_interfaces/Time time_ref # corresponding time from this external source +string source # (optional) name of time source diff --git a/dimos/message_codegen/schemas/sensor_msgs/package.xml b/dimos/message_codegen/schemas/sensor_msgs/package.xml new file mode 100644 index 00000000000..bfab23e6112 --- /dev/null +++ b/dimos/message_codegen/schemas/sensor_msgs/package.xml @@ -0,0 +1,37 @@ + + + + sensor_msgs + 5.3.8 + A package containing some sensor data related message and service definitions. + + Tully Foote + + Apache License 2.0 + + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + William Woodall + + ament_cmake + + rosidl_default_generators + + builtin_interfaces + geometry_msgs + std_msgs + + rosidl_default_runtime + + ament_cmake_gtest + ament_lint_auto + ament_lint_common + rosidl_cmake + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/shape_msgs/LICENSE b/dimos/message_codegen/schemas/shape_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/shape_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg b/dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg new file mode 100644 index 00000000000..2c3b0d03df2 --- /dev/null +++ b/dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg @@ -0,0 +1,7 @@ +# Definition of a mesh. + +# List of triangles; the index values refer to positions in vertices[]. +MeshTriangle[] triangles + +# The actual vertices that make up the mesh. +geometry_msgs/Point[] vertices diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg b/dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg new file mode 100644 index 00000000000..9de74df9b0f --- /dev/null +++ b/dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg @@ -0,0 +1,3 @@ +# Definition of a triangle's vertices. + +uint32[3] vertex_indices diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg b/dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg new file mode 100644 index 00000000000..9d8a43a8459 --- /dev/null +++ b/dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg @@ -0,0 +1,7 @@ +# Representation of a plane, using the plane equation ax + by + cz + d = 0. +# +# a := coef[0] +# b := coef[1] +# c := coef[2] +# d := coef[3] +float64[4] coef diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg b/dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg new file mode 100644 index 00000000000..b9014ad75d2 --- /dev/null +++ b/dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg @@ -0,0 +1,50 @@ +# Defines box, sphere, cylinder, cone and prism. +# All shapes are defined to have their bounding boxes centered around 0,0,0. + +uint8 BOX=1 +uint8 SPHERE=2 +uint8 CYLINDER=3 +uint8 CONE=4 +uint8 PRISM=5 + +# The type of the shape +uint8 type + +# The dimensions of the shape +float64[<=3] dimensions # At no point will dimensions have a length > 3. + +# The meaning of the shape dimensions: each constant defines the index in the 'dimensions' array. + +# For type BOX, the X, Y, and Z dimensions are the length of the corresponding sides of the box. +uint8 BOX_X=0 +uint8 BOX_Y=1 +uint8 BOX_Z=2 + +# For the SPHERE type, only one component is used, and it gives the radius of the sphere. +uint8 SPHERE_RADIUS=0 + +# For the CYLINDER and CONE types, the center line is oriented along the Z axis. +# Therefore the CYLINDER_HEIGHT (CONE_HEIGHT) component of dimensions gives the +# height of the cylinder (cone). +# The CYLINDER_RADIUS (CONE_RADIUS) component of dimensions gives the radius of +# the base of the cylinder (cone). +# Cone and cylinder primitives are defined to be circular. The tip of the cone +# is pointing up, along +Z axis. + +uint8 CYLINDER_HEIGHT=0 +uint8 CYLINDER_RADIUS=1 + +uint8 CONE_HEIGHT=0 +uint8 CONE_RADIUS=1 + +# For the type PRISM, the center line is oriented along Z axis. +# The PRISM_HEIGHT component of dimensions gives the +# height of the prism. +# The polygon defines the Z axis centered base of the prism. +# The prism is constructed by extruding the base in +Z and -Z +# directions by half of the PRISM_HEIGHT +# Only x and y fields of the points are used in the polygon. +# Points of the polygon are ordered counter-clockwise. + +uint8 PRISM_HEIGHT=0 +geometry_msgs/Polygon polygon diff --git a/dimos/message_codegen/schemas/shape_msgs/package.xml b/dimos/message_codegen/schemas/shape_msgs/package.xml new file mode 100644 index 00000000000..43cd5cd3968 --- /dev/null +++ b/dimos/message_codegen/schemas/shape_msgs/package.xml @@ -0,0 +1,31 @@ + + + + shape_msgs + 5.3.8 + A package containing some message definitions which describe geometric shapes. + + Tully Foote + + Apache License 2.0 + + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + William Woodall + + ament_cmake + + rosidl_default_generators + + geometry_msgs + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/std_msgs/LICENSE b/dimos/message_codegen/schemas/std_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Bool.msg b/dimos/message_codegen/schemas/std_msgs/msg/Bool.msg new file mode 100644 index 00000000000..ffd399ea7eb --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Bool.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +bool data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Byte.msg b/dimos/message_codegen/schemas/std_msgs/msg/Byte.msg new file mode 100644 index 00000000000..400d445c18a --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Byte.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +byte data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg new file mode 100644 index 00000000000..ac6ce0c8c75 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +byte[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Char.msg b/dimos/message_codegen/schemas/std_msgs/msg/Char.msg new file mode 100644 index 00000000000..eb3abbf6f86 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Char.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +char data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg b/dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg new file mode 100644 index 00000000000..182dbc8349a --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg @@ -0,0 +1,4 @@ +float32 r +float32 g +float32 b +float32 a diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Empty.msg b/dimos/message_codegen/schemas/std_msgs/msg/Empty.msg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float32.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float32.msg new file mode 100644 index 00000000000..ed3fc9d23a7 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Float32.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +float32 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg new file mode 100644 index 00000000000..82a85ae3ae7 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +float32[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float64.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float64.msg new file mode 100644 index 00000000000..9f78c835392 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Float64.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +float64 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg new file mode 100644 index 00000000000..43d7ab7378b --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +float64[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Header.msg b/dimos/message_codegen/schemas/std_msgs/msg/Header.msg new file mode 100644 index 00000000000..6966bb98863 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Header.msg @@ -0,0 +1,9 @@ +# Standard metadata for higher-level stamped data types. +# This is generally used to communicate timestamped data +# in a particular coordinate frame. + +# Two-integer timestamp that is expressed as seconds and nanoseconds. +builtin_interfaces/Time stamp + +# Transform frame with which this data is associated. +string frame_id diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int16.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int16.msg new file mode 100644 index 00000000000..31429678cff --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int16.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +int16 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg new file mode 100644 index 00000000000..db6f56b78a0 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int16[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int32.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int32.msg new file mode 100644 index 00000000000..e4dc836038e --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int32.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +int32 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg new file mode 100644 index 00000000000..67c5f40f5bb --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int32[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int64.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int64.msg new file mode 100644 index 00000000000..fbc143a7dcb --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int64.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +int64 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg new file mode 100644 index 00000000000..ea34ee81d5b --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int64[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int8.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int8.msg new file mode 100644 index 00000000000..d44e8cbb116 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int8.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +int8 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg new file mode 100644 index 00000000000..8ab6b543e8b --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int8[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg b/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg new file mode 100644 index 00000000000..ab0376b4fc5 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg @@ -0,0 +1,8 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +string label # label of given dimension +uint32 size # size of given dimension (in type units) +uint32 stride # stride of given dimension diff --git a/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg b/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg new file mode 100644 index 00000000000..06f2fea3de3 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg @@ -0,0 +1,31 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# The multiarray declares a generic multi-dimensional array of a +# particular data type. Dimensions are ordered from outer most +# to inner most. +# +# Accessors should ALWAYS be written in terms of dimension stride +# and specified outer-most dimension first. +# +# multiarray(i,j,k) = data[data_offset + dim_stride[1]*i + dim_stride[2]*j + k] +# +# A standard, 3-channel 640x480 image with interleaved color channels +# would be specified as: +# +# dim[0].label = "height" +# dim[0].size = 480 +# dim[0].stride = 3*640*480 = 921600 (note dim[0] stride is just size of image) +# dim[1].label = "width" +# dim[1].size = 640 +# dim[1].stride = 3*640 = 1920 +# dim[2].label = "channel" +# dim[2].size = 3 +# dim[2].stride = 3 +# +# multiarray(i,j,k) refers to the ith row, jth column, and kth channel. + +MultiArrayDimension[] dim # Array of dimension properties +uint32 data_offset # padding bytes at front of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/String.msg b/dimos/message_codegen/schemas/std_msgs/msg/String.msg new file mode 100644 index 00000000000..82c18e55326 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/String.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +string data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg new file mode 100644 index 00000000000..6e0c9054223 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +uint16 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg new file mode 100644 index 00000000000..cb51b70447c --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint16[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg new file mode 100644 index 00000000000..5723cbc8edf --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +uint32 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg new file mode 100644 index 00000000000..6750d1803ed --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint32[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg new file mode 100644 index 00000000000..330cab9830d --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +uint64 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg new file mode 100644 index 00000000000..e5dc3f8ebd1 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint64[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg new file mode 100644 index 00000000000..f04b64f3d17 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg @@ -0,0 +1,6 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +uint8 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg new file mode 100644 index 00000000000..74b3825b60f --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg @@ -0,0 +1,10 @@ +# This was originally provided as an example message. +# It is deprecated as of Foxy +# It is recommended to create your own semantically meaningful message. +# However if you would like to continue using this please use the equivalent in example_msgs. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint8[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/package.xml b/dimos/message_codegen/schemas/std_msgs/package.xml new file mode 100644 index 00000000000..5b586c7ab24 --- /dev/null +++ b/dimos/message_codegen/schemas/std_msgs/package.xml @@ -0,0 +1,31 @@ + + + + std_msgs + 5.3.8 + A package containing some standard message definitions. + + Tully Foote + + Apache License 2.0 + + Dirk Thomas + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + + ament_cmake + + rosidl_default_generators + + builtin_interfaces + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg b/dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg new file mode 100644 index 00000000000..e737b64698f --- /dev/null +++ b/dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg @@ -0,0 +1,10 @@ +uint8 NO_ERROR = 0 +uint8 LOOKUP_ERROR = 1 +uint8 CONNECTIVITY_ERROR = 2 +uint8 EXTRAPOLATION_ERROR = 3 +uint8 INVALID_ARGUMENT_ERROR = 4 +uint8 TIMEOUT_ERROR = 5 +uint8 TRANSFORM_ERROR = 6 + +uint8 error +string error_string diff --git a/dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg b/dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg new file mode 100644 index 00000000000..fda1e4d0985 --- /dev/null +++ b/dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg @@ -0,0 +1 @@ +geometry_msgs/TransformStamped[] transforms diff --git a/dimos/message_codegen/schemas/tf2_msgs/package.xml b/dimos/message_codegen/schemas/tf2_msgs/package.xml new file mode 100644 index 00000000000..17f6b9bdb88 --- /dev/null +++ b/dimos/message_codegen/schemas/tf2_msgs/package.xml @@ -0,0 +1,36 @@ + + + + tf2_msgs + 0.36.23 + + tf2_msgs + + + Alejandro Hernandez Cordero + Chris Lalancette + + BSD + http://www.ros.org/wiki/tf2_msgs + + Eitan Marder-Eppstein + Tully Foote + + ament_cmake + rosidl_default_generators + + builtin_interfaces + geometry_msgs + + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + + + diff --git a/dimos/message_codegen/schemas/trajectory_msgs/LICENSE b/dimos/message_codegen/schemas/trajectory_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/trajectory_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg new file mode 100644 index 00000000000..a5d219880f7 --- /dev/null +++ b/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg @@ -0,0 +1,11 @@ +# The header is used to specify the coordinate frame and the reference time for +# the trajectory durations +std_msgs/Header header + +# The names of the active joints in each trajectory point. These names are +# ordered and must correspond to the values in each trajectory point. +string[] joint_names + +# Array of trajectory points, which describe the positions, velocities, +# accelerations and/or efforts of the joints at each time point. +JointTrajectoryPoint[] points diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg new file mode 100644 index 00000000000..01e38a4562e --- /dev/null +++ b/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg @@ -0,0 +1,26 @@ +# Each trajectory point specifies either positions[, velocities[, accelerations]] +# or positions[, effort] for the trajectory to be executed. +# All specified values are in the same order as the joint names in JointTrajectory.msg. + +# Single DOF joint positions for each joint relative to their "0" position. +# The units depend on the specific joint type: radians for revolute or +# continuous joints, and meters for prismatic joints. +float64[] positions + +# The rate of change in position of each joint. Units are joint type dependent. +# Radians/second for revolute or continuous joints, and meters/second for +# prismatic joints. +float64[] velocities + +# Rate of change in velocity of each joint. Units are joint type dependent. +# Radians/second^2 for revolute or continuous joints, and meters/second^2 for +# prismatic joints. +float64[] accelerations + +# The torque or the force to be applied at each joint. For revolute/continuous +# joints effort denotes a torque in newton-meters. For prismatic joints, effort +# denotes a force in newtons. +float64[] effort + +# Desired time from the trajectory start to arrive at this trajectory point. +builtin_interfaces/Duration time_from_start diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg new file mode 100644 index 00000000000..155fdddf0b8 --- /dev/null +++ b/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg @@ -0,0 +1,10 @@ +# The header is used to specify the coordinate frame and the reference time for the trajectory durations +std_msgs/Header header + +# A representation of a multi-dof joint trajectory (each point is a transformation) +# Each point along the trajectory will include an array of positions/velocities/accelerations +# that has the same length as the array of joint names, and has the same order of joints as +# the joint names array. + +string[] joint_names +MultiDOFJointTrajectoryPoint[] points diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg new file mode 100644 index 00000000000..b5f6457f182 --- /dev/null +++ b/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg @@ -0,0 +1,11 @@ +# Each multi-dof joint can specify a transform (up to 6 DOF). +geometry_msgs/Transform[] transforms + +# There can be a velocity specified for the origin of the joint. +geometry_msgs/Twist[] velocities + +# There can be an acceleration specified for the origin of the joint. +geometry_msgs/Twist[] accelerations + +# Desired time from the trajectory start to arrive at this trajectory point. +builtin_interfaces/Duration time_from_start diff --git a/dimos/message_codegen/schemas/trajectory_msgs/package.xml b/dimos/message_codegen/schemas/trajectory_msgs/package.xml new file mode 100644 index 00000000000..b1a8ce6f0f7 --- /dev/null +++ b/dimos/message_codegen/schemas/trajectory_msgs/package.xml @@ -0,0 +1,34 @@ + + + + trajectory_msgs + 5.3.8 + A package containing some robot trajectory message definitions. + + Tully Foote + + Apache License 2.0 + + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + William Woodall + + ament_cmake + + rosidl_default_generators + + builtin_interfaces + geometry_msgs + std_msgs + + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg new file mode 100644 index 00000000000..1f9152d4f15 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg @@ -0,0 +1,13 @@ +# A 2D bounding box that can be rotated about its center. +# All dimensions are in pixels, but represented using floating-point +# values to allow sub-pixel precision. If an exact pixel crop is required +# for a rotated bounding box, it can be calculated using Bresenham's line +# algorithm. + +# The 2D position (in pixels) and orientation of the bounding box center. +vision_msgs/Pose2D center + +# The total size (in pixels) of the bounding box surrounding the object relative +# to the pose of its center. +float64 size_x +float64 size_y diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg new file mode 100644 index 00000000000..31bd42f6c79 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg @@ -0,0 +1,2 @@ +std_msgs/Header header +vision_msgs/BoundingBox2D[] boxes diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg new file mode 100644 index 00000000000..cb8f49da3c8 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg @@ -0,0 +1,10 @@ +# A 3D bounding box that can be positioned and rotated about its center (6 DOF) +# Dimensions of this box are in meters, and as such, it may be migrated to +# another package, such as geometry_msgs, in the future. + +# The 3D position and orientation of the bounding box center +geometry_msgs/Pose center + +# The total size of the bounding box, in meters, surrounding the object's center +# pose. +geometry_msgs/Vector3 size diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg new file mode 100644 index 00000000000..c998e699dd4 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg @@ -0,0 +1,2 @@ +std_msgs/Header header +vision_msgs/BoundingBox3D[] boxes \ No newline at end of file diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg new file mode 100644 index 00000000000..ec1404c3a44 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg @@ -0,0 +1,17 @@ +# Defines a classification result. +# +# This result does not contain any position information. It is designed for +# classifiers, which simply provide class probabilities given an instance of +# source data (e.g., an image or a point cloud). + +std_msgs/Header header + +# A list of class probabilities. This list need not provide a probability for +# every possible class, just ones that are nonzero, or above some +# user-defined threshold. +ObjectHypothesis[] results + +# Source data that generated this classification are not a part of the message. +# If you need to access them, use an exact or approximate time synchronizer in +# your code, as this message's header should match the header of the source +# data. diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg new file mode 100644 index 00000000000..c2eb7f41493 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg @@ -0,0 +1,23 @@ +# Defines a 2D detection result. +# +# This is similar to a 2D classification, but includes position information, +# allowing a classification result for a specific crop or image point to +# to be located in the larger image. + +std_msgs/Header header + +# Class probabilities +ObjectHypothesisWithPose[] results + +# 2D bounding box surrounding the object. +BoundingBox2D bbox + +# ID used for consistency across multiple detection messages. Detections +# of the same object in different detection messages should have the same id. +# This field may be empty. +string id + +# Source data that generated this detection are not a part of the message. +# If you need to access them, use an exact or approximate time synchronizer in +# your code, as this message's header should match the header of the source +# data. diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg new file mode 100644 index 00000000000..7d05be04092 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg @@ -0,0 +1,7 @@ +# A list of 2D detections, for a multi-object 2D detector. + +std_msgs/Header header + +# A list of the detected proposals. A multi-proposal detector might generate +# this list with many candidate detections generated from a single input. +Detection2D[] detections diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg new file mode 100644 index 00000000000..bed3f72691d --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg @@ -0,0 +1,23 @@ +# Defines a 3D detection result. +# +# This extends a basic 3D classification by including the pose of the +# detected object. + +std_msgs/Header header + +# Class probabilities. Does not have to include hypotheses for all possible +# object ids, the scores for any ids not listed are assumed to be 0. +ObjectHypothesisWithPose[] results + +# 3D bounding box surrounding the object. +BoundingBox3D bbox + +# ID used for consistency across multiple detection messages. Detections +# of the same object in different detection messages should have the same id. +# This field may be empty. +string id + +# Source data that generated this classification are not a part of the message. +# If you need to access them, use an exact or approximate time synchronizer in +# your code, as this message's header should match the header of the source +# data. diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg new file mode 100644 index 00000000000..b3d3011a82e --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg @@ -0,0 +1,7 @@ +# A list of 3D detections, for a multi-object 3D detector. + +std_msgs/Header header + +# A list of the detected proposals. A multi-proposal detector might generate +# this list with many candidate detections generated from a single input. +Detection3D[] detections diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg b/dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg new file mode 100644 index 00000000000..d73a3c5e529 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg @@ -0,0 +1,25 @@ +# Provides meta-information about a visual pipeline. +# +# This message serves a similar purpose to sensor_msgs/CameraInfo, but instead +# of being tied to hardware, it represents information about a specific +# computer vision pipeline. This information stays constant (or relatively +# constant) over time, and so it is wasteful to send it with each individual +# result. By listening to these messages, subscribers will receive +# the context in which published vision messages are to be interpreted. +# Each vision pipeline should publish its LabelInfo messages to its own topic, +# in a manner similar to CameraInfo. +# This message is meant to allow converting data from vision pipelines that +# return id based classifications back to human readable string class names. + +# Used for sequencing +std_msgs/Header header + +# An array of uint16 keys and string values containing the association +# between class identifiers and their names. According to the amount +# of classes and the datatype used to store their ids internally, the +# maxiumum class id allowed (65535 for uint16 and 255 for uint8) belongs to +# the "UNLABELED" class. +vision_msgs/VisionClass[] class_map + +# The value between 0-1 used as confidence threshold for the inference. +float32 threshold diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg b/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg new file mode 100644 index 00000000000..e6716e83bfe --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg @@ -0,0 +1,12 @@ +# An object hypothesis that contains no pose information. +# If you would like to define an array of ObjectHypothesis messages, +# please see the Classification message type. + +# The unique ID of the object class. To get additional information about +# this ID, such as its human-readable class name, listeners should perform a +# lookup in a metadata database. See vision_msgs/VisionInfo.msg for more detail. +string class_id + +# The probability or confidence value of the detected object. By convention, +# this value should lie in the range [0-1]. +float64 score diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg b/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg new file mode 100644 index 00000000000..bc6c6e8b0ce --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg @@ -0,0 +1,16 @@ +# An object hypothesis that contains pose information. +# If you would like to define an array of ObjectHypothesisWithPose messages, +# please see the Detection2D or Detection3D message types. + +# The object hypothesis (ID and score). +ObjectHypothesis hypothesis + +# The 6D pose of the object hypothesis. This pose should be +# defined as the pose of some fixed reference point on the object, such as +# the geometric center of the bounding box, the center of mass of the +# object or the origin of a reference mesh of the object. +# Note that this pose is not stamped; frame information can be defined by +# parent messages. +# Also note that different classes predicted for the same input data may have +# different predicted 6D poses. +geometry_msgs/PoseWithCovariance pose diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg new file mode 100644 index 00000000000..01455417ab5 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg @@ -0,0 +1,5 @@ +# Represents a 2D point in pixel coordinates. +# XY matches the sensor_msgs/Image convention: X is positive right and Y is positive down. + +float64 x +float64 y diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg new file mode 100644 index 00000000000..367dcec904e --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg @@ -0,0 +1,4 @@ +# Represents a 2D pose (coordinates and a radian rotation). Rotation is positive counterclockwise. + +vision_msgs/Point2D position +float64 theta diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg b/dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg new file mode 100644 index 00000000000..93f2181b876 --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg @@ -0,0 +1,12 @@ +# A key value pair that maps an integer class_id to a string class label +# in computer vision systems. + +# The int value that identifies the class. +# Elements identified with 65535, the maximum uint16 value are assumed +# to belong to the "UNLABELED" class. For vision pipelines using less +# than 255 classes the "UNLABELED" is the maximum value in the uint8 +# range. +uint16 class_id + +# The name of the class represented by the class_id +string class_name diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg b/dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg new file mode 100644 index 00000000000..8058070997d --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg @@ -0,0 +1,40 @@ +# Provides meta-information about a visual pipeline. +# +# This message serves a similar purpose to sensor_msgs/CameraInfo, but instead +# of being tied to hardware, it represents information about a specific +# computer vision pipeline. This information stays constant (or relatively +# constant) over time, and so it is wasteful to send it with each individual +# result. By listening to these messages, subscribers will receive +# the context in which published vision messages are to be interpreted. +# Each vision pipeline should publish its VisionInfo messages to its own topic, +# in a manner similar to CameraInfo. + +# Used for sequencing +std_msgs/Header header + +# Name of the vision pipeline. This should be a value that is meaningful to an +# outside user. +string method + +# Location where the metadata database is stored. The recommended location is +# as an XML string on the ROS parameter server, but the exact implementation +# and information is left up to the user. +# The database should store information attached to class ids. Each +# class id should map to an atomic, visually recognizable element. This +# definition is intentionally vague to allow extreme flexibility. The +# elements could be classes in a pixel segmentation algorithm, object classes +# in a detector, different people's faces in a face detection algorithm, etc. +# Vision pipelines report results in terms of numeric IDs, which map into +# this database. +# The information stored in this database is, again, left up to the user. The +# database could be as simple as a map from ID to class name, or it could +# include information such as object meshes or colors to use for +# visualization. +string database_location + +# Metadata database version. This counter is incremented +# each time the pipeline begins using a new version of the database (useful +# in the case of online training or user modifications). +# The counter value can be monitored by listeners to ensure that the pipeline +# and the listener are using the same metadata. +int32 database_version \ No newline at end of file diff --git a/dimos/message_codegen/schemas/vision_msgs/package.xml b/dimos/message_codegen/schemas/vision_msgs/package.xml new file mode 100644 index 00000000000..6f60ee86bfb --- /dev/null +++ b/dimos/message_codegen/schemas/vision_msgs/package.xml @@ -0,0 +1,37 @@ + + + vision_msgs + 4.1.1 + + Messages for interfacing with various computer vision pipelines, such as + object detectors. + + + Adam Allevato + + Apache License 2.0 + + Adam Allevato + Adam Allevato + Apache License 2.0 + + ament_cmake + rosidl_default_generators + + std_msgs + geometry_msgs + + std_msgs + geometry_msgs + rosidl_default_runtime + + ament_cmake_gtest + ament_lint_auto + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/schemas/visualization_msgs/LICENSE b/dimos/message_codegen/schemas/visualization_msgs/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg new file mode 100644 index 00000000000..2b9e64a6e5b --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg @@ -0,0 +1,36 @@ +int32 CIRCLE=0 +int32 LINE_STRIP=1 +int32 LINE_LIST=2 +int32 POLYGON=3 +int32 POINTS=4 + +int32 ADD=0 +int32 REMOVE=1 + +std_msgs/Header header +# Namespace which is used with the id to form a unique id. +string ns +# Unique id within the namespace. +int32 id +# One of the above types, e.g. CIRCLE, LINE_STRIP, etc. +int32 type +# Either ADD or REMOVE. +int32 action +# Two-dimensional coordinate position, in pixel-coordinates. +geometry_msgs/Point position +# The scale of the object, e.g. the diameter for a CIRCLE. +float32 scale +# The outline color of the marker. +std_msgs/ColorRGBA outline_color +# Whether or not to fill in the shape with color. +uint8 filled +# Fill color; in the range: [0.0-1.0] +std_msgs/ColorRGBA fill_color +# How long the object should last before being automatically deleted. +# 0 indicates forever. +builtin_interfaces/Duration lifetime + +# Coordinates in 2D in pixel coords. Used for LINE_STRIP, LINE_LIST, POINTS, etc. +geometry_msgs/Point[] points +# The color for each line, point, etc. in the points field. +std_msgs/ColorRGBA[] outline_colors diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg new file mode 100644 index 00000000000..c2af8dc97a4 --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg @@ -0,0 +1,26 @@ +# Time/frame info. +# If header.time is set to 0, the marker will be retransformed into +# its frame on each timestep. You will receive the pose feedback +# in the same frame. +# Otherwise, you might receive feedback in a different frame. +# For rviz, this will be the current 'fixed frame' set by the user. +std_msgs/Header header + +# Initial pose. Also, defines the pivot point for rotations. +geometry_msgs/Pose pose + +# Identifying string. Must be globally unique in +# the topic that this message is sent through. +string name + +# Short description (< 40 characters). +string description + +# Scale to be used for default controls (default=1). +float32 scale + +# All menu and submenu entries associated with this marker. +MenuEntry[] menu_entries + +# List of controls displayed for this marker. +InteractiveMarkerControl[] controls diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg new file mode 100644 index 00000000000..10f88c809cc --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg @@ -0,0 +1,77 @@ +# Represents a control that is to be displayed together with an interactive marker + +# Identifying string for this control. +# You need to assign a unique value to this to receive feedback from the GUI +# on what actions the user performs on this control (e.g. a button click). +string name + + +# Defines the local coordinate frame (relative to the pose of the parent +# interactive marker) in which is being rotated and translated. +# Default: Identity +geometry_msgs/Quaternion orientation + + +# Orientation mode: controls how orientation changes. +# INHERIT: Follow orientation of interactive marker +# FIXED: Keep orientation fixed at initial state +# VIEW_FACING: Align y-z plane with screen (x: forward, y:left, z:up). +uint8 INHERIT = 0 +uint8 FIXED = 1 +uint8 VIEW_FACING = 2 + +uint8 orientation_mode + +# Interaction mode for this control +# +# NONE: This control is only meant for visualization; no context menu. +# MENU: Like NONE, but right-click menu is active. +# BUTTON: Element can be left-clicked. +# MOVE_AXIS: Translate along local x-axis. +# MOVE_PLANE: Translate in local y-z plane. +# ROTATE_AXIS: Rotate around local x-axis. +# MOVE_ROTATE: Combines MOVE_PLANE and ROTATE_AXIS. +uint8 NONE = 0 +uint8 MENU = 1 +uint8 BUTTON = 2 +uint8 MOVE_AXIS = 3 +uint8 MOVE_PLANE = 4 +uint8 ROTATE_AXIS = 5 +uint8 MOVE_ROTATE = 6 +# "3D" interaction modes work with the mouse+SHIFT+CTRL or with 3D cursors. +# MOVE_3D: Translate freely in 3D space. +# ROTATE_3D: Rotate freely in 3D space about the origin of parent frame. +# MOVE_ROTATE_3D: Full 6-DOF freedom of translation and rotation about the cursor origin. +uint8 MOVE_3D = 7 +uint8 ROTATE_3D = 8 +uint8 MOVE_ROTATE_3D = 9 + +uint8 interaction_mode + + +# If true, the contained markers will also be visible +# when the gui is not in interactive mode. +bool always_visible + + +# Markers to be displayed as custom visual representation. +# Leave this empty to use the default control handles. +# +# Note: +# - The markers can be defined in an arbitrary coordinate frame, +# but will be transformed into the local frame of the interactive marker. +# - If the header of a marker is empty, its pose will be interpreted as +# relative to the pose of the parent interactive marker. +Marker[] markers + + +# In VIEW_FACING mode, set this to true if you don't want the markers +# to be aligned with the camera view point. The markers will show up +# as in INHERIT mode. +bool independent_marker_orientation + + +# Short description (< 40 characters) of what this control does, +# e.g. "Move the robot". +# Default: A generic description based on the interaction mode +string description diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg new file mode 100644 index 00000000000..43c754c97eb --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg @@ -0,0 +1,42 @@ +# Time/frame info. +std_msgs/Header header + +# Identifying string. Must be unique in the topic namespace. +string client_id + +# Feedback message sent back from the GUI, e.g. +# when the status of an interactive marker was modified by the user. + +# Specifies which interactive marker and control this message refers to +string marker_name +string control_name + +# Type of the event +# KEEP_ALIVE: sent while dragging to keep up control of the marker +# MENU_SELECT: a menu entry has been selected +# BUTTON_CLICK: a button control has been clicked +# POSE_UPDATE: the pose has been changed using one of the controls +uint8 KEEP_ALIVE = 0 +uint8 POSE_UPDATE = 1 +uint8 MENU_SELECT = 2 +uint8 BUTTON_CLICK = 3 + +uint8 MOUSE_DOWN = 4 +uint8 MOUSE_UP = 5 + +uint8 event_type + +# Current pose of the marker +# Note: Has to be valid for all feedback types. +geometry_msgs/Pose pose + +# Contains the ID of the selected menu entry +# Only valid for MENU_SELECT events. +uint32 menu_entry_id + +# If event_type is BUTTON_CLICK, MOUSE_DOWN, or MOUSE_UP, mouse_point +# may contain the 3 dimensional position of the event on the +# control. If it does, mouse_point_valid will be true. mouse_point +# will be relative to the frame listed in the header. +geometry_msgs/Point mouse_point +bool mouse_point_valid diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg new file mode 100644 index 00000000000..d73bcd0480c --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg @@ -0,0 +1,14 @@ +# Identifying string. Must be unique in the topic namespace +# that this server works on. +string server_id + +# Sequence number. +# The client will use this to detect if it has missed a subsequent +# update. Every update message will have the same sequence number as +# an init message. Clients will likely want to unsubscribe from the +# init topic after a successful initialization to avoid receiving +# duplicate data. +uint64 seq_num + +# All markers. +InteractiveMarker[] markers diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg new file mode 100644 index 00000000000..04a22e9a7eb --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg @@ -0,0 +1,10 @@ + +# Time/frame info. +std_msgs/Header header + +# Initial pose. Also, defines the pivot point for rotations. +geometry_msgs/Pose pose + +# Identifying string. Must be globally unique in +# the topic that this message is sent through. +string name diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg new file mode 100644 index 00000000000..2070a03ae8b --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg @@ -0,0 +1,32 @@ + +# Identifying string. Must be unique in the topic namespace +# that this server works on. +string server_id + +# Sequence number. +# The client will use this to detect if it has missed an update. +uint64 seq_num + +# Type holds the purpose of this message. It must be one of UPDATE or KEEP_ALIVE. +# UPDATE: Incremental update to previous state. +# The sequence number must be 1 higher than for +# the previous update. +# KEEP_ALIVE: Indicates the that the server is still living. +# The sequence number does not increase. +# No payload data should be filled out (markers, poses, or erases). +uint8 KEEP_ALIVE = 0 +uint8 UPDATE = 1 + +uint8 type + +# Note: No guarantees on the order of processing. +# Contents must be kept consistent by sender. + +# Markers to be added or updated +InteractiveMarker[] markers + +# Poses of markers that should be moved +InteractiveMarkerPose[] poses + +# Names of markers to be erased +string[] erases diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg new file mode 100644 index 00000000000..eb9938a11a0 --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg @@ -0,0 +1,81 @@ +# See: +# - http://www.ros.org/wiki/rviz/DisplayTypes/Marker +# - http://www.ros.org/wiki/rviz/Tutorials/Markers%3A%20Basic%20Shapes +# +# for more information on using this message with rviz. + +int32 ARROW=0 +int32 CUBE=1 +int32 SPHERE=2 +int32 CYLINDER=3 +int32 LINE_STRIP=4 +int32 LINE_LIST=5 +int32 CUBE_LIST=6 +int32 SPHERE_LIST=7 +int32 POINTS=8 +int32 TEXT_VIEW_FACING=9 +int32 MESH_RESOURCE=10 +int32 TRIANGLE_LIST=11 +int32 ARROW_STRIP=12 + +int32 ADD=0 +int32 MODIFY=0 +int32 DELETE=2 +int32 DELETEALL=3 + +# Header for timestamp and frame id. +std_msgs/Header header +# Namespace in which to place the object. +# Used in conjunction with id to create a unique name for the object. +string ns +# Object ID used in conjunction with the namespace for manipulating and deleting the object later. +int32 id +# Type of object. +int32 type +# Action to take; one of: +# - 0 add/modify an object +# - 1 (deprecated) +# - 2 deletes an object (with the given ns and id) +# - 3 deletes all objects (or those with the given ns if any) +int32 action +# Pose of the object with respect the frame_id specified in the header. +geometry_msgs/Pose pose +# Scale of the object; 1,1,1 means default (usually 1 meter square). +geometry_msgs/Vector3 scale +# Color of the object; in the range: [0.0-1.0] +std_msgs/ColorRGBA color +# How long the object should last before being automatically deleted. +# 0 indicates forever. +builtin_interfaces/Duration lifetime +# If this marker should be frame-locked, i.e. retransformed into its frame every timestep. +bool frame_locked + +# Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, ARROW_STRIP, etc.) +geometry_msgs/Point[] points +# Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, etc.) +# The number of colors provided must either be 0 or equal to the number of points provided. +# NOTE: alpha is not yet used +std_msgs/ColorRGBA[] colors + +# Texture resource is a special URI that can either reference a texture file in +# a format acceptable to (resource retriever)[https://docs.ros.org/en/rolling/p/resource_retriever/] +# or an embedded texture via a string matching the format: +# "embedded://texture_name" +string texture_resource +# An image to be loaded into the rendering engine as the texture for this marker. +# This will be used iff texture_resource is set to embedded. +sensor_msgs/CompressedImage texture +# Location of each vertex within the texture; in the range: [0.0-1.0] +UVCoordinate[] uv_coordinates + +# Only used for text markers +string text + +# Only used for MESH_RESOURCE markers. +# Similar to texture_resource, mesh_resource uses resource retriever to load a mesh. +# Optionally, a mesh file can be sent in-message via the mesh_file field. If doing so, +# use the following format for mesh_resource: +# "embedded://mesh_name" +string mesh_resource +MeshFile mesh_file +bool mesh_use_embedded_materials diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg new file mode 100644 index 00000000000..dd0fab432ab --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg @@ -0,0 +1 @@ +Marker[] markers diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg new file mode 100644 index 00000000000..aee5720dbf6 --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg @@ -0,0 +1,54 @@ +# MenuEntry message. +# +# Each InteractiveMarker message has an array of MenuEntry messages. +# A collection of MenuEntries together describe a +# menu/submenu/subsubmenu/etc tree, though they are stored in a flat +# array. The tree structure is represented by giving each menu entry +# an ID number and a "parent_id" field. Top-level entries are the +# ones with parent_id = 0. Menu entries are ordered within their +# level the same way they are ordered in the containing array. Parent +# entries must appear before their children. +# +# Example: +# - id = 3 +# parent_id = 0 +# title = "fun" +# - id = 2 +# parent_id = 0 +# title = "robot" +# - id = 4 +# parent_id = 2 +# title = "pr2" +# - id = 5 +# parent_id = 2 +# title = "turtle" +# +# Gives a menu tree like this: +# - fun +# - robot +# - pr2 +# - turtle + +# ID is a number for each menu entry. Must be unique within the +# control, and should never be 0. +uint32 id + +# ID of the parent of this menu entry, if it is a submenu. If this +# menu entry is a top-level entry, set parent_id to 0. +uint32 parent_id + +# menu / entry title +string title + +# Arguments to command indicated by command_type (below) +string command + +# Command_type stores the type of response desired when this menu +# entry is clicked. +# FEEDBACK: send an InteractiveMarkerFeedback message with menu_entry_id set to this entry's id. +# ROSRUN: execute "rosrun" with arguments given in the command field (above). +# ROSLAUNCH: execute "roslaunch" with arguments given in the command field (above). +uint8 FEEDBACK=0 +uint8 ROSRUN=1 +uint8 ROSLAUNCH=2 +uint8 command_type diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg new file mode 100644 index 00000000000..f7c43398365 --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg @@ -0,0 +1,8 @@ +# Used to send raw mesh files. + +# The filename is used for both debug purposes and to provide a file extension +# for whatever parser is used. +string filename + +# This stores the raw text of the mesh file. +uint8[] data diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg new file mode 100644 index 00000000000..d48b0f293e9 --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg @@ -0,0 +1,4 @@ +# Location of the pixel as a ratio of the width of a 2D texture. +# Values should be in range: [0.0-1.0]. +float32 u +float32 v diff --git a/dimos/message_codegen/schemas/visualization_msgs/package.xml b/dimos/message_codegen/schemas/visualization_msgs/package.xml new file mode 100644 index 00000000000..f18262ca40d --- /dev/null +++ b/dimos/message_codegen/schemas/visualization_msgs/package.xml @@ -0,0 +1,35 @@ + + + + visualization_msgs + 5.3.8 + A package containing some visualization and interaction related message definitions. + + Tully Foote + + Apache License 2.0 + + Geoffrey Biggs + Michael Carroll + Michel Hidalgo + William Woodall + + ament_cmake + + rosidl_default_generators + + builtin_interfaces + geometry_msgs + sensor_msgs + std_msgs + + rosidl_default_runtime + + ament_lint_common + + rosidl_interface_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/sources.json b/dimos/message_codegen/sources.json new file mode 100644 index 00000000000..53344c33b83 --- /dev/null +++ b/dimos/message_codegen/sources.json @@ -0,0 +1,201 @@ +[ + { + "repository": "ros2/common_interfaces", + "revision": "a941f14bb318d8d904505ed935ccbb97f24a70a4", + "files": { + "schemas/geometry_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/geometry_msgs/msg/Accel.msg": "67f371aabfc8ec1bd58bbb01a1709222e685c549462984c9958cc89fcd9f6abb", + "schemas/geometry_msgs/msg/AccelStamped.msg": "c46e9fcf5551d2330b63b1efe0626f747bcda24ddcc9e281597a9354b3bd9eea", + "schemas/geometry_msgs/msg/AccelWithCovariance.msg": "59512bab4004aefda7a9dea2a6fdbeb625c66a3a5359aae33b4561cf4a41263b", + "schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg": "04d5dbf78d814f58f4a01b1e9a63b5a5fdd24f5164cf021908d05fb079e63de8", + "schemas/geometry_msgs/msg/Inertia.msg": "33bc8db637874153ba5261bb5e7c23ca12754e15e5a2e58a86533c1f5bd66dd4", + "schemas/geometry_msgs/msg/InertiaStamped.msg": "456743836340c5d638dba1fcae3211acfe61f0690dcc9fe5b7ae9af8991591f1", + "schemas/geometry_msgs/msg/Point.msg": "eb4c07e591cf0269ccb17245dcd4f998162feb09cc8add85fa082c8a30bfc91d", + "schemas/geometry_msgs/msg/Point32.msg": "acade2dacb4f1f7988f34e8221079eb1c757f51e8ef48adb5651f7dc478fed59", + "schemas/geometry_msgs/msg/PointStamped.msg": "c58b03c27604f45e9b0fd2f1b327dcbada7d6a389beb8c060d448abc25e76bfc", + "schemas/geometry_msgs/msg/Polygon.msg": "43679118501e3b294349c9ad73af9f03b476ef77c7096cd79b4ce46646823056", + "schemas/geometry_msgs/msg/PolygonInstance.msg": "2ba1b905a10593821b1f8f4c05ad27cf2d1a9bd1e9c2643b01297583993f7bd4", + "schemas/geometry_msgs/msg/PolygonInstanceStamped.msg": "0dd863a4fb199e8833d13df9802064884a8be7a7f439f2b6e378aebcf121a506", + "schemas/geometry_msgs/msg/PolygonStamped.msg": "ff0812e3cae3e92947ba4abe3f9ea6ad31e04af0f2d97399027786ad27d39f0a", + "schemas/geometry_msgs/msg/Pose.msg": "3eceb77c63ebbb544c11d7f991e475e9819e0cf534deb1a879392c1b3dc997de", + "schemas/geometry_msgs/msg/Pose2D.msg": "48bbdb9e593b50b3e4b4e4494ca6ce076f59937c1b4ad80bc7ea09e87891a899", + "schemas/geometry_msgs/msg/PoseArray.msg": "3f58a91730c78dbc5ec5092131945ccdfeeb775aa0f02df7ff09f6c979b1d398", + "schemas/geometry_msgs/msg/PoseStamped.msg": "31898ab0eb64a6c44c27ab4959819a32ec3bc3ee847c8fe1b01c897d48e311e5", + "schemas/geometry_msgs/msg/PoseWithCovariance.msg": "a22f234e91b9fcd4ba0c5b533496b43c62d7f6ade39082212ac9835679d29f94", + "schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg": "87b6851480902effb5232f87bf68e76f19bf7b26affa11001be9e515542c21fb", + "schemas/geometry_msgs/msg/Quaternion.msg": "298495eb67a139642ffd37cc9029eae085e6c39a8789828b7517868a487939ed", + "schemas/geometry_msgs/msg/QuaternionStamped.msg": "855d4fd0cecb74ed55477a8c1f19fc9498207e7833a4f923b56fd68a9ba99ec9", + "schemas/geometry_msgs/msg/Transform.msg": "c8916279f0a429dd9561158bd2133bc4e2d780277c3c594116b240a27e7a2993", + "schemas/geometry_msgs/msg/TransformStamped.msg": "f6e137c205e9187ac1dafdfbace7435de58bb3779a55e9c6b52c2cb513785c42", + "schemas/geometry_msgs/msg/Twist.msg": "ed471ef861f65af991b1f64d66ef941dd41dd4c0702f6222512b1a16c62d58b0", + "schemas/geometry_msgs/msg/TwistStamped.msg": "ffc9d5925412410b28d601c55cf386a0b3e4d5dba00920fbafb98d7201f582ca", + "schemas/geometry_msgs/msg/TwistWithCovariance.msg": "5690a1f109d4962c73b5ca7f3673c48052d02f37b6a38fe2fb37c899cf555c45", + "schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg": "af369aea38a14e57ff350a3f2c63c2c66335a367822d134fecdef60789e49682", + "schemas/geometry_msgs/msg/Vector3.msg": "d8b9ea9aad1f424faf4d2b94dae1e1368af1e5d59de11aeed019399cff7f9e1d", + "schemas/geometry_msgs/msg/Vector3Stamped.msg": "bfe690d1b7d907c039c9c1580cf8de557d546c8aeb3280c1bd5e0a60d84356cd", + "schemas/geometry_msgs/msg/VelocityStamped.msg": "48517d22e2485d0d018300aba815569d05614f7e0eb9c2959719081d8ca0bd5b", + "schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg": "d04d9a70bba11e70baa146d05b02804f43c835c2caa733d8ddacc4b09528f43f", + "schemas/geometry_msgs/msg/Wrench.msg": "d9667abd3d2a67d5624113fa07a647b0d4806bf89d21c8a5cf914905a036bf25", + "schemas/geometry_msgs/msg/WrenchStamped.msg": "853a8534230b795b6c1afcb8483002f5d1cf14e967ffa0da2cba8da5453b2162", + "schemas/geometry_msgs/package.xml": "879da7003d6d2952701aa23146f0d78096143d5107dd6e775a23e591c2c376a0", + "schemas/nav_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/nav_msgs/msg/Goals.msg": "37006ffd5763454ccb2a9630eda00501e5cb9b874a6cb38deec7398c2abb919f", + "schemas/nav_msgs/msg/GridCells.msg": "4bc9802947dcd2bbfafcbcffbce165ce6ff87e5132b9511ab2994ef4b23ff2b3", + "schemas/nav_msgs/msg/MapMetaData.msg": "6868a7d604c6cc033dd0adfac8a0adb0a6dedae1b7b140dbb47c83f3bcc6f140", + "schemas/nav_msgs/msg/OccupancyGrid.msg": "3e54ec7e662bdd6d5528efab99c6e34ce3eed27ce628721fcdb4e5e1bbf8188b", + "schemas/nav_msgs/msg/Odometry.msg": "bb00547ddf498cdbae46fd991d9d85a59f507e12e7cf01fb18a86f1111524f4f", + "schemas/nav_msgs/msg/Path.msg": "fc1e2eff6c2bd63fb92b6cf29bad29873b026d7abe00d3a68965b40668bfdd5b", + "schemas/nav_msgs/msg/Trajectory.msg": "66345fad009bc64a3c313020ec78d33a0f6424698ca37a020e33038cc19511b1", + "schemas/nav_msgs/msg/TrajectoryPoint.msg": "aec0753c683e369c16253d018f6e97c4230e4f4ba0135d52050b333793f39796", + "schemas/nav_msgs/package.xml": "0d61b26dbf9ccfd2e993713d5d5cea913f0ab789d1a28bdb42eac2ef47c4a0a5", + "schemas/sensor_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/sensor_msgs/msg/BatteryState.msg": "ce13430f3c107274fb7123a6d1e79a9f83974d78cb0be1721695129e49240b25", + "schemas/sensor_msgs/msg/CameraInfo.msg": "1fced83678f5f2708aff8540987594692452de9f0b43905ce3bfba689226f3aa", + "schemas/sensor_msgs/msg/ChannelFloat32.msg": "6cf885a09a7f499ce2348bc3099e146a6273bb1e7ff875824ecbe05abaf0d086", + "schemas/sensor_msgs/msg/CompressedImage.msg": "75ca1003981c407148ff94a3470760985dd69233b8287a5d52848d45a312f144", + "schemas/sensor_msgs/msg/FluidPressure.msg": "a2a96aa57e9957549dbf5c739c3dba3fb4303f0dd8426c9178b7333b656bb0d9", + "schemas/sensor_msgs/msg/Illuminance.msg": "b55f46c55588f7d729feb7dd84b60b1796dcfdb2351a26982ff2505129702182", + "schemas/sensor_msgs/msg/Image.msg": "575cd3434771916c2b551db8ac484522ecef1d6105196e043a305887d2730704", + "schemas/sensor_msgs/msg/Imu.msg": "5800b7c2e6d3afed966ae229b1559f6e762c792ad34a88e55ad4288d8bbbd34b", + "schemas/sensor_msgs/msg/JointState.msg": "711d1771a002c7190e5bbe746a163a67477c1e2a45482a64f1fe339815ca6f5d", + "schemas/sensor_msgs/msg/Joy.msg": "5a7d133e7dc82f531e03bd4ff92c9240a828bb6ceb6f19d5cd767d5372adb757", + "schemas/sensor_msgs/msg/JoyFeedback.msg": "47f62324e13743dd7a14bb71d64dc4cc034f4ff7885688c235bc121e224e06c3", + "schemas/sensor_msgs/msg/JoyFeedbackArray.msg": "6930a74a9e38918bb6f872c3e30ee3bb172c3b71cb3daf5d07c6ea76ee44f0ab", + "schemas/sensor_msgs/msg/LaserEcho.msg": "57511740458bf605dd609aab1b43312ec0e884d702196993a29ea32cb67d4f5f", + "schemas/sensor_msgs/msg/LaserScan.msg": "bb688599d8787fa1b48393e50064013e58449055eb60e501eb01a07e8bc03357", + "schemas/sensor_msgs/msg/MagneticField.msg": "b1bf534a4175055d85ee4630788c67a960733c383a458b86f6dfdfa27786be64", + "schemas/sensor_msgs/msg/MultiDOFJointState.msg": "bb707259b63ea52101697daf624ff7ad73a1f9977117ce3798a36cc1858d99fd", + "schemas/sensor_msgs/msg/MultiEchoLaserScan.msg": "8e96fd2ff5e685bfed326fecd90797fade8485be7c02f54250e5ea535c42b5e3", + "schemas/sensor_msgs/msg/NavSatFix.msg": "7457a0d5afd253a69a9996288192fb9bf10fdd053989204d5aca8d56d95b65ac", + "schemas/sensor_msgs/msg/NavSatStatus.msg": "f41663c70f192cfb8af118403ced55171b9c42af40a4ef798536d8af23b3d4f9", + "schemas/sensor_msgs/msg/PointCloud.msg": "8bdec27b9f1b688448410d1c6de34b42af6ef56ad4e496a214793e9ec88db993", + "schemas/sensor_msgs/msg/PointCloud2.msg": "22699bfd6c68be148363a2e889408833a5a37d3464ea20032d1c757336b80f2a", + "schemas/sensor_msgs/msg/PointField.msg": "6e6d5d51d2e464d3074b44b112f219e67fcdc0b280260d93f8cefd9710ec972e", + "schemas/sensor_msgs/msg/Range.msg": "6aac2960a3702cad5c5a6b5eda68e252a97d199bd9b7385c975332edbbc170cf", + "schemas/sensor_msgs/msg/RegionOfInterest.msg": "9c07010ab5ffddd1202876a778b44c99cafa780bc0503041c3fd935870a14c6a", + "schemas/sensor_msgs/msg/RelativeHumidity.msg": "bd9cff7bdebac733030ec1de6a66f004bf4f31924078a3170984d338352e649a", + "schemas/sensor_msgs/msg/Temperature.msg": "20a8580f84dbc063d87c3e1b902494149428272749844fa1dbf24fa80575be82", + "schemas/sensor_msgs/msg/TimeReference.msg": "4fdb6fb81fc2e910c560d80dd21b161a72d7f09b2f0ea9bdfcb75d71ab342491", + "schemas/sensor_msgs/package.xml": "00cc932b8a1d2a9064c621bfacab56428a5175afe37269da38ba09361e8a4a5a", + "schemas/shape_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/shape_msgs/msg/Mesh.msg": "29507f9817d335be2f43addd1997e032f73aeeff156d13931b92db62715dfe01", + "schemas/shape_msgs/msg/MeshTriangle.msg": "2beff414354278b465ec50b0526756317a641c2165ca1d6938028ed630445b96", + "schemas/shape_msgs/msg/Plane.msg": "b3d30ea44df5e4cdd40eda15239e19e6b18d5bccdb227d8cea45c7875b8c6fd0", + "schemas/shape_msgs/msg/SolidPrimitive.msg": "b3ec61569b2b4e2c37428e0625d4a360c00c95fc9ad4c94f9c8399225b98b2d8", + "schemas/shape_msgs/package.xml": "6c815efae68e089af95fd6e224292275808eaaea6bd85e3cfb1071fc6b7cd8dc", + "schemas/std_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/std_msgs/msg/Bool.msg": "d989b95f2ba14d15eff5b274b5d1f379b938aaea2157d8bd707f942457ae18bf", + "schemas/std_msgs/msg/Byte.msg": "448fd1e2fba020e0e297156875162512d9f9cab89e45f7793cb48f5999bdb287", + "schemas/std_msgs/msg/ByteMultiArray.msg": "b1f5112522ff33249f4391e4bf8b02535acd99ef447dbd20f04cd7115f18cdfc", + "schemas/std_msgs/msg/Char.msg": "b39e71ef965c29b1d121af0c0104b4167b9f972836b160c2c18b8f76f959d793", + "schemas/std_msgs/msg/ColorRGBA.msg": "6a2ce596d968f23d8456ff1e0b1218dec75ce2542614e004c99d29aceb3be697", + "schemas/std_msgs/msg/Empty.msg": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "schemas/std_msgs/msg/Float32.msg": "fb905efdb5c7902255cad5a6e4953158384238d4652d9e7ed68d134da052f3af", + "schemas/std_msgs/msg/Float32MultiArray.msg": "06fdd671e03917b05d2f8be67ce6b1ed5934990c9361b2ec6ab24637f9ec5aef", + "schemas/std_msgs/msg/Float64.msg": "b319b310779a5bc2e1f16a47a204236d5c231f2e9a9bf1555d6d098ae5aba625", + "schemas/std_msgs/msg/Float64MultiArray.msg": "344f5d8e6215a6e994659fb272de97c47a02b435db94a6d0f983b1fb467e0775", + "schemas/std_msgs/msg/Header.msg": "d2cea14630e39ed0fa5b432ba9160a7c38855b9427d3344f99e83e83facb53c2", + "schemas/std_msgs/msg/Int16.msg": "ea0ed16cdc7adc6b93ed503f21391832bbad3968d39881d117184bf298f9c5f0", + "schemas/std_msgs/msg/Int16MultiArray.msg": "82c59adccac841bdcb69c9030866972f1008c894c7e4245a2c24a78f8379e3de", + "schemas/std_msgs/msg/Int32.msg": "4614a6d0154436fb9ff12b0b7637816f42a550e4f5e0c4705bedf11293b4f7a7", + "schemas/std_msgs/msg/Int32MultiArray.msg": "70dd821b52c083f05963b02d49a59214baaba0fc17a56eba7c30346a26183a4a", + "schemas/std_msgs/msg/Int64.msg": "117752e7d1f0e4709749c04a9251dcece8545c0dac7bbb6fb8f31262d6ace238", + "schemas/std_msgs/msg/Int64MultiArray.msg": "423483a9473b3e6f8e00170a4c16591d801fd61d987d38b46def6ec2cf3b05d1", + "schemas/std_msgs/msg/Int8.msg": "2ad86a195e6c5d3415b5b48f4c248c45bfe05d636735f88d821c44ab660c7f6f", + "schemas/std_msgs/msg/Int8MultiArray.msg": "8b4b59b15a32fb25353425041c33874f6667376df2f4e5c08f9af2d56d11e403", + "schemas/std_msgs/msg/MultiArrayDimension.msg": "94927d0ee40f1a1d9bf7bdddbca803e8b6e6d315d70c7295a9b0d2d6c380abed", + "schemas/std_msgs/msg/MultiArrayLayout.msg": "8f059b66610c5fe0532e3f12ff1022a10671caebf773f00816fd4c9303626914", + "schemas/std_msgs/msg/String.msg": "2022b3f1c32b578ff8d54a9948a51a10778761e0ad4ba60e50ae51292ca16884", + "schemas/std_msgs/msg/UInt16.msg": "1e221bc3043d630d8f0e9db8c6d50f3f47a19db3c0908a290e95e58e2d3a225b", + "schemas/std_msgs/msg/UInt16MultiArray.msg": "288489782bda9287b6f7045ea5b039126280f84acf3a5ca2fa0710f8a916d3d5", + "schemas/std_msgs/msg/UInt32.msg": "4db7deaede98bebcc6ddfa951cf4d55aaad57909f38a8c346a12ae25df2e58ae", + "schemas/std_msgs/msg/UInt32MultiArray.msg": "3a25d8463602c0f3eff61a14c3c17c10ef819aadf7ef19179e95cfdaea07b3ce", + "schemas/std_msgs/msg/UInt64.msg": "3c2e946558706bf4afa6fca53dac6e19865c19629bf43b28a5e7bb5a9109eb58", + "schemas/std_msgs/msg/UInt64MultiArray.msg": "2e9c7e85a430eb66905eea278c7de39fb16baeda225ced6b78d15e06cd426e4d", + "schemas/std_msgs/msg/UInt8.msg": "4f3a2f4948339ff1b3bdb947c1f5124d6da4766a36f0f7a7bdad63fbbac41b76", + "schemas/std_msgs/msg/UInt8MultiArray.msg": "5c042755bdeaa442d6bab5755790cef6a3f9434162dab9028fd8dc1b794d6bd4", + "schemas/std_msgs/package.xml": "a34587c4319cab814f6e092a4f2d30f96e8de0325c81f69c2701a9545383da23", + "schemas/trajectory_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/trajectory_msgs/msg/JointTrajectory.msg": "d63cda4a5ec81824ed4acd737e6b5903449fb1a7e2f5cdcdcc4c49285f01117c", + "schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg": "2358055d26d27c0c302e921f90d5aa59cb5feb3e22937f8ac98314b0c52ba8f4", + "schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg": "070af6b4c9f4238d9de36621105d78c999dbad2045d0cb2a633f86a17f73f6b7", + "schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg": "7e3a4b150ff7ce8d7d897a480d8d324a244a0afb4a07fdf6241074071170ac7a", + "schemas/trajectory_msgs/package.xml": "c0d9fd1b3f17b2d3811086b67414d519850a75e8ce08e609e40d1b9fee821575", + "schemas/visualization_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/visualization_msgs/msg/ImageMarker.msg": "d9c80f1109ceb8764ca5c9198fb2dbad4e3c5bc073d94c2be2cbcd6ea0eccdc6", + "schemas/visualization_msgs/msg/InteractiveMarker.msg": "95fd14ff8172ac01847378ab836ae387f54ab458b715e93dc1a049a10daa4326", + "schemas/visualization_msgs/msg/InteractiveMarkerControl.msg": "d73f1e212bcbab4d191cc3254c9f6de0b9de4f420ab2d87ba122ef0a2683acc6", + "schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg": "27b820cb63c165a9966bdb5eed516eecc25d9d15bb66192f14e930eff7446915", + "schemas/visualization_msgs/msg/InteractiveMarkerInit.msg": "facc8236619cef328d291555f6bdc784e34fa3a1700d6d2390bab73c45d121fa", + "schemas/visualization_msgs/msg/InteractiveMarkerPose.msg": "b6e3a8d40bf9c99ea7837eb08b0e8e8189f3fc5d7bb370ce501141cc1966582c", + "schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg": "6d75ca37561c3497ee1991cb6e61e55b59ebf2e1d458bdce30ad023d36762bdb", + "schemas/visualization_msgs/msg/Marker.msg": "136042d6ddb4589159f23fe1d7a469420c556c0a37fa712d4fff9c2dd74e9239", + "schemas/visualization_msgs/msg/MarkerArray.msg": "38a122bed2014534668ad143f6b57a831b6edb3d4453b2feeef8669930f234cc", + "schemas/visualization_msgs/msg/MenuEntry.msg": "47056d0f57316473249d619dbe51d26680c56c329be668afab9b5fd7a1f2a0a5", + "schemas/visualization_msgs/msg/MeshFile.msg": "6c5393590d3765a6da1bc815f0dba8962b55efad40ab4fb1346673cf89c294ed", + "schemas/visualization_msgs/msg/UVCoordinate.msg": "544f2580cfb42e1e28dcb27856572abd52ad348d8f6197526f51f6d15acec1f0", + "schemas/visualization_msgs/package.xml": "19ed838dc5a99735e2dd9b45e308d1227f6ba7c411ce3675cca480620993750d" + } + }, + { + "repository": "ros2/rcl_interfaces", + "revision": "7aa3caf43377ea6ad615bc1040832e2c7566bfbe", + "files": { + "schemas/builtin_interfaces/msg/Duration.msg": "57da13a4201e7d258a2931323145b953e47e46967494e62ba66c2faca4fbade2", + "schemas/builtin_interfaces/msg/Time.msg": "dc5a01ddde3aecffee21eb24974fe77cc969f873218a2b1811aa0ac8a456b8bd", + "schemas/builtin_interfaces/package.xml": "0f709bdbc4742e9040e788adcc2df710542d9a095080cbcda2dcb4174461de51", + "schemas/licenses/ros2_rcl_interfaces/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + } + }, + { + "repository": "ros2/geometry2", + "revision": "f702874b1c8535d6a038230ab2cda0ba5d521ebd", + "files": { + "schemas/licenses/ros2_geometry2/LICENSE": "1b1e5ebcad699924203feced7205a4bbdf4f153d34065a19a8a4e107cf1e154b", + "schemas/tf2_msgs/msg/TF2Error.msg": "f1f3603b877ed51a5a28b264257e9bc37312e32a767838f52310d07027d819ab", + "schemas/tf2_msgs/msg/TFMessage.msg": "f3fca610a59b31ee4c7b740522ecdd0fd8c76002170088111409e4df513f1dfc", + "schemas/tf2_msgs/package.xml": "ac78cb0ff503bc07b20358bbe7bcb7475db7b6f0d87d2a84e321b92755bfb14e" + } + }, + { + "repository": "ros-perception/vision_msgs", + "revision": "adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27", + "files": { + "schemas/licenses/ros-perception_vision_msgs/LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "schemas/vision_msgs/msg/BoundingBox2D.msg": "74ed6347e3c8f74b884a81c5a36925c0e320836c1a5ea55df2b8d03574cc25b1", + "schemas/vision_msgs/msg/BoundingBox2DArray.msg": "0045d22aad0e9ab13e54b365e56b1a8c99829086a5126a4ede2c1916850ffb44", + "schemas/vision_msgs/msg/BoundingBox3D.msg": "30502a6e247a84d87b4c2c0262fd07ce6ba3fa8d6d24e6e39c1522d7e469c450", + "schemas/vision_msgs/msg/BoundingBox3DArray.msg": "dac9423ac1a15724f3a068a3987e9702ddcff6ea7eedacc92d7352aa24ba478d", + "schemas/vision_msgs/msg/Classification.msg": "05c1206c9db5728e8e6a8528354bbc6a9d2c5be9147268227c887019c7ecaf34", + "schemas/vision_msgs/msg/Detection2D.msg": "868ffec733235c01bb5bfba3f3c528f193ea0fb3069650aaf95383a7fa9a8200", + "schemas/vision_msgs/msg/Detection2DArray.msg": "bb2eeef88b466103b89a7ae9f927164d2064e9d94e8455bb98ad2b69130331ae", + "schemas/vision_msgs/msg/Detection3D.msg": "68885eeededfc57231f171f2b3eb97f0d0a18580ca08307bc60b9b87216df985", + "schemas/vision_msgs/msg/Detection3DArray.msg": "077f34a634e6de6654265af5b26508eea1105bef72395cffae50fde61b713c41", + "schemas/vision_msgs/msg/LabelInfo.msg": "96cf2fa183f8f20a7356fd18163d2a8e875306c799f3fadec08169e5e487f3aa", + "schemas/vision_msgs/msg/ObjectHypothesis.msg": "6224cb18c032fe062d18859089444f4e1f311ab478e45d937fdfac18a980695b", + "schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg": "162639c82b24a8fc4f3e93a4dc91704928d5cff9d39d169515bb748eccf4d573", + "schemas/vision_msgs/msg/Point2D.msg": "6b99220dccc3193a603fb40d6a2880b4de67fb2175121c5683d0bde9f71e3733", + "schemas/vision_msgs/msg/Pose2D.msg": "0cdb3bc9872a5c3379a5122c14d03ec13d59b92752d3b444cc41592492258ab2", + "schemas/vision_msgs/msg/VisionClass.msg": "ae82ce087350e3ee1c0f0f8bb8f6e6c2e08f94dea6d984dec579fd72663bdb72", + "schemas/vision_msgs/msg/VisionInfo.msg": "5a47776dfea36e48958dbde43ab55e9cb94fb337b0f68b4fcc444807f333b23d", + "schemas/vision_msgs/package.xml": "b69e5eb38183cbcf2cf0b729a21ea6217eb76a48bd0613c00539a598a5f35872" + } + }, + { + "repository": "ros2/rosidl", + "revision": "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", + "files": { + "_vendor/rosidl_parser.py": "ce1f7d84ab0ad8300e77917061b74dbe701d33f3fd12de5ba6b75374c8f9970e", + "schemas/licenses/ros2_rosidl/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "schemas/rosidl_adapter/package.xml": "653c797d2b4e2f5e6ad7b18812632bf6bf55aa924dfbca0405439389a5273989" + } + }, + { + "repository": "foxglove/schemas", + "revision": "e86a94e9d4d259cdde71872f18336a7a055bf9ba", + "files": { + "schemas/foxglove_msgs/msg/CompressedVideo.msg": "83d044efaefc90291cdd56cd36b2ef6b190748c1df860d1eca7df77328174324", + "schemas/licenses/foxglove_schemas/LICENSE": "da11235665c17d4c1634072dae92b8ba1b38d6fdde2ccf19a6bbede33253f58d" + } + } +] diff --git a/dimos/message_codegen/templates/codec.rs b/dimos/message_codegen/templates/codec.rs new file mode 100644 index 00000000000..7507889426f --- /dev/null +++ b/dimos/message_codegen/templates/codec.rs @@ -0,0 +1,56 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use re_cdr::{BigEndian, LittleEndian}; +use serde::{de::DeserializeOwned, Serialize}; + +pub trait Message: Serialize + DeserializeOwned { + const NAME: &'static str; + const SCHEMA: &'static str; + + fn validate(&self) -> Result<(), String>; + + fn encode(&self) -> Result, String> { + self.encode_endian(true) + } + + fn encode_endian(&self, little_endian: bool) -> Result, String> { + self.validate()?; + let body = if little_endian { + re_cdr::to_vec::<_, LittleEndian>(self) + } else { + re_cdr::to_vec::<_, BigEndian>(self) + }.map_err(|error| error.to_string())?; + let mut bytes = Vec::with_capacity(4 + body.len()); + bytes.extend_from_slice(&[0, u8::from(little_endian), 0, 0]); + bytes.extend(body); + Ok(bytes) + } + + fn decode(bytes: &[u8]) -> Result { + if bytes.len() < 4 || bytes[0] != 0 || bytes[1] > 1 || bytes[2] != 0 || bytes[3] != 0 { + return Err("Expected plain CDR/XCDR1 encapsulation".into()); + } + let (value, consumed): (Self, usize) = if bytes[1] == 1 { + re_cdr::from_bytes::(&bytes[4..]) + } else { + re_cdr::from_bytes::(&bytes[4..]) + }.map_err(|error| error.to_string())?; + if consumed != bytes.len() - 4 { + return Err("Trailing bytes after CDR message".into()); + } + value.validate()?; + Ok(value) + } +} diff --git a/dimos/message_codegen/templates/dimos_cdr.hpp b/dimos/message_codegen/templates/dimos_cdr.hpp new file mode 100644 index 00000000000..40f81ff51de --- /dev/null +++ b/dimos/message_codegen/templates/dimos_cdr.hpp @@ -0,0 +1,71 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace dimos::cdr { + +template +std::vector encode(const T& value, bool little_endian = true) try { + using namespace eprosima::fastcdr; + value.validate(); + size_t alignment = 0; + CdrSizeCalculator calculator(CdrVersion::XCDRv1); + const auto body_size = calculator.calculate_serialized_size(value, alignment); + std::vector bytes(4 + body_size, 0); + FastBuffer buffer(reinterpret_cast(bytes.data()), bytes.size()); + Cdr writer(buffer, little_endian ? Cdr::LITTLE_ENDIANNESS : Cdr::BIG_ENDIANNESS, + CdrVersion::XCDRv1); + writer.serialize_encapsulation(); + writer << value; + bytes.resize(writer.get_serialized_data_length()); + return bytes; +} catch (const eprosima::fastcdr::exception::Exception& error) { + throw std::invalid_argument(error.what()); +} + +template +T decode(const uint8_t* bytes, size_t size) try { + using namespace eprosima::fastcdr; + if (size < 4 || bytes[0] != 0 || bytes[1] > 1 || bytes[2] != 0 || bytes[3] != 0) { + throw std::invalid_argument("Expected plain CDR/XCDR1 encapsulation"); + } + // FastBuffer's API takes mutable storage; decoding only reads it. + FastBuffer buffer(reinterpret_cast(const_cast(bytes)), size); + Cdr reader(buffer, Cdr::DEFAULT_ENDIAN, CdrVersion::XCDRv1); + reader.read_encapsulation(); + T value{}; + reader >> value; + if (reader.get_serialized_data_length() != size) { + throw std::invalid_argument("Trailing bytes after CDR message"); + } + value.validate(); + return value; +} catch (const eprosima::fastcdr::exception::Exception& error) { + throw std::invalid_argument(error.what()); +} + +template +T decode(const std::vector& bytes) { + return decode(bytes.data(), bytes.size()); +} + +} // namespace dimos::cdr diff --git a/dimos/message_codegen/templates/dimos_python.hpp b/dimos/message_codegen/templates/dimos_python.hpp new file mode 100644 index 00000000000..8772cc3696a --- /dev/null +++ b/dimos/message_codegen/templates/dimos_python.hpp @@ -0,0 +1,151 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace dimos::python { +namespace py = pybind11; + +struct BorrowState { + size_t count = 0; +}; + +inline py::object owner_root(py::object owner) { + return py::hasattr(owner, "__dimos_owner") ? owner.attr("__dimos_owner") : owner; +} + +inline std::shared_ptr borrow_state(py::object owner) { + owner = owner_root(owner); + if (!py::hasattr(owner, "__dimos_buffers")) { + owner.attr("__dimos_buffers") = py::capsule( + new std::shared_ptr(std::make_shared()), + [](void* value) { delete static_cast*>(value); }); + } + auto capsule = owner.attr("__dimos_buffers").cast(); + return *static_cast*>(capsule.get_pointer()); +} + +inline void require_unborrowed(py::object owner) { + if (borrow_state(owner)->count != 0) { + throw py::buffer_error("Cannot replace or resize message storage while a NumPy view is borrowed"); + } +} + +struct Borrow { + py::object owner; + std::shared_ptr state; + + explicit Borrow(py::object value) : owner(owner_root(value)), state(borrow_state(owner)) { + ++state->count; + } + ~Borrow() { --state->count; } +}; + +template +struct Sequence { + Container* values; + py::object owner; +}; + +template +Container sequence_from_python(py::handle value) { + using T = typename Container::value_type; + if constexpr (std::is_arithmetic_v && !std::is_same_v) { + if (PyObject_CheckBuffer(value.ptr())) { + auto info = py::reinterpret_borrow(value).request(); + if (info.ndim == 1 && info.itemsize == sizeof(T) && + info.format == py::format_descriptor::format() && info.strides[0] == sizeof(T)) { + const auto* first = static_cast(info.ptr); + if constexpr (std::is_same_v>) { + return Container(first, first + info.size); + } else { + Container result{}; + if (static_cast(info.size) != result.size()) { + throw py::value_error("Incorrect fixed-array length"); + } + std::copy(first, first + info.size, result.begin()); + return result; + } + } + } + } + return py::cast(value); +} + +template +void bind_sequence(py::module_& module, const char* name) { + if (py::hasattr(module, name)) return; + using T = typename Container::value_type; + using View = Sequence; + auto cls = py::class_(module, name, py::module_local()); + cls.def("__len__", [](const View& self) { return self.values->size(); }); + cls.def("__getitem__", [](const View& self, py::ssize_t index) { + if (index < 0) index += self.values->size(); + if (index < 0 || static_cast(index) >= self.values->size()) throw py::index_error(); + // Message elements are values. Assign an edited element back explicitly; + // a vector resize must never leave a Python object pointing into it. + return T((*self.values)[index]); + }); + cls.def("__setitem__", [](View& self, py::ssize_t index, const T& value) { + if (index < 0) index += self.values->size(); + if (index < 0 || static_cast(index) >= self.values->size()) throw py::index_error(); + (*self.values)[index] = value; + }); + cls.def("__iter__", [](const View& self) { + return py::iter(py::cast(Container(*self.values))); + }); + cls.def("__repr__", [](const View& self) { return py::repr(py::cast(*self.values)); }); + cls.def("__eq__", [](const View& self, py::object other) { + if (!PySequence_Check(other.ptr())) return false; + return py::cast(*self.values).equal(py::list(other)); + }); + if constexpr (std::is_same_v>) { + cls.def("append", [](View& self, const T& value) { + require_unborrowed(self.owner); + self.values->push_back(value); + }); + cls.def("extend", [](View& self, py::iterable values) { + require_unborrowed(self.owner); + auto extra = sequence_from_python(values); + self.values->insert(self.values->end(), extra.begin(), extra.end()); + }); + cls.def("clear", [](View& self) { + require_unborrowed(self.owner); + self.values->clear(); + }); + } + if constexpr (std::is_arithmetic_v && !std::is_same_v) { + cls.def("view", [](const View& self) { + py::capsule owner(new Borrow(self.owner), [](void* value) { delete static_cast(value); }); + py::array result(py::dtype::of(), {self.values->size()}, {sizeof(T)}, self.values->data(), owner); + result.attr("setflags")(py::arg("write") = false); + return result; + }); + cls.def("copy", [](const View& self) { + py::array_t result(self.values->size()); + std::copy(self.values->begin(), self.values->end(), result.mutable_data()); + return result; + }); + } +} + +} // namespace dimos::python diff --git a/dimos/message_codegen/test_definitions.py b/dimos/message_codegen/test_definitions.py new file mode 100644 index 00000000000..5d8aaad0eb2 --- /dev/null +++ b/dimos/message_codegen/test_definitions.py @@ -0,0 +1,136 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pathlib import Path + +import pytest +from rosbags.typesys import get_types_from_msg + +from dimos.message_codegen.definitions import Definitions, parse_message + + +def write_message(root: Path, name: str, text: str) -> Path: + path = root / f"{name}.msg" + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(text) + return path + + +def test_resolves_standard_dependencies_without_ros(tmp_path): + write_message(tmp_path, "example_msgs/msg/Telemetry", "sensor_msgs/Image image\nstring label\n") + + definitions = Definitions([tmp_path]) + closure = definitions.resolve(["example_msgs/msg/Telemetry"]) + + assert [message.name for message in closure] == [ + "builtin_interfaces/msg/Time", + "std_msgs/msg/Header", + "sensor_msgs/msg/Image", + "example_msgs/msg/Telemetry", + ] + reflected = get_types_from_msg( + definitions.schema("example_msgs/msg/Telemetry"), "example_msgs/msg/Telemetry" + ) + assert set(reflected) == {message.name for message in closure} + + +def test_preserves_defaults_constants_and_bounds(tmp_path): + path = write_message( + tmp_path, + "example_msgs/msg/Telemetry", + "uint8 MODE=7\nstring<=12 label 'hello'\nfloat64[3] xyz [1, 2, 3]\nint32[<=4] values [4]\n", + ) + + message = parse_message(path) + + assert message.constants[0].value == 7 + assert message.fields[0].default == "hello" + assert message.fields[0].type.string_bound == 12 + assert message.fields[1].default == (1.0, 2.0, 3.0) + assert message.fields[1].type.array_size == 3 + assert not message.fields[1].type.sequence + assert message.fields[2].type.sequence + assert message.fields[2].type.array_size == 4 + + +def test_conflicting_definition_reports_both_sources(tmp_path): + first = write_message(tmp_path / "one", "example_msgs/msg/Value", "int32 value\n") + second = write_message(tmp_path / "two", "example_msgs/msg/Value", "float64 value\n") + + with pytest.raises(ValueError, match="Conflicting definition") as error: + Definitions([tmp_path / "one", tmp_path / "two"], bundled=False) + + assert str(first) in str(error.value) + assert str(second) in str(error.value) + + +def test_explicit_empty_sequence_default(tmp_path): + path = write_message(tmp_path, "example_msgs/msg/Value", "int32[<=8] values []\n") + + message = parse_message(path) + + assert message.fields[0].default == () + + +def test_equivalent_definitions_ignore_comments(tmp_path): + write_message(tmp_path / "one", "example_msgs/msg/Value", "int32 value # comment\n") + write_message(tmp_path / "two", "example_msgs/msg/Value", "# another comment\nint32 value\n") + + closure = Definitions([tmp_path / "one", tmp_path / "two"], bundled=False).resolve() + + assert [message.name for message in closure] == ["example_msgs/msg/Value"] + + +def test_missing_dependency_reports_source(tmp_path): + source = write_message(tmp_path, "example_msgs/msg/Value", "other_msgs/Absent value\n") + + with pytest.raises( + ValueError, match="unresolved message dependency other_msgs/msg/Absent" + ) as error: + Definitions([tmp_path], bundled=False).resolve() + + assert str(source) in str(error.value) + + +def test_recursive_message_reports_chain(tmp_path): + write_message(tmp_path, "example_msgs/msg/First", "Second second\n") + write_message(tmp_path, "example_msgs/msg/Second", "First first\n") + + with pytest.raises( + ValueError, match="First -> example_msgs/msg/Second -> example_msgs/msg/First" + ): + Definitions([tmp_path], bundled=False).resolve() + + +def test_invalid_field_reports_source_line(tmp_path): + source = write_message( + tmp_path, "example_msgs/msg/Value", "# title\nint32 first\nuint8 BADNAME\n" + ) + + with pytest.raises(ValueError) as error: + parse_message(source) + + assert f"{source}:3:" in str(error.value) + + +def test_all_bundled_schemas_resolve(): + closure = Definitions([]).resolve() + + assert "sensor_msgs/msg/PointCloud2" in {message.name for message in closure} + assert "visualization_msgs/msg/MarkerArray" in {message.name for message in closure} + assert all( + dependency in {item.name for item in closure} + for message in closure + for dependency in message.dependencies + ) diff --git a/dimos/message_codegen/test_native.py b/dimos/message_codegen/test_native.py new file mode 100644 index 00000000000..7e29108028f --- /dev/null +++ b/dimos/message_codegen/test_native.py @@ -0,0 +1,183 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Run against the generated example extension; see its README build commands.""" + +import gc +import pickle +import weakref + +import numpy as np +import pytest +from rosbags.typesys import Stores, get_types_from_msg, get_typestore + +generated = pytest.importorskip("dimos_generated", reason="Build examples/message-codegen first") +Telemetry = generated.demo_msgs.msg.Telemetry +ImageEnvelope = generated.demo_msgs.msg.ImageEnvelope +Image = generated.sensor_msgs.msg.Image + + +def test_all_generated_types_match_independent_codec(): + reference = get_typestore(Stores.ROS2_JAZZY) + message_types = [ + value + for package in vars(generated).values() + if hasattr(package, "msg") + for value in vars(package.msg).values() + if isinstance(value, type) and hasattr(value, "msg_name") + ] + assert len(message_types) >= 142 + for message_type in message_types: + reference.register(get_types_from_msg(message_type.schema, message_type.msg_name)) + for little_endian in (True, False): + encoded = message_type().encode(little_endian=little_endian) + decoded = reference.deserialize_cdr(encoded, message_type.msg_name) + canonical = bytes( + reference.serialize_cdr(decoded, message_type.msg_name, little_endian=little_endian) + ) + assert encoded == canonical, message_type.msg_name + assert message_type.decode(canonical).encode(little_endian=little_endian) == encoded + + +def test_native_defaults_match_definition(): + value = Telemetry() + + assert list(value.hops) == [] + assert list(value.axes) == [1.0, 2.0, 3.0] + assert value.reading.temperature == 21.5 + assert value.reading.active is True + assert value.label == "start" + + +def test_sequence_and_nested_edits_survive_serialization(): + value = Telemetry() + value.hops.append(4) + value.hops.extend([5, 6]) + value.axes[1] = -2.0 + value.reading.temperature = 37.5 + + decoded = Telemetry.decode(value.encode()) + + assert list(decoded.hops) == [4, 5, 6] + assert list(decoded.axes) == [1.0, -2.0, 3.0] + assert decoded.reading.temperature == 37.5 + + +def test_numpy_views_are_readonly_and_share_native_storage(): + value = Image(data=np.arange(16, dtype=np.uint8)) + first = value.data.view() + second = value.data.view() + + assert np.shares_memory(first, second) + assert not first.flags.writeable + np.testing.assert_array_equal(first, np.arange(16, dtype=np.uint8)) + with pytest.raises(ValueError, match="read-only"): + first[0] = 7 + + +def test_mutable_copy_is_independent(): + value = Image(data=[1, 2, 3]) + view = value.data.view() + copied = value.data.copy() + copied[0] = 9 + + assert copied.flags.writeable + assert not np.shares_memory(view, copied) + assert list(value.data) == [1, 2, 3] + + +def test_view_retains_owner_until_released(): + value = Image(data=[1, 2, 3]) + owner = weakref.ref(value) + view = value.data.view() + del value + gc.collect() + + assert owner() is not None + np.testing.assert_array_equal(view, [1, 2, 3]) + del view + gc.collect() + assert owner() is None + + +def test_all_views_must_be_released_before_resize(): + value = Image(data=[1, 2, 3]) + first = value.data.view() + second = value.data.view() + + with pytest.raises(BufferError, match="borrowed"): + value.data.append(4) + with pytest.raises(BufferError, match="borrowed"): + value.data = [9, 8] + del first + with pytest.raises(BufferError, match="borrowed"): + value.data.clear() + del second + value.data.append(4) + assert list(value.data) == [1, 2, 3, 4] + + +def test_nested_buffer_prevents_parent_replacement(): + parent = ImageEnvelope(image=Image(data=[1, 2, 3])) + view = parent.image.data.view() + + with pytest.raises(BufferError, match="borrowed"): + parent.image = Image(data=[9]) + del parent + gc.collect() + np.testing.assert_array_equal(view, [1, 2, 3]) + + +def test_fixed_array_view_tracks_element_edits(): + value = Telemetry() + view = value.axes.view() + value.axes[0] = 7 + + assert view[0] == 7 + with pytest.raises(BufferError, match="borrowed"): + value.axes = [4, 5, 6] + + +def test_bounds_are_checked_on_encoding(): + value = Telemetry() + value.hops.extend(range(9)) + + with pytest.raises(ValueError, match="sequence bound"): + value.encode() + value.hops.clear() + value.label = "x" * 33 + with pytest.raises(ValueError, match="string bound"): + value.encode() + + +def test_fixed_array_rejects_wrong_length(): + with pytest.raises((TypeError, ValueError, RuntimeError)): + Telemetry(axes=[1, 2]) + + +def test_pickle_preserves_values_for_worker_ipc(): + value = Telemetry(sequence=99, hops=[1, 2], payload=[0, 255]) + value.header.frame_id = "map" + + restored = pickle.loads(pickle.dumps(value)) + + assert restored.encode() == value.encode() + restored.hops.append(3) + assert list(value.hops) == [1, 2] + + +def test_standard_string_message_round_trips(): + value = generated.std_msgs.msg.String(data="hello") + + assert value.decode(value.encode()).data == "hello" diff --git a/examples/message-codegen/EVIDENCE.md b/examples/message-codegen/EVIDENCE.md new file mode 100644 index 00000000000..ceb872a97de --- /dev/null +++ b/examples/message-codegen/EVIDENCE.md @@ -0,0 +1,78 @@ +# Stage 1 local verification + +Captured on 2026-09-21 on Linux x86_64 with Python 3.12, GCC 16, and Rust 1.98. +These are terminal demos intended for human inspection, executed automatically. +The ROS reference runs independently in a Jazzy container. + +The full build generated 142 message types. Focused verification after adding +the all-types oracle passed **22 tests**. The raw transport passed nine unit tests +and one doctest. `cargo build --offline` also passed after dependency setup. + +## relay + +```text +Python sends: sequence=40 label=start hops=[1] +C++ received: frame=map sequence=40 label=start temperature=21.5 x=4.25 axes=[1,2,3] +Rust received: frame=map sequence=41 label=start/cpp temperature=21.5 x=4.25 axes=[1.0, 2.0, 3.0] +Python receives: sequence=42 label=start/cpp/rust hops=[1, 2, 3] +Nested fields, fixed arrays, bytes, defaults, and edits survived. Evidence: build/message-codegen/demo/evidence +``` + +## conformance + +```text +LE Python -> Python: fields and bytes match +LE Python -> C++ : fields and bytes match +LE Python -> Rust : fields and bytes match +LE C++ -> Python: fields and bytes match +LE C++ -> C++ : fields and bytes match +LE C++ -> Rust : fields and bytes match +LE Rust -> Python: fields and bytes match +LE Rust -> C++ : fields and bytes match +LE Rust -> Rust : fields and bytes match +BE Python -> Python: fields and bytes match +BE Python -> C++ : fields and bytes match +BE Python -> Rust : fields and bytes match +BE C++ -> Python: fields and bytes match +BE C++ -> C++ : fields and bytes match +BE C++ -> Rust : fields and bytes match +BE Rust -> Python: fields and bytes match +BE Rust -> C++ : fields and bytes match +BE Rust -> Rust : fields and bytes match +Python/C++/Rust reject truncated +Python/C++/Rust reject unsupported representation +Python/C++/Rust reject trailing bytes +Python/C++/Rust reject missing header +All nine encoder/decoder combinations and both input byte orders match the independent ROS2 codec. +``` + +## buffers + +```text +640x480 RGB image: 921,600 bytes, shared read-only view; resize rejected + local median (microseconds): borrow=4.2, copy=31.6, encode=71.4, decode=74.2 +100,000-point buffer: 1,200,000 bytes, shared read-only view; resize rejected + local median (microseconds): borrow=5.7, copy=47.0, encode=119.3, decode=128.2 +Borrowed image remains readable after its message variable is released. +``` + +## transport + +```text +Python -> native Rust -> Python: 128 raw bytes match +Python -> native Rust -> Python: 65536 raw bytes match +Python -> native Rust -> Python: 1048576 raw bytes match +``` + +## jazzy-reference + +```text +ROS2 Jazzy decoded python-le.cdr: every field matches +ROS2 Jazzy decoded python-be.cdr: every field matches +ROS2 Jazzy decoded C++.cdr: every field matches +ROS2 Jazzy decoded Rust.cdr: every field matches +ROS2 Jazzy confirms declared defaults, nested fields, bounds, arrays, Unicode, and both byte orders. +``` + +Reproduce with the commands in [README.md](README.md). CI retains fresh output +and binary payloads as artifacts; generated sources and build products are ignored. diff --git a/examples/message-codegen/README.md b/examples/message-codegen/README.md new file mode 100644 index 00000000000..cf13a5b30c8 --- /dev/null +++ b/examples/message-codegen/README.md @@ -0,0 +1,119 @@ +# A message without an upstream PR + +`demo_msgs/msg/Telemetry.msg` contains a standard ROS2 header, a custom nested +reading, a position, defaults, fixed and variable arrays, and a bounded string. +This example generates Python, C++, and Rust from that definition without ROS. +The native processes print the fields they receive and each adds its own hop. + +## Build dependencies + +Use Python 3.12+, a C++17 compiler, CMake 3.20+, and Rust 1.92+. Install Python +build/test dependencies into the checkout's virtual environment: + +```bash +uv venv .venv --python 3.12 +uv pip install --python .venv/bin/python pybind11==3.0.1 rosbags==0.11.0 pytest pytest-asyncio pytest-env numpy lcm-dimos-fork +``` + +Install Fast CDR 2.4.0 into a local build prefix. This setup step downloads source; +message generation and application runtime do not access the network: + +```bash +mkdir -p build/message-codegen +curl -fL https://github.com/eProsima/Fast-CDR/archive/refs/tags/v2.4.0.tar.gz \ + -o build/message-codegen/fastcdr.tar.gz +echo '79d8466107dd6b7d1defe961c4aa31735038937cf9dd1175cf6b0da0df2209ab build/message-codegen/fastcdr.tar.gz' | sha256sum -c - +tar -xzf build/message-codegen/fastcdr.tar.gz -C build/message-codegen +cmake -S build/message-codegen/Fast-CDR-2.4.0 \ + -B build/message-codegen/fastcdr-build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$PWD/build/message-codegen/install" \ + -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON +cmake --build build/message-codegen/fastcdr-build -j 2 +cmake --install build/message-codegen/fastcdr-build +``` + +## Generate and build all three languages + +Run from the repository root: + +```bash +.venv/bin/python -m dimos.message_codegen.generate \ + --package-root examples/message-codegen \ + --output build/message-codegen/demo +cmake -S build/message-codegen/demo/cpp -B build/message-codegen/demo/cpp/build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH="$PWD/build/message-codegen/install" \ + -DPython_EXECUTABLE="$PWD/.venv/bin/python" +cmake --build build/message-codegen/demo/cpp/build -j 2 +c++ -std=c++17 -Ibuild/message-codegen/install/include \ + -Ibuild/message-codegen/demo/cpp examples/message-codegen/relay.cpp \ + build/message-codegen/install/lib/libfastcdr.a \ + -o build/message-codegen/demo/cpp-relay +mkdir -p build/message-codegen/demo/rust/src/bin +cp examples/message-codegen/relay.rs build/message-codegen/demo/rust/src/bin/relay.rs +cargo build --manifest-path build/message-codegen/demo/rust/Cargo.toml +``` + +Cargo resolves build dependencies on the first build. Once cached, use `--offline` +to demonstrate that generation/builds do not fetch message definitions or ROS. + +## Run and inspect + +```bash +PYTHONPATH=build/message-codegen/demo/cpp/build \ + .venv/bin/python examples/message-codegen/demo_relay.py --build build/message-codegen/demo +PYTHONPATH=build/message-codegen/demo/cpp/build \ + .venv/bin/python examples/message-codegen/demo_conformance.py --build build/message-codegen/demo +.venv/bin/pytest dimos/message_codegen/test_definitions.py --noconftest -o addopts='' -q +``` + +The relay starts with sequence `40`, label `start`, and hops `[1]`. C++ increments +the sequence and adds hop `2`; Rust increments it again and adds hop `3`. Python +prints sequence `42`, label `start/cpp/rust`, and hops `[1, 2, 3]`. The terminal +also shows the nested temperature, position, and fixed-array values in each native +process. Binary artifacts remain under `build/message-codegen/demo/evidence/`. + +The conformance demo prints the nine native encoder/decoder combinations, checks +both byte orders against an independent ROS2 codec, and exercises rejected +payloads. It is a local conformance check, not a replacement for the planned ROS2 +Jazzy CI reference job. + +No background processes remain after either command. To clean up, remove the +example's ignored `build/message-codegen/demo` directory; removing the broader +`build/message-codegen` directory also removes the native toolchain installation. + +## Run the complete stage + +The same scripts drive local verification and CI: + +```bash +bash scripts/setup_message_codegen.sh +bash scripts/test_message_codegen.sh +``` + +The second command builds every bundled and demo message, runs the tests and +relay, prints image/point-cloud buffer timings, and exchanges raw LCM payloads +between Python and Rust, including a fragmented 1 MiB payload. It requires local +UDP multicast. Output and payloads are retained in the demo's `evidence/` folder. +The independent Jazzy job builds the same demo definitions with ROS generators +inside a container; ROS is absent from the standalone build and application. + +## Python sequence and buffer behavior + +Primitive sequences are live: `message.payload.append(7)` and indexed assignment +update the message. Nested message fields are live too. Elements of a sequence of +messages are values: edit a retrieved element and assign it back to persist the +change. This avoids dangling references when the sequence resizes. + +`image.data.view()` returns a read-only NumPy view retaining the message owner. +While any view exists, operations that replace nested storage or resize a sequence +on that owner raise `BufferError`. Scalar and in-place element updates remain +possible. `image.data.copy()` returns an independent, writable NumPy array. +The terminal buffer demo reports local borrow/copy/encode/decode medians; these +are reproducible measurements, not platform-independent performance guarantees. + +## Current stage scope + +This stage provides standalone generation and codecs. DimOS runtime consumers +still use the old types; their coordinated replacement follows in the stack. diff --git a/examples/message-codegen/demo_buffers.py b/examples/message-codegen/demo_buffers.py new file mode 100644 index 00000000000..e2feee07633 --- /dev/null +++ b/examples/message-codegen/demo_buffers.py @@ -0,0 +1,88 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Show safe native buffer borrowing and report a reproducible local baseline.""" + +import gc +from statistics import median +from time import perf_counter_ns + +from dimos_generated.sensor_msgs.msg import Image, PointCloud2, PointField +import numpy as np + + +def main() -> None: + pixels = np.arange(640 * 480 * 3, dtype=np.uint8) + points = np.arange(100_000 * 3, dtype=np.float32).view(np.uint8) + fixtures = { + "640x480 RGB image": Image( + height=480, width=640, step=640 * 3, encoding="rgb8", data=pixels + ), + "100,000-point buffer": PointCloud2( + height=1, + width=100_000, + point_step=12, + row_step=1_200_000, + data=points, + fields=[ + PointField(name=name, offset=index * 4, datatype=PointField.FLOAT32, count=1) + for index, name in enumerate(("x", "y", "z")) + ], + is_dense=True, + ), + } + for label, message in fixtures.items(): + view = message.data.view() + assert np.shares_memory(view, message.data.view()) + assert not view.flags.writeable + try: + message.data.append(0) + except BufferError: + print(f"{label}: {view.nbytes:,} bytes, shared read-only view; resize rejected") + else: + raise AssertionError("Borrowed buffer allowed resizing") + copied = message.data.copy() + assert not np.shares_memory(view, copied) + assert copied.flags.writeable + del view + durations = {"borrow": [], "copy": [], "encode": [], "decode": []} + encoded = message.encode() + for _ in range(30): + start = perf_counter_ns() + borrowed = message.data.view() + durations["borrow"].append(perf_counter_ns() - start) + del borrowed + start = perf_counter_ns() + copied = message.data.copy() + durations["copy"].append(perf_counter_ns() - start) + start = perf_counter_ns() + encoded = message.encode() + durations["encode"].append(perf_counter_ns() - start) + start = perf_counter_ns() + decoded = type(message).decode(encoded) + durations["decode"].append(perf_counter_ns() - start) + assert decoded.encode() == encoded + print( + " local median (microseconds): " + + ", ".join(f"{name}={median(values) / 1000:.1f}" for name, values in durations.items()) + ) + last_view = fixtures["640x480 RGB image"].data.view() + fixtures.clear() + gc.collect() + np.testing.assert_array_equal(last_view, pixels) + print("Borrowed image remains readable after its message variable is released.") + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/demo_conformance.py b/examples/message-codegen/demo_conformance.py new file mode 100644 index 00000000000..3fe11a211f5 --- /dev/null +++ b/examples/message-codegen/demo_conformance.py @@ -0,0 +1,123 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Exercise real native encoders/decoders and an independent ROS2 codec.""" + +import argparse +from pathlib import Path +import subprocess + +from dimos_generated.demo_msgs.msg import Telemetry +from rosbags.typesys import Stores, get_types_from_msg, get_typestore + + +def relay( + executable: Path, source: Path, target: Path, mode: str = "echo" +) -> subprocess.CompletedProcess[str]: + return subprocess.run( + [str(executable), mode, str(source), str(target)], + text=True, + capture_output=True, + check=False, + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--build", type=Path, required=True) + args = parser.parse_args() + build = args.build.resolve() + evidence = build / "evidence" + evidence.mkdir(exist_ok=True) + native = {"C++": build / "cpp-relay", "Rust": build / "rust/target/debug/relay"} + reference = get_typestore(Stores.ROS2_JAZZY) + reference.register(get_types_from_msg(Telemetry.schema, Telemetry.msg_name)) + defaults = Telemetry().encode() + (evidence / "defaults-python.cdr").write_bytes(defaults) + for language, executable in native.items(): + target = evidence / f"defaults-{language}.cdr" + result = relay(executable, evidence / "defaults-python.cdr", target, "defaults") + assert result.returncode == 0, result.stderr + assert target.read_bytes() == defaults + fixture = Telemetry( + sequence=4294967295, hops=[-2147483648, 2147483647], payload=list(range(256)) + ) + fixture.header.stamp.sec = -1 + fixture.header.stamp.nanosec = 999999999 + fixture.header.frame_id = "map" + fixture.label = "café" + fixture.position.x = -1.25 + for endian in (True, False): + encoded = fixture.encode(little_endian=endian) + (evidence / ("python-le.cdr" if endian else "python-be.cdr")).write_bytes(encoded) + (evidence / "source.cdr").write_bytes(encoded) + decoded = reference.deserialize_cdr(encoded, Telemetry.msg_name) + assert decoded.header.stamp.sec == -1 + assert decoded.sequence == 4294967295 + assert decoded.label == "café" + assert decoded.reading.temperature == 21.5 + assert decoded.position.x == -1.25 + assert list(decoded.hops) == [-2147483648, 2147483647] + assert list(decoded.payload) == list(range(256)) + canonical = bytes(reference.serialize_cdr(decoded, Telemetry.msg_name, little_endian=True)) + assert encoded == bytes( + reference.serialize_cdr(decoded, Telemetry.msg_name, little_endian=endian) + ) + produced = {"Python": encoded} + for language, executable in native.items(): + target = evidence / f"{language}.cdr" + result = relay( + executable, evidence / "source.cdr", target, "echo" if endian else "echo-be" + ) + assert result.returncode == 0, result.stderr + produced[language] = target.read_bytes() + assert produced[language] == encoded + for producer, payload in produced.items(): + decoded_python = Telemetry.decode(payload) + assert decoded_python.encode() == canonical + print(f"{'LE' if endian else 'BE'} {producer:6} -> Python: fields and bytes match") + (evidence / "matrix.cdr").write_bytes(payload) + for consumer, executable in native.items(): + result = relay(executable, evidence / "matrix.cdr", evidence / "decoded.cdr") + assert result.returncode == 0, result.stderr + assert (evidence / "decoded.cdr").read_bytes() == canonical + print( + f"{'LE' if endian else 'BE'} {producer:6} -> {consumer:6}: fields and bytes match" + ) + encoded = fixture.encode() + malformed = { + "truncated": encoded[:-1], + "unsupported representation": b"\x00\x07\x00\x00" + encoded[4:], + "trailing bytes": encoded + b"\x00", + "missing header": b"\x00", + } + for reason, payload in malformed.items(): + try: + Telemetry.decode(payload) + except (ValueError, RuntimeError): + pass + else: + raise AssertionError(f"Python accepted {reason}") + (evidence / "invalid.cdr").write_bytes(payload) + for language, executable in native.items(): + result = relay(executable, evidence / "invalid.cdr", evidence / "invalid-output.cdr") + assert result.returncode == 1, (language, reason, result.stderr) + print(f"Python/C++/Rust reject {reason}") + print( + "All nine encoder/decoder combinations and both input byte orders match the independent ROS2 codec." + ) + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/demo_msgs/CMakeLists.txt b/examples/message-codegen/demo_msgs/CMakeLists.txt new file mode 100644 index 00000000000..678cf68d3e6 --- /dev/null +++ b/examples/message-codegen/demo_msgs/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.20) +project(demo_msgs) +find_package(ament_cmake REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) +find_package(geometry_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) +rosidl_generate_interfaces(${PROJECT_NAME} + "msg/Reading.msg" + "msg/Telemetry.msg" + "msg/ImageEnvelope.msg" + DEPENDENCIES std_msgs geometry_msgs sensor_msgs) +ament_export_dependencies(rosidl_default_runtime) +ament_package() diff --git a/examples/message-codegen/demo_msgs/msg/ImageEnvelope.msg b/examples/message-codegen/demo_msgs/msg/ImageEnvelope.msg new file mode 100644 index 00000000000..22ac3d3400a --- /dev/null +++ b/examples/message-codegen/demo_msgs/msg/ImageEnvelope.msg @@ -0,0 +1,2 @@ +# Exercise a buffer borrowed through a nested generated message. +sensor_msgs/Image image diff --git a/examples/message-codegen/demo_msgs/msg/Reading.msg b/examples/message-codegen/demo_msgs/msg/Reading.msg new file mode 100644 index 00000000000..5ba02abfcf1 --- /dev/null +++ b/examples/message-codegen/demo_msgs/msg/Reading.msg @@ -0,0 +1,4 @@ +# A nested application-defined message; no DimOS registry entry is needed. +float64 temperature 21.5 +uint8 flags 3 +bool active true diff --git a/examples/message-codegen/demo_msgs/msg/Telemetry.msg b/examples/message-codegen/demo_msgs/msg/Telemetry.msg new file mode 100644 index 00000000000..4aed948a78a --- /dev/null +++ b/examples/message-codegen/demo_msgs/msg/Telemetry.msg @@ -0,0 +1,9 @@ +# The same definition drives all three native language outputs. +std_msgs/Header header +Reading reading +geometry_msgs/Point position +string<=32 label "start" +uint32 sequence 0 +float64[3] axes [1.0, 2.0, 3.0] +uint8[] payload +int32[<=8] hops diff --git a/examples/message-codegen/demo_msgs/package.xml b/examples/message-codegen/demo_msgs/package.xml new file mode 100644 index 00000000000..1426d261892 --- /dev/null +++ b/examples/message-codegen/demo_msgs/package.xml @@ -0,0 +1,16 @@ + + + demo_msgs + 0.1.0 + Independent ROS2 reference build for the DimOS message conformance demo. + Dimensional + Apache-2.0 + ament_cmake + rosidl_default_generators + std_msgs + geometry_msgs + sensor_msgs + rosidl_default_runtime + rosidl_interface_packages + ament_cmake + diff --git a/examples/message-codegen/demo_relay.py b/examples/message-codegen/demo_relay.py new file mode 100644 index 00000000000..682c76a6506 --- /dev/null +++ b/examples/message-codegen/demo_relay.py @@ -0,0 +1,66 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Show one locally defined message crossing Python, C++, Rust, then Python.""" + +import argparse +from pathlib import Path +import subprocess + +from dimos_generated.demo_msgs.msg import Telemetry + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--build", type=Path, required=True) + args = parser.parse_args() + build = args.build.resolve() + outputs = build / "evidence" + outputs.mkdir(exist_ok=True) + message = Telemetry(sequence=40, hops=[1], payload=[0, 127, 255]) + message.header.frame_id = "map" + message.position.x = 4.25 + (outputs / "python.cdr").write_bytes(message.encode()) + print( + f"Python sends: sequence={message.sequence} label={message.label} hops={message.hops}", + flush=True, + ) + subprocess.run( + [str(build / "cpp-relay"), "edit", str(outputs / "python.cdr"), str(outputs / "cpp.cdr")], + check=True, + ) + subprocess.run( + [ + str(build / "rust" / "target" / "debug" / "relay"), + "edit", + str(outputs / "cpp.cdr"), + str(outputs / "rust.cdr"), + ], + check=True, + ) + received = Telemetry.decode((outputs / "rust.cdr").read_bytes()) + print( + f"Python receives: sequence={received.sequence} label={received.label} hops={received.hops}" + ) + assert received.sequence == 42 + assert received.label == "start/cpp/rust" + assert received.hops == [1, 2, 3] + assert received.payload == [0, 127, 255] + assert received.reading.temperature == 21.5 + assert received.position.x == 4.25 + print(f"Nested fields, fixed arrays, bytes, defaults, and edits survived. Evidence: {outputs}") + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/demo_ros_reference.py b/examples/message-codegen/demo_ros_reference.py new file mode 100644 index 00000000000..7a82a1b0219 --- /dev/null +++ b/examples/message-codegen/demo_ros_reference.py @@ -0,0 +1,56 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""CI-only conformance with ROS2 Jazzy's independently generated types and RMW.""" + +import argparse +from pathlib import Path + +from demo_msgs.msg import Telemetry as RosTelemetry +from rclpy.serialization import deserialize_message, serialize_message + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--build", type=Path, required=True) + args = parser.parse_args() + build = args.build.resolve() + evidence = build / "evidence" + for filename in ("defaults-python.cdr", "defaults-C++.cdr", "defaults-Rust.cdr"): + assert ( + deserialize_message((evidence / filename).read_bytes(), RosTelemetry) == RosTelemetry() + ), filename + reference = RosTelemetry( + sequence=4294967295, payload=list(range(256)), hops=[-2147483648, 2147483647] + ) + reference.header.frame_id = "map" + reference.header.stamp.sec = -1 + reference.header.stamp.nanosec = 999999999 + reference.label = "café" + reference.position.x = -1.25 + expected = serialize_message(reference) + for filename in ("python-le.cdr", "python-be.cdr", "C++.cdr", "Rust.cdr"): + decoded = deserialize_message((evidence / filename).read_bytes(), RosTelemetry) + # RMW may leave alignment padding unspecified. Compare every field; + # byte-canonical comparisons use the independent rosbags oracle. + assert decoded == reference, filename + print(f"ROS2 Jazzy decoded {filename}: every field matches") + (evidence / "ros-jazzy.cdr").write_bytes(expected) + print( + "ROS2 Jazzy confirms declared defaults, nested fields, bounds, arrays, Unicode, and both byte orders." + ) + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/demo_transport.py b/examples/message-codegen/demo_transport.py new file mode 100644 index 00000000000..b018697efcf --- /dev/null +++ b/examples/message-codegen/demo_transport.py @@ -0,0 +1,66 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Verify Python/native raw LCM interoperability, including fragmented payloads.""" + +import argparse +from pathlib import Path +import selectors +import socket +import subprocess +import time + +import lcm + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--executable", type=Path, required=True) + args = parser.parse_args() + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as port_socket: + port_socket.bind(("", 0)) + port = port_socket.getsockname()[1] + transport = lcm.LCM(f"udpm://239.255.76.67:{port}?ttl=0&recv_buf_size=4194304") + received: list[bytes] = [] + subscription = transport.subscribe("REPLY", lambda _channel, data: received.append(data)) + process = subprocess.Popen( + [str(args.executable.resolve()), str(port)], stdout=subprocess.PIPE, text=True + ) + try: + assert process.stdout is not None + with selectors.DefaultSelector() as ready: + ready.register(process.stdout, selectors.EVENT_READ) + assert ready.select(timeout=10), "Native transport did not become ready" + assert process.stdout.readline().strip() == "READY" + for size in (128, 65536, 1048576): + payload = bytes(index % 251 for index in range(size)) + transport.publish("INPUT", payload) + deadline = time.monotonic() + 10 + while not received and time.monotonic() < deadline: + transport.handle_timeout(100) + assert received, f"No reply for {size} bytes" + assert received.pop(0) == payload + print(f"Python -> native Rust -> Python: {size} raw bytes match", flush=True) + assert process.wait(timeout=10) == 0 + finally: + transport.unsubscribe(subscription) + if process.poll() is None: + process.terminate() + process.wait(timeout=10) + if process.stdout is not None: + process.stdout.close() + + +if __name__ == "__main__": + main() diff --git a/examples/message-codegen/relay.cpp b/examples/message-codegen/relay.cpp new file mode 100644 index 00000000000..3bf83de80e3 --- /dev/null +++ b/examples/message-codegen/relay.cpp @@ -0,0 +1,52 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "messages.hpp" + +int main(int argc, char** argv) { + if (argc != 4) { + std::cerr << "usage: relay \n"; + return 2; + } + try { + std::ifstream input(argv[2], std::ios::binary); + if (!input) throw std::runtime_error("Cannot open input"); + std::vector bytes((std::istreambuf_iterator(input)), {}); + const std::string mode(argv[1]); + auto value = mode == "defaults" ? demo_msgs::msg::Telemetry{} : dimos::cdr::decode(bytes); + std::cout << "C++ received: frame=" << value.header.frame_id + << " sequence=" << value.sequence << " label=" << value.label + << " temperature=" << value.reading.temperature + << " x=" << value.position.x << " axes=[" << value.axes[0] + << "," << value.axes[1] << "," << value.axes[2] << "]\n"; + if (mode == "edit") { + ++value.sequence; + value.hops.push_back(2); + value.label += "/cpp"; + } else if (mode != "echo" && mode != "echo-be" && mode != "defaults") { + throw std::runtime_error("Expected edit, echo, echo-be, or defaults mode"); + } + const auto output = dimos::cdr::encode(value, mode != "echo-be"); + std::ofstream stream(argv[3], std::ios::binary); + stream.write(reinterpret_cast(output.data()), output.size()); + if (!stream) throw std::runtime_error("Cannot write output"); + } catch (const std::exception& error) { + std::cerr << error.what() << '\n'; + return 1; + } +} diff --git a/examples/message-codegen/relay.rs b/examples/message-codegen/relay.rs new file mode 100644 index 00000000000..6a38670afa1 --- /dev/null +++ b/examples/message-codegen/relay.rs @@ -0,0 +1,43 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use dimos_generated_messages::{codec::Message, demo_msgs::msg::Telemetry}; + +fn main() -> Result<(), Box> { + let arguments: Vec = std::env::args().collect(); + if arguments.len() != 4 { + return Err("usage: relay ".into()); + } + let mut value = if arguments[1] == "defaults" { Telemetry::default() } else { Telemetry::decode(&std::fs::read(&arguments[2])?)? }; + println!( + "Rust received: frame={} sequence={} label={} temperature={} x={} axes={:?}", + value.header.frame_id, + value.sequence, + value.label, + value.reading.temperature, + value.position.x, + value.axes, + ); + match arguments[1].as_str() { + "edit" => { + value.sequence += 1; + value.hops.push(3); + value.label.push_str("/rust"); + } + "echo" | "echo-be" | "defaults" => {} + _ => return Err("Expected edit, echo, echo-be, or defaults mode".into()), + } + std::fs::write(&arguments[3], value.encode_endian(arguments[1] != "echo-be")?)?; + Ok(()) +} diff --git a/native/rust/dimos-lcm-transport/Cargo.toml b/native/rust/dimos-lcm-transport/Cargo.toml new file mode 100644 index 00000000000..f83c98802d0 --- /dev/null +++ b/native/rust/dimos-lcm-transport/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "dimos-lcm-transport" +version = "0.1.0" +edition = "2021" +description = "Schema-independent LCM UDP multicast transport for DimOS" +license = "Apache-2.0" + +[dependencies] +byteorder = "1" +socket2 = { version = "0.5", features = ["all"] } +tokio = { version = "1.51.1", features = ["net", "rt-multi-thread", "macros", "time"] } diff --git a/native/rust/dimos-lcm-transport/README.md b/native/rust/dimos-lcm-transport/README.md new file mode 100644 index 00000000000..57907bcbf8e --- /dev/null +++ b/native/rust/dimos-lcm-transport/README.md @@ -0,0 +1,27 @@ +# DimOS raw LCM transport + +This crate publishes and receives opaque bytes over LCM UDP multicast. It has no +message definitions, fingerprints, generated message crate, or CDR dependency. +Typed consumers choose their own codec above this transport. + +The initial implementation was extracted from Dimensional's `dimos-lcm` repository, +`tools/rust/lcm`, commit `04d78e8622500244123ba9cefa4c51b4cb454549`, matching the +existing workspace lockfile. That crate declares Apache-2.0 in its Cargo manifest. +The source is maintained here so adding a message no longer depends on that +repository. Original transport behavior and its unit tests are retained; local +changes are reviewed in the DimOS history. + +Source: https://github.com/dimensionalOS/dimos-lcm/tree/04d78e8622500244123ba9cefa4c51b4cb454549/tools/rust/lcm + +Run the raw transport checks with: + +```bash +cargo test -p dimos-lcm-transport +cargo build -p dimos-lcm-transport --example interop +.venv/bin/python examples/message-codegen/demo_transport.py \ + --executable target/debug/examples/interop +``` + +The demo chooses a local UDP port, starts the native receiver, waits for its ready +signal, and exchanges both short and fragmented binary payloads with Python's LCM +binding. It terminates and reaps the native process even on failure. diff --git a/native/rust/dimos-lcm-transport/examples/interop.rs b/native/rust/dimos-lcm-transport/examples/interop.rs new file mode 100644 index 00000000000..efc4c9e9576 --- /dev/null +++ b/native/rust/dimos-lcm-transport/examples/interop.rs @@ -0,0 +1,46 @@ +// Copyright 2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use dimos_lcm_transport::{Lcm, LcmOptions}; +use std::io::{self, Write}; +use std::time::Duration; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let port = std::env::args() + .nth(1) + .ok_or("usage: interop ")? + .parse()?; + let transport = Lcm::with_options(LcmOptions { + port, + ttl: 0, + ..Default::default() + }) + .await?; + println!("READY"); + io::stdout().flush()?; + for _ in 0..3 { + let message = tokio::time::timeout(Duration::from_secs(10), async { + loop { + let message = transport.recv().await?; + if message.channel == "INPUT" { + return Ok::<_, io::Error>(message); + } + } + }) + .await??; + transport.publish("REPLY", &message.data).await?; + } + Ok(()) +} diff --git a/native/rust/dimos-lcm-transport/src/lib.rs b/native/rust/dimos-lcm-transport/src/lib.rs new file mode 100644 index 00000000000..1bbaef79375 --- /dev/null +++ b/native/rust/dimos-lcm-transport/src/lib.rs @@ -0,0 +1,41 @@ +// Copyright 2025-2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Pure Rust LCM (Lightweight Communications and Marshalling) transport. +//! +//! Provides UDP multicast publish/subscribe for LCM messages. +//! No system LCM library required. +//! +//! # Example +//! +//! ```no_run +//! use dimos_lcm_transport::Lcm; +//! +//! #[tokio::main] +//! async fn main() { +//! let mut lcm = Lcm::new().await.unwrap(); +//! +//! // Publish +//! let data = vec![1, 2, 3]; +//! lcm.publish("EXAMPLE", &data).await.unwrap(); +//! +//! // Receive +//! let msg = lcm.recv().await.unwrap(); +//! println!("{}: {} bytes", msg.channel, msg.data.len()); +//! } +//! ``` + +mod transport; + +pub use transport::{Lcm, LcmOptions, ReceivedMessage}; diff --git a/native/rust/dimos-lcm-transport/src/transport.rs b/native/rust/dimos-lcm-transport/src/transport.rs new file mode 100644 index 00000000000..5be58aa18b3 --- /dev/null +++ b/native/rust/dimos-lcm-transport/src/transport.rs @@ -0,0 +1,395 @@ +// Copyright 2025-2026 Dimensional Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use byteorder::{BigEndian, ByteOrder}; +use socket2::{Domain, Protocol, Socket, Type}; +use std::collections::HashMap; +use std::io; +use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::Mutex; +use tokio::net::UdpSocket; + +const MAGIC_SHORT: u32 = 0x4c433032; // "LC02" +const MAGIC_LONG: u32 = 0x4c433033; // "LC03" +const SHORT_HEADER_SIZE: usize = 8; +const FRAGMENT_HEADER_SIZE: usize = 20; +const MAX_DATAGRAM_SIZE: usize = 65507; + +/// Default LCM multicast group address. +pub const DEFAULT_MULTICAST_GROUP: Ipv4Addr = Ipv4Addr::new(239, 255, 76, 67); +/// Default LCM multicast port. +pub const DEFAULT_PORT: u16 = 7667; + +static SEQ: AtomicU32 = AtomicU32::new(0); + +struct FragmentBuffer { + channel: String, + num_fragments: u16, + received: u16, + data: Vec, +} + +/// Configuration for an LCM transport instance. +#[derive(Debug, Clone)] +pub struct LcmOptions { + /// Multicast group address (default: 239.255.76.67). + pub multicast_group: Ipv4Addr, + /// UDP port (default: 7667). + pub port: u16, + /// Multicast TTL (default: 1). + pub ttl: u32, + /// Network interface to bind to (default: any). + pub interface: Ipv4Addr, +} + +impl Default for LcmOptions { + fn default() -> Self { + Self { + multicast_group: DEFAULT_MULTICAST_GROUP, + port: DEFAULT_PORT, + ttl: 1, + interface: Ipv4Addr::UNSPECIFIED, + } + } +} + +/// A received LCM message. +#[derive(Debug, Clone)] +pub struct ReceivedMessage { + /// Channel name. + pub channel: String, + /// Encoded message payload. + pub data: Vec, +} + +/// Returns the first and subsequent payload sizes, and the number of fragments +fn fragment_params(msg_size: usize, channel_len: usize) -> (usize, usize, usize) { + let first_payload_size = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE - channel_len - 1; + let subsequent_payload_size = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE; + let num_fragments = if msg_size <= first_payload_size { + 1 + } else { + 1 + msg_size + .saturating_sub(first_payload_size) + .div_ceil(subsequent_payload_size) + }; + (first_payload_size, subsequent_payload_size, num_fragments) +} + +/// Pure Rust LCM UDP multicast transport. +pub struct Lcm { + socket: UdpSocket, + multicast_addr: SocketAddrV4, + reassembly: Mutex>, +} + +impl Lcm { + /// Create a new LCM transport with default options. + pub async fn new() -> io::Result { + Self::with_options(LcmOptions::default()).await + } + + /// Create a new LCM transport with custom options. + pub async fn with_options(opts: LcmOptions) -> io::Result { + let s2 = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?; + s2.set_reuse_address(true)?; + // Sensor messages arrive as bursts of large fragments. Request enough + // queue space to reassemble an image without relying on kernel defaults. + s2.set_recv_buffer_size(4 * 1024 * 1024)?; + #[cfg(not(target_os = "windows"))] + s2.set_reuse_port(true)?; + + let bind_addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, opts.port); + s2.bind(&bind_addr.into())?; + + let std_socket: std::net::UdpSocket = s2.into(); + std_socket.set_nonblocking(true)?; + let socket = UdpSocket::from_std(std_socket)?; + + socket.join_multicast_v4(opts.multicast_group, opts.interface)?; + socket.set_multicast_ttl_v4(opts.ttl)?; + + Ok(Self { + socket, + multicast_addr: SocketAddrV4::new(opts.multicast_group, opts.port), + reassembly: Mutex::new(HashMap::new()), + }) + } + + /// Publish encoded message data on the given channel. + pub async fn publish(&self, channel: &str, data: &[u8]) -> io::Result<()> { + let channel_bytes = channel.as_bytes(); + let total = SHORT_HEADER_SIZE + channel_bytes.len() + 1 + data.len(); + let seqno = SEQ.fetch_add(1, Ordering::Relaxed); + + if total > MAX_DATAGRAM_SIZE { + self.publish_fragmented(channel_bytes, data, seqno).await + } else { + self.publish_small(channel_bytes, data, seqno).await + } + } + + async fn publish_small(&self, channel_bytes: &[u8], data: &[u8], seqno: u32) -> io::Result<()> { + let total = SHORT_HEADER_SIZE + channel_bytes.len() + 1 + data.len(); + let mut buf = vec![0u8; total]; + + BigEndian::write_u32(&mut buf[0..4], MAGIC_SHORT); + BigEndian::write_u32(&mut buf[4..8], seqno); + + buf[SHORT_HEADER_SIZE..SHORT_HEADER_SIZE + channel_bytes.len()] + .copy_from_slice(channel_bytes); + // null terminator already 0 from vec![0u8; ..] + let payload_start = SHORT_HEADER_SIZE + channel_bytes.len() + 1; + buf[payload_start..].copy_from_slice(data); + + self.socket.send_to(&buf, self.multicast_addr).await?; + Ok(()) + } + + async fn publish_fragmented( + &self, + channel_bytes: &[u8], + data: &[u8], + seqno: u32, + ) -> io::Result<()> { + let msg_size = data.len(); + let (first_payload_size, subsequent_payload_size, num_fragments) = + fragment_params(msg_size, channel_bytes.len()); + + let mut payload_offset = 0; + + for fragment_no in 0..num_fragments { + let is_first = fragment_no == 0; + let channel_size = if is_first { channel_bytes.len() + 1 } else { 0 }; + let max_payload = if is_first { + first_payload_size + } else { + subsequent_payload_size + }; + let payload_len = (msg_size - payload_offset).min(max_payload); + + let datagram_size = FRAGMENT_HEADER_SIZE + channel_size + payload_len; + let mut buf = vec![0u8; datagram_size]; + + BigEndian::write_u32(&mut buf[0..4], MAGIC_LONG); + BigEndian::write_u32(&mut buf[4..8], seqno); + BigEndian::write_u32(&mut buf[8..12], msg_size as u32); + BigEndian::write_u32(&mut buf[12..16], payload_offset as u32); + BigEndian::write_u16(&mut buf[16..18], fragment_no as u16); + BigEndian::write_u16(&mut buf[18..20], num_fragments as u16); + + let mut offset = FRAGMENT_HEADER_SIZE; + + if is_first { + buf[offset..offset + channel_bytes.len()].copy_from_slice(channel_bytes); + // null terminator already 0 + offset += channel_bytes.len() + 1; + } + + buf[offset..offset + payload_len] + .copy_from_slice(&data[payload_offset..payload_offset + payload_len]); + + self.socket.send_to(&buf, self.multicast_addr).await?; + payload_offset += payload_len; + } + + Ok(()) + } + + /// Receive one LCM message asynchronously. + /// + /// Waits until a complete message arrives, reassembling fragments if necessary. + pub async fn recv(&self) -> io::Result { + let mut buf = vec![0u8; MAX_DATAGRAM_SIZE]; + loop { + let (n, sender) = self.socket.recv_from(&mut buf).await?; + let pkt = &buf[..n]; + + if pkt.len() < 4 { + continue; + } + let magic = BigEndian::read_u32(&pkt[0..4]); + + if magic == MAGIC_SHORT { + if let Some(msg) = Self::decode_small(pkt)? { + return Ok(msg); + } + } else if magic == MAGIC_LONG { + if let Some(msg) = self.process_fragment(sender, pkt)? { + return Ok(msg); + } + } + // Unknown magic or incomplete fragment — wait for the next datagram + } + } + + fn process_fragment( + &self, + sender: SocketAddr, + buf: &[u8], + ) -> io::Result> { + if buf.len() < FRAGMENT_HEADER_SIZE { + return Ok(None); + } + + let seqno = BigEndian::read_u32(&buf[4..8]); + let total_size = BigEndian::read_u32(&buf[8..12]) as usize; + let fragment_offset = BigEndian::read_u32(&buf[12..16]) as usize; + let fragment_no = BigEndian::read_u16(&buf[16..18]); + let num_fragments = BigEndian::read_u16(&buf[18..20]); + + let mut offset = FRAGMENT_HEADER_SIZE; + + // First fragment carries the channel name + let channel = if fragment_no == 0 { + let channel_end = match buf[offset..].iter().position(|&b| b == 0) { + Some(pos) => offset + pos, + None => return Ok(None), + }; + let ch = String::from_utf8_lossy(&buf[offset..channel_end]).into_owned(); + offset = channel_end + 1; + Some(ch) + } else { + None + }; + + let payload = &buf[offset..]; + + let key = (sender, seqno); + + let mut reassembly = self.reassembly.lock().unwrap(); + let entry = reassembly.entry(key).or_insert_with(|| FragmentBuffer { + channel: channel.clone().unwrap_or_default(), + num_fragments, + received: 0, + data: vec![0u8; total_size], + }); + + // First fragment also sets the channel name on an existing entry + if let Some(ch) = channel { + entry.channel = ch; + } + + let end = (fragment_offset + payload.len()).min(total_size); + entry.data[fragment_offset..end].copy_from_slice(&payload[..end - fragment_offset]); + entry.received += 1; + + if entry.received == entry.num_fragments { + let complete = reassembly.remove(&key).unwrap(); + return Ok(Some(ReceivedMessage { + channel: complete.channel, + data: complete.data, + })); + } + + Ok(None) + } + + fn decode_small(buf: &[u8]) -> io::Result> { + if buf.len() < SHORT_HEADER_SIZE || BigEndian::read_u32(&buf[0..4]) != MAGIC_SHORT { + return Ok(None); + } + let channel_start = SHORT_HEADER_SIZE; + let channel_end = match buf[channel_start..].iter().position(|&b| b == 0) { + Some(pos) => channel_start + pos, + None => return Ok(None), + }; + let channel = String::from_utf8_lossy(&buf[channel_start..channel_end]).into_owned(); + let data = buf[channel_end + 1..].to_vec(); + Ok(Some(ReceivedMessage { channel, data })) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_CHANNEL_LEN: usize = 13; // "/test_channel" + const FIRST_PAYLOAD: usize = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE - TEST_CHANNEL_LEN - 1; + const SUBSEQUENT_PAYLOAD: usize = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE; + + #[test] + fn fragment_count_fits_in_one() { + let (_, _, n) = fragment_params(FIRST_PAYLOAD, TEST_CHANNEL_LEN); + assert_eq!(n, 1); + } + + #[test] + fn fragment_count_spills_into_two() { + let (_, _, n) = fragment_params(FIRST_PAYLOAD + 1, TEST_CHANNEL_LEN); + assert_eq!(n, 2); + } + + #[test] + fn fragment_count_spills_into_three() { + let (_, _, n) = fragment_params(FIRST_PAYLOAD + SUBSEQUENT_PAYLOAD + 1, TEST_CHANNEL_LEN); + assert_eq!(n, 3); + } + + #[test] + fn fragment_count_one_mb() { + let (_, _, n) = fragment_params(1024 * 1024, TEST_CHANNEL_LEN); + assert_eq!(n, 17); + } + + fn make_small_packet(channel: &[u8], payload: &[u8]) -> Vec { + let mut buf = vec![0u8; SHORT_HEADER_SIZE + channel.len() + 1 + payload.len()]; + BigEndian::write_u32(&mut buf[0..4], MAGIC_SHORT); + BigEndian::write_u32(&mut buf[4..8], 0); + buf[SHORT_HEADER_SIZE..SHORT_HEADER_SIZE + channel.len()].copy_from_slice(channel); + buf[SHORT_HEADER_SIZE + channel.len() + 1..].copy_from_slice(payload); + buf + } + + #[test] + fn decode_small_known_good() { + let buf = make_small_packet(b"CHAN", &[1, 2, 3]); + let msg = Lcm::decode_small(&buf).unwrap().unwrap(); + assert_eq!(msg.channel, "CHAN"); + assert_eq!(msg.data, [1u8, 2, 3]); + } + + #[test] + fn decode_small_empty_payload() { + let buf = make_small_packet(b"CHAN", &[]); + let msg = Lcm::decode_small(&buf).unwrap().unwrap(); + assert_eq!(msg.channel, "CHAN"); + assert!(msg.data.is_empty()); + } + + #[test] + fn decode_small_wrong_magic() { + let mut buf = make_small_packet(b"CHAN", &[1, 2, 3]); + BigEndian::write_u32(&mut buf[0..4], 0xDEADBEEF); + assert!(Lcm::decode_small(&buf).unwrap().is_none()); + } + + #[test] + fn decode_small_truncated() { + // Shorter than SHORT_HEADER_SIZE + let buf = vec![0x4C, 0x43, 0x30, 0x32, 0x00]; + assert!(Lcm::decode_small(&buf).unwrap().is_none()); + } + + #[test] + fn decode_small_missing_null_terminator() { + // Valid header but channel bytes have no null terminator + let mut buf = vec![0u8; SHORT_HEADER_SIZE + 4]; + BigEndian::write_u32(&mut buf[0..4], MAGIC_SHORT); + BigEndian::write_u32(&mut buf[4..8], 0); + buf[SHORT_HEADER_SIZE..SHORT_HEADER_SIZE + 4].copy_from_slice(b"CHAN"); + assert!(Lcm::decode_small(&buf).unwrap().is_none()); + } +} diff --git a/openspec/changes/replace-lcm-message-encoding/design.md b/openspec/changes/replace-lcm-message-encoding/design.md index 1516b356477..c2c6d003a36 100644 --- a/openspec/changes/replace-lcm-message-encoding/design.md +++ b/openspec/changes/replace-lcm-message-encoding/design.md @@ -55,7 +55,9 @@ bundled Jazzy .msg + local/installed .msg Use Fast CDR-backed generated C++ serialization and generated pybind11 bindings for Python. Python and C++ share the implementation rather than maintaining separate Python wire layouts. Rust uses generated native types with a Serde-compatible CDR backend. The generator also emits qualified type metadata and complete schema text for recording and introspection. -The implementation starting point is standalone `.msg` parsing, lowering to IDL for Fast-DDS-Gen without DDS type support, generated pybind11 bindings, and a Rust struct emitter plus `re_cdr`. These are candidates to validate, not a claim that a turnkey three-language generator exists. Stage 1 must pin working versions and document the exact build invocation, generated APIs, namespace handling, bounds/default behavior, and dependency footprint. A backend that cannot satisfy the contract must be replaced or the design revised before stage 1 is accepted; do not proceed with a knowingly temporary codec. +The implementation uses the pinned upstream `rosidl_adapter` parser, a shared normalized definition model, a C++ struct/Fast CDR customization emitter, generated pybind11 bindings, and a Rust struct emitter plus `re_cdr`. Fast CDR owns sizing, alignment, primitive representation, and containers; the emitter only supplies the declared fields, defaults, validation, and library calls. There is no second handwritten wire engine. + +The Fast-DDS-Gen 4.3.0 candidate was built successfully without ROS, but its IDL default annotation did not accept a ROS fixed-array default (`@default({1.0, 2.0})`). Using it would require additional default handling and a second schema transformation. Directly emitting the small native value types from the same normalized model preserves scalar and array defaults across all languages and removes Java/Gradle from the user build requirements. The currently validated dependencies are Fast CDR 2.4.0, pybind11 3.0.1, and `re_cdr` 0.1.0. The full 142-type build, independent-codec checks, Jazzy reference, bounds, and buffer tests now pass locally; CI repeats these gates. Packaging is stage 2. Use encapsulated plain CDR/XCDR1 with little-endian emission as the initial wire profile; decode the supported big- and little-endian representations according to the encapsulation header and reject unsupported representations. Check layout against ROS2 Jazzy serialization in CI. No LCM fingerprint or DimOS schema-hash prefix is part of the CDR payload. @@ -132,15 +134,40 @@ Stages 1–3 establish the new generation workflow in standalone examples before Rollback is source/release rollback as a unit; old and new processes or recordings are not promised interoperability. Retain demo artifacts as review evidence, not as a promise to decode the obsolete format. -## Open Questions +## Engineering gates -No outstanding product decisions require another user interview. The following engineering checks are mandatory stage-1 work and must be recorded here before later stages proceed: +No outstanding product decisions require another user interview. The stage-1 checks below are resolved by the implementation evidence that follows; CI repeats the executable checks: 1. Exact pinned parser, C++ generator/Fast CDR, pybind11, and Rust codec versions that pass the complete `.msg` and CDR conformance suite without ROS installed. 2. Measured Python buffer-copy and owner-lifetime behavior, with any unavoidable copies documented. 3. The license/provenance and build viability of extracting Rust's existing raw LCM transport, or the concrete maintained replacement if extraction is unsuitable. 4. The consumer inventory and any necessary subdivision of stage 4 into independently runnable PRs, each retaining the demo requirement. +## Implementation inventory and evidence + +The initial source inventory found 185 files under `dimos` with direct LCM-codec/generated-type references, 8 native SDK files, 2 native examples, and the browser SDK decoder. A broader scan finds 690 Python files importing `dimos.msgs`; this includes tests and indirect convenience-API users, so the direct codec count is not the size of the full cutover. + +| Consumer group | Required cutover | +| --- | --- | +| Message classes and helpers | Replace generated/wrapped types, dynamic lookup, timestamp inheritance, flattened poses, and rich geometry/image/cloud methods | +| Python transports and workers | CDR codec selection on LCM/Zenoh and typed SHM; worker serialization and explicit WebRTC type routing | +| C++ and Rust modules | Generated native types, codec adapters, transform streams, hardware/perception producers, and examples | +| Navigation/perception/robot code | Constructors, geometry operators, image/cloud conversion, timestamp access, detector messages, and standard primitive imports | +| Recorders and readers | Python and Rust MCAP/SQLite paths, image codecs, timestamps, transform collections, replay, and fixtures | +| Live viewers and browser | Rerun adapters, cockpit schema export, browser CDR decoder, relay codecs, and WebXR/phone/hosted teleoperation | + +Bundled upstream packages now cover builtin, standard, geometry, sensor, navigation, trajectory, visualization, shape, TF2, and vision definitions. Existing nonstandard messages also require in-tree definitions: JointCommand, RobotState, MotorCommandArray, ImuInfo, TrajectoryStatus, grasp candidates, bounding-box arrays, entity markers, and weighted line segments. Use a DimOS-owned schema namespace for nonstandard messages rather than redefining standard ROS types. Replace the current custom `TrajectoryPoint`/`JointTrajectory` layouts with the actual standard joint trajectory definitions and explicit time conversion at callers. The current line-segment decoder's overloaded Path/orientation representation requires an explicit generated line-segment message and matching native producer change. + +Keep stage 4 as a coordinated public type/caller cutover unless a dependency-closed working subdivision is proven. Separate helper extraction can precede the switch only if it has its own runnable demo and does not introduce compatibility methods on the generated classes. + +Initial executable evidence is the `examples/message-codegen` relay: sequence 40 and hops `[1]` enter C++, C++ adds hop 2, Rust adds hop 3, and Python receives sequence 42 with the nested reading/position/arrays intact. A generated PoseStamped also matched an independent Jazzy codec byte-for-byte. See the example README and `scripts/test_message_codegen.sh` for reproducible commands. Local stage-1 verification built 139 bundled types and three demo types, passed 22 Python tests plus nine Rust transport tests and its doctest, exercised all nine language combinations in both byte orders, and checked every generated type against the independent Jazzy codec. An isolated Jazzy container independently generated the demo types and decoded all three native implementations' payloads. ROS alignment padding can be unspecified, so ROS comparisons assert every decoded field; the rosbags oracle checks deterministic native bytes. Jazzy's Python generator emitted invalid code for an explicit empty sequence default, so the demo uses the equivalent implicit empty default; our parser still tests explicit empty defaults. + +The raw Rust LCM implementation is extracted into `native/rust/dimos-lcm-transport` from external revision `04d78e8622500244123ba9cefa4c51b4cb454549`, preserving its Apache-2.0 provenance. It has no generated-message dependency. The Python/native duplex demo verified 128-byte, 64 KiB, and fragmented 1 MiB payloads exactly; receive buffers are 4 MiB to accommodate the large burst. Integration into the native SDK remains stage 4. + +Primitive sequences and nested message fields are live. Nested sequence elements are returned by value and must be assigned back after edits, avoiding references invalidated by vector resizing. Numeric `.view()` returns read-only NumPy storage retaining the root owner; borrowed views block resizing or replacement of that owner's nested storage. `.copy()` explicitly produces independent writable storage. Local 30-iteration medians were 4.2/31.6/71.4/74.2 microseconds for borrowing/copying/encoding/decoding a 921,600-byte RGB image and 5.7/47.0/119.3/128.2 microseconds for a 1,200,000-byte cloud. These are local measurements, not portable performance promises. Lifetime, multiple-borrow, mutation rejection, fixed-array edits, and worker pickle behavior have regression tests. + +The generation entry point is `python -m dimos.message_codegen.generate`. It reads bundled/local sources only; setup downloads native dependencies separately. Generated sources stay under ignored `build/`. The host has no ROS installation, the generated Rust crate builds with Cargo's offline flag after setup, and `.github/workflows/message-codegen.yml` separates standalone builds from the independent ROS reference container. Release packaging and installed external providers remain stage 2. + ## Reference material These references informed exploration; pinned versions and executable conformance evidence, not current web documentation alone, determine acceptance. diff --git a/openspec/changes/replace-lcm-message-encoding/tasks.md b/openspec/changes/replace-lcm-message-encoding/tasks.md index 48c8814d28c..0c6e633286b 100644 --- a/openspec/changes/replace-lcm-message-encoding/tasks.md +++ b/openspec/changes/replace-lcm-message-encoding/tasks.md @@ -1,17 +1,17 @@ ## 1. PR 1 — Generate and exchange messages without ROS -- [ ] 1.1 Inventory message definitions and consumers across Python, C++, Rust, recordings, SHM, WebRTC/browser, live Rerun, and the existing ROS bridge; record required standard/custom types and any working subdivisions of the runtime cutover in design.md. -- [ ] 1.2 Inspect the external Rust raw LCM implementation and license; prove an extraction or maintained-replacement route with native/Python raw-byte and fragmented-payload checks, and record the choice before advancing the stack. -- [ ] 1.3 Pin and vendor the required Jazzy `.msg` dependency closure with immutable upstream revisions, licenses, and notices. -- [ ] 1.4 Implement standalone package resolution and parsing, including qualified names, transitive dependencies, defaults/bounds, conflict rejection, and source diagnostics for unsupported or invalid definitions. -- [ ] 1.5 Validate and pin the C++ generator/Fast CDR pipeline without ROS or DDS runtime requirements; generate buildable types and encapsulated XCDR1 codecs rather than handwritten message layouts. -- [ ] 1.6 Generate pybind11 bindings sharing the C++ codecs, with transport-neutral encode/decode, nested-field/sequence mutation semantics, and type/schema metadata. -- [ ] 1.7 Validate and pin the native Rust generation/CDR backend, emit equivalent types/metadata/codecs, and document any rejected candidates with evidence in design.md. -- [ ] 1.8 Implement and verify read-only image/point-cloud buffer views, explicit mutable copies, owner lifetimes, and rejection of storage-invalidating mutations while views exist; capture representative buffer performance and copying behavior. -- [ ] 1.9 Add all nine language encoder/decoder conformance combinations, endian/alignment cases, defaults, bounds, fixed/dynamic arrays, nested standard/custom messages, malformed inputs, and independent ROS2 Jazzy reference checks in a separate CI job. -- [ ] 1.10 Provide one documented generation entry point and an ignored output directory; demonstrate generation/build/runtime with ROS absent and preinstalled dependencies available offline. -- [ ] 1.11 Create the cumulative example definitions and a runnable `demo_` file relay: Python → C++ → Rust → Python, printing decoded fields and each process's edits; include realistic buffer-view behavior in its terminal demo. -- [ ] 1.12 Add exact demo setup/run/teardown instructions, capture visible output and automated results for PR review, and resolve the stage-1 engineering gates in design.md before accepting PR 1. +- [x] 1.1 Inventory message definitions and consumers across Python, C++, Rust, recordings, SHM, WebRTC/browser, live Rerun, and the existing ROS bridge; record required standard/custom types and any working subdivisions of the runtime cutover in design.md. +- [x] 1.2 Inspect the external Rust raw LCM implementation and license; prove an extraction or maintained-replacement route with native/Python raw-byte and fragmented-payload checks, and record the choice before advancing the stack. +- [x] 1.3 Pin and vendor the required Jazzy `.msg` dependency closure with immutable upstream revisions, licenses, and notices. +- [x] 1.4 Implement standalone package resolution and parsing, including qualified names, transitive dependencies, defaults/bounds, conflict rejection, and source diagnostics for unsupported or invalid definitions. +- [x] 1.5 Validate and pin the shared-definition C++ emitter/Fast CDR pipeline without ROS or DDS runtime requirements; generate buildable types and encapsulated XCDR1 codecs rather than handwritten message layouts. +- [x] 1.6 Generate pybind11 bindings sharing the C++ codecs, with transport-neutral encode/decode, nested-field/sequence mutation semantics, and type/schema metadata. +- [x] 1.7 Validate and pin the native Rust generation/CDR backend, emit equivalent types/metadata/codecs, and document any rejected candidates with evidence in design.md. +- [x] 1.8 Implement and verify read-only image/point-cloud buffer views, explicit mutable copies, owner lifetimes, and rejection of storage-invalidating mutations while views exist; capture representative buffer performance and copying behavior. +- [x] 1.9 Add all nine language encoder/decoder conformance combinations, endian/alignment cases, defaults, bounds, fixed/dynamic arrays, nested standard/custom messages, malformed inputs, and independent ROS2 Jazzy reference checks in a separate CI job. +- [x] 1.10 Provide one documented generation entry point and an ignored output directory; demonstrate generation/build/runtime with ROS absent and preinstalled dependencies available offline. +- [x] 1.11 Create the cumulative example definitions and a runnable `demo_` file relay: Python → C++ → Rust → Python, printing decoded fields and each process's edits; include realistic buffer-view behavior in its terminal demo. +- [x] 1.12 Add exact demo setup/run/teardown instructions, capture visible output and automated results for PR review, and resolve the stage-1 engineering gates in design.md before accepting PR 1. ## 2. PR 2 — Package and consume messages outside DimOS diff --git a/pyproject.toml b/pyproject.toml index 54022f56665..1e61e67ef9f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -568,6 +568,7 @@ explicit = true [tool.ruff] line-length = 100 +extend-exclude = ["dimos/message_codegen/_vendor"] exclude = [ ".git", ".pytest_cache", diff --git a/scripts/setup_message_codegen.sh b/scripts/setup_message_codegen.sh new file mode 100644 index 00000000000..afddb5fbc98 --- /dev/null +++ b/scripts/setup_message_codegen.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Install the pinned standalone CDR dependency into an ignored local prefix. +# This is a build-environment setup step, never part of message generation. +cd "$(dirname "$0")/.." +mkdir -p build/message-codegen +curl --fail --location --retry 3 \ + https://github.com/eProsima/Fast-CDR/archive/refs/tags/v2.4.0.tar.gz \ + -o build/message-codegen/fastcdr.tar.gz +echo '79d8466107dd6b7d1defe961c4aa31735038937cf9dd1175cf6b0da0df2209ab build/message-codegen/fastcdr.tar.gz' | sha256sum -c - +tar -xzf build/message-codegen/fastcdr.tar.gz -C build/message-codegen +cmake -S build/message-codegen/Fast-CDR-2.4.0 -B build/message-codegen/fastcdr-build \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$PWD/build/message-codegen/install" \ + -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON +cmake --build build/message-codegen/fastcdr-build -j 2 +cmake --install build/message-codegen/fastcdr-build diff --git a/scripts/test_message_codegen.sh b/scripts/test_message_codegen.sh new file mode 100644 index 00000000000..7adcb9b0194 --- /dev/null +++ b/scripts/test_message_codegen.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Run the same native builds, tests, and visible demos locally and in CI. +cd "$(dirname "$0")/.." +.venv/bin/python -m dimos.message_codegen.generate \ + --package-root examples/message-codegen --output build/message-codegen/demo +cmake -S build/message-codegen/demo/cpp -B build/message-codegen/demo/cpp/build \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$PWD/build/message-codegen/install" \ + -DPython_EXECUTABLE="$PWD/.venv/bin/python" +cmake --build build/message-codegen/demo/cpp/build -j 2 +c++ -std=c++17 -Ibuild/message-codegen/install/include -Ibuild/message-codegen/demo/cpp \ + examples/message-codegen/relay.cpp build/message-codegen/install/lib/libfastcdr.a \ + -o build/message-codegen/demo/cpp-relay +mkdir -p build/message-codegen/demo/rust/src/bin build/message-codegen/demo/evidence +cp examples/message-codegen/relay.rs build/message-codegen/demo/rust/src/bin/relay.rs +cargo build --manifest-path build/message-codegen/demo/rust/Cargo.toml +export PYTHONPATH="$PWD/build/message-codegen/demo/cpp/build${PYTHONPATH:+:$PYTHONPATH}" +.venv/bin/pytest dimos/message_codegen --noconftest -o addopts='' -q \ + | tee build/message-codegen/demo/evidence/pytest.txt +.venv/bin/python examples/message-codegen/demo_relay.py --build build/message-codegen/demo \ + | tee build/message-codegen/demo/evidence/relay.txt +.venv/bin/python examples/message-codegen/demo_conformance.py --build build/message-codegen/demo \ + | tee build/message-codegen/demo/evidence/conformance.txt +.venv/bin/python examples/message-codegen/demo_buffers.py \ + | tee build/message-codegen/demo/evidence/buffers.txt +cargo test -p dimos-lcm-transport +cargo build -p dimos-lcm-transport --example interop +.venv/bin/python examples/message-codegen/demo_transport.py --executable target/debug/examples/interop \ + | tee build/message-codegen/demo/evidence/transport.txt diff --git a/scripts/vendor_message_definitions.py b/scripts/vendor_message_definitions.py new file mode 100644 index 00000000000..18075544645 --- /dev/null +++ b/scripts/vendor_message_definitions.py @@ -0,0 +1,97 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Refresh the pinned, ROS-free schema and parser sources used by message codegen. + +Run with the checkout's development Python environment. This maintenance command +requires network access; generation and downstream applications never run it. +""" + +from __future__ import annotations + +import hashlib +import io +import json +from pathlib import Path +import tarfile + +import requests + +ROOT = Path(__file__).resolve().parents[1] / "dimos" / "message_codegen" +SOURCES = ( + ( + "ros2/common_interfaces", + "a941f14bb318d8d904505ed935ccbb97f24a70a4", + ( + "std_msgs", + "geometry_msgs", + "sensor_msgs", + "nav_msgs", + "trajectory_msgs", + "visualization_msgs", + "shape_msgs", + ), + ), + ("ros2/rcl_interfaces", "7aa3caf43377ea6ad615bc1040832e2c7566bfbe", ("builtin_interfaces",)), + ("ros2/geometry2", "f702874b1c8535d6a038230ab2cda0ba5d521ebd", ("tf2_msgs",)), + ("ros-perception/vision_msgs", "adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27", ("vision_msgs",)), + ("ros2/rosidl", "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", ("rosidl_adapter",)), + ("foxglove/schemas", "e86a94e9d4d259cdde71872f18336a7a055bf9ba", ("foxglove_msgs",)), +) + + +def main() -> None: + provenance: list[dict[str, object]] = [] + for repository, revision, packages in SOURCES: + url = f"https://codeload.github.com/{repository}/tar.gz/{revision}" + response = requests.get(url, timeout=90) + response.raise_for_status() + files: dict[str, str] = {} + with tarfile.open(fileobj=io.BytesIO(response.content), mode="r:gz") as archive: + for member in archive: + path = Path(*Path(member.name).parts[1:]) + if ( + repository == "foxglove/schemas" + and path.as_posix() == "schemas/ros2/CompressedVideo.msg" + ): + path = Path("foxglove_msgs/msg/CompressedVideo.msg") + if not member.isfile() or not path.parts: + continue + if len(path.parts) == 1 and path.name in {"LICENSE", "LICENSE.txt", "NOTICE"}: + target = ROOT / "schemas" / "licenses" / repository.replace("/", "_") / path + elif path.parts[0] not in packages: + continue + elif path.as_posix() == "rosidl_adapter/rosidl_adapter/parser.py": + target = ROOT / "_vendor" / "rosidl_parser.py" + elif path.name in {"LICENSE", "LICENSE.txt", "NOTICE", "package.xml"} or ( + len(path.parts) == 3 and path.parts[1] == "msg" and path.suffix == ".msg" + ): + target = ROOT / "schemas" / path + else: + continue + source = archive.extractfile(member) + assert source is not None + content = source.read() + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(content) + files[str(target.relative_to(ROOT))] = hashlib.sha256(content).hexdigest() + provenance.append( + {"repository": repository, "revision": revision, "files": dict(sorted(files.items()))} + ) + print(f"{repository}@{revision}: {len(files)} files") + (ROOT / "sources.json").write_text(json.dumps(provenance, indent=2) + "\n") + + +if __name__ == "__main__": + main() From d742ade369a9eddf45cadfe2dd2fec598070d148 Mon Sep 17 00:00:00 2001 From: cc Date: Mon, 21 Sep 2026 10:07:57 -0700 Subject: [PATCH 03/55] fix: bound schema validation and local demo socket --- dimos/message_codegen/README.md | 4 +++- .../message_codegen/_vendor/rosidl_parser.py | 3 ++- dimos/message_codegen/sources.json | 23 ++++++++++++++----- dimos/message_codegen/test_definitions.py | 15 ++++++++++++ examples/message-codegen/demo_transport.py | 2 +- scripts/vendor_message_definitions.py | 22 +++++++++++++++++- 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/dimos/message_codegen/README.md b/dimos/message_codegen/README.md index 36d85ec18fe..447d5f58602 100644 --- a/dimos/message_codegen/README.md +++ b/dimos/message_codegen/README.md @@ -35,7 +35,9 @@ files. `schemas/*/package.xml` retains upstream authorship and declared licenses `schemas/licenses/` contains upstream license texts, including the Apache 2.0 license shared by the standard interface packages and parser. The parser's original copyright header is preserved. `rosidl_parser.pyi` is DimOS's type stub; -the upstream implementation remains unmodified. +the upstream implementation has one documented patch replacing an ambiguous +constant-name regex with its linear-time equivalent. `sources.json` records both +the original and patched hashes; the maintenance script reapplies the patch. To refresh the pinned inputs intentionally, edit the revisions in `scripts/vendor_message_definitions.py`, then run that maintenance command with diff --git a/dimos/message_codegen/_vendor/rosidl_parser.py b/dimos/message_codegen/_vendor/rosidl_parser.py index 836a3b7519f..cdf64bc3ae6 100644 --- a/dimos/message_codegen/_vendor/rosidl_parser.py +++ b/dimos/message_codegen/_vendor/rosidl_parser.py @@ -72,7 +72,8 @@ VALID_MESSAGE_NAME_PATTERN = re.compile('^[A-Z][A-Za-z0-9]*$') # relaxed patterns used for compatibility with ROS 1 messages # VALID_MESSAGE_NAME_PATTERN = re.compile('^[A-Za-z][A-Za-z0-9]*$') -VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z]([A-Z0-9_]?[A-Z0-9]+)*$') +# DimOS patch: equivalent linear-time pattern; avoid nested ambiguous repetition. +VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z](?:[A-Z0-9]|_[A-Z0-9])*$') class InvalidSpecification(Exception): diff --git a/dimos/message_codegen/sources.json b/dimos/message_codegen/sources.json index 53344c33b83..cf507a378e4 100644 --- a/dimos/message_codegen/sources.json +++ b/dimos/message_codegen/sources.json @@ -135,7 +135,8 @@ "schemas/visualization_msgs/msg/MeshFile.msg": "6c5393590d3765a6da1bc815f0dba8962b55efad40ab4fb1346673cf89c294ed", "schemas/visualization_msgs/msg/UVCoordinate.msg": "544f2580cfb42e1e28dcb27856572abd52ad348d8f6197526f51f6d15acec1f0", "schemas/visualization_msgs/package.xml": "19ed838dc5a99735e2dd9b45e308d1227f6ba7c411ce3675cca480620993750d" - } + }, + "patches": {} }, { "repository": "ros2/rcl_interfaces", @@ -145,7 +146,8 @@ "schemas/builtin_interfaces/msg/Time.msg": "dc5a01ddde3aecffee21eb24974fe77cc969f873218a2b1811aa0ac8a456b8bd", "schemas/builtin_interfaces/package.xml": "0f709bdbc4742e9040e788adcc2df710542d9a095080cbcda2dcb4174461de51", "schemas/licenses/ros2_rcl_interfaces/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" - } + }, + "patches": {} }, { "repository": "ros2/geometry2", @@ -155,7 +157,8 @@ "schemas/tf2_msgs/msg/TF2Error.msg": "f1f3603b877ed51a5a28b264257e9bc37312e32a767838f52310d07027d819ab", "schemas/tf2_msgs/msg/TFMessage.msg": "f3fca610a59b31ee4c7b740522ecdd0fd8c76002170088111409e4df513f1dfc", "schemas/tf2_msgs/package.xml": "ac78cb0ff503bc07b20358bbe7bcb7475db7b6f0d87d2a84e321b92755bfb14e" - } + }, + "patches": {} }, { "repository": "ros-perception/vision_msgs", @@ -179,15 +182,22 @@ "schemas/vision_msgs/msg/VisionClass.msg": "ae82ce087350e3ee1c0f0f8bb8f6e6c2e08f94dea6d984dec579fd72663bdb72", "schemas/vision_msgs/msg/VisionInfo.msg": "5a47776dfea36e48958dbde43ab55e9cb94fb337b0f68b4fcc444807f333b23d", "schemas/vision_msgs/package.xml": "b69e5eb38183cbcf2cf0b729a21ea6217eb76a48bd0613c00539a598a5f35872" - } + }, + "patches": {} }, { "repository": "ros2/rosidl", "revision": "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", "files": { - "_vendor/rosidl_parser.py": "ce1f7d84ab0ad8300e77917061b74dbe701d33f3fd12de5ba6b75374c8f9970e", + "_vendor/rosidl_parser.py": "4ca3bc4ecbfca7f48a07f1d9630bfb5d006f55857e75a3d3207380386431572e", "schemas/licenses/ros2_rosidl/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", "schemas/rosidl_adapter/package.xml": "653c797d2b4e2f5e6ad7b18812632bf6bf55aa924dfbca0405439389a5273989" + }, + "patches": { + "_vendor/rosidl_parser.py": { + "upstream_sha256": "ce1f7d84ab0ad8300e77917061b74dbe701d33f3fd12de5ba6b75374c8f9970e", + "description": "Equivalent linear-time constant-name validation regex" + } } }, { @@ -196,6 +206,7 @@ "files": { "schemas/foxglove_msgs/msg/CompressedVideo.msg": "83d044efaefc90291cdd56cd36b2ef6b190748c1df860d1eca7df77328174324", "schemas/licenses/foxglove_schemas/LICENSE": "da11235665c17d4c1634072dae92b8ba1b38d6fdde2ccf19a6bbede33253f58d" - } + }, + "patches": {} } ] diff --git a/dimos/message_codegen/test_definitions.py b/dimos/message_codegen/test_definitions.py index 5d8aaad0eb2..135b279e727 100644 --- a/dimos/message_codegen/test_definitions.py +++ b/dimos/message_codegen/test_definitions.py @@ -83,6 +83,21 @@ def test_explicit_empty_sequence_default(tmp_path): assert message.fields[0].default == () +@pytest.mark.parametrize("name", ["A", "A0", "A_B2_C"]) +def test_constant_name_validation_accepts_ros_names(tmp_path, name): + path = write_message(tmp_path, "example_msgs/msg/Value", f"uint8 {name}=1\n") + + assert parse_message(path).constants[0].name == name + + +@pytest.mark.parametrize("name", ["A_", "A__B", "a", "A" + "0" * 10000 + "!"]) +def test_constant_name_validation_rejects_invalid_names(tmp_path, name): + path = write_message(tmp_path, "example_msgs/msg/Value", f"uint8 {name}=1\n") + + with pytest.raises(ValueError): + parse_message(path) + + def test_equivalent_definitions_ignore_comments(tmp_path): write_message(tmp_path / "one", "example_msgs/msg/Value", "int32 value # comment\n") write_message(tmp_path / "two", "example_msgs/msg/Value", "# another comment\nint32 value\n") diff --git a/examples/message-codegen/demo_transport.py b/examples/message-codegen/demo_transport.py index b018697efcf..2d03ecf4708 100644 --- a/examples/message-codegen/demo_transport.py +++ b/examples/message-codegen/demo_transport.py @@ -29,7 +29,7 @@ def main() -> None: parser.add_argument("--executable", type=Path, required=True) args = parser.parse_args() with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as port_socket: - port_socket.bind(("", 0)) + port_socket.bind(("127.0.0.1", 0)) port = port_socket.getsockname()[1] transport = lcm.LCM(f"udpm://239.255.76.67:{port}?ttl=0&recv_buf_size=4194304") received: list[bytes] = [] diff --git a/scripts/vendor_message_definitions.py b/scripts/vendor_message_definitions.py index 18075544645..8326d8d864f 100644 --- a/scripts/vendor_message_definitions.py +++ b/scripts/vendor_message_definitions.py @@ -58,6 +58,7 @@ def main() -> None: response = requests.get(url, timeout=90) response.raise_for_status() files: dict[str, str] = {} + patches: dict[str, dict[str, str]] = {} with tarfile.open(fileobj=io.BytesIO(response.content), mode="r:gz") as archive: for member in archive: path = Path(*Path(member.name).parts[1:]) @@ -83,11 +84,30 @@ def main() -> None: source = archive.extractfile(member) assert source is not None content = source.read() + if target == ROOT / "_vendor" / "rosidl_parser.py": + original = ( + b"VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z]([A-Z0-9_]?[A-Z0-9]+)*$')" + ) + replacement = ( + b"# DimOS patch: equivalent linear-time pattern; avoid nested ambiguous repetition.\n" + b"VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z](?:[A-Z0-9]|_[A-Z0-9])*$')" + ) + assert content.count(original) == 1, "Recheck parser patch against upstream" + patches[str(target.relative_to(ROOT))] = { + "upstream_sha256": hashlib.sha256(content).hexdigest(), + "description": "Equivalent linear-time constant-name validation regex", + } + content = content.replace(original, replacement) target.parent.mkdir(parents=True, exist_ok=True) target.write_bytes(content) files[str(target.relative_to(ROOT))] = hashlib.sha256(content).hexdigest() provenance.append( - {"repository": repository, "revision": revision, "files": dict(sorted(files.items()))} + { + "repository": repository, + "revision": revision, + "files": dict(sorted(files.items())), + "patches": patches, + } ) print(f"{repository}@{revision}: {len(files)} files") (ROOT / "sources.json").write_text(json.dumps(provenance, indent=2) + "\n") From f0e9e5a4f2937cd36498a9f6d83df3c63fceb8b6 Mon Sep 17 00:00:00 2001 From: cc Date: Mon, 21 Sep 2026 10:17:47 -0700 Subject: [PATCH 04/55] fix: include raw LCM crate in recorder Nix sources --- dimos/experimental/memory/rust/flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/dimos/experimental/memory/rust/flake.nix b/dimos/experimental/memory/rust/flake.nix index 368ebe32b3c..83a8badd620 100644 --- a/dimos/experimental/memory/rust/flake.nix +++ b/dimos/experimental/memory/rust/flake.nix @@ -31,6 +31,7 @@ ../../../../Cargo.toml ../../../../dimos/experimental/memory/rust ../../../../native/rust/dimos-module + ../../../../native/rust/dimos-lcm-transport ../../../../native/rust/dimos-module-macros ../../../../dimos/mapping/ray_tracing/rust ../../../../dimos/mapping/ray_tracing/rust/py From bbba64ac584b4ddaf1c2b6a3a02b86c14b67286d Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 1 Oct 2026 01:18:43 -0700 Subject: [PATCH 05/55] fix: prepare generator-layer test dependencies and namespace imports --- dimos/message_codegen/__init__.py | 0 dimos/message_codegen/_vendor/__init__.py | 0 dimos/message_codegen/_vendor/rosidl_parser.py | 2 +- scripts/test_message_codegen.sh | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 dimos/message_codegen/__init__.py delete mode 100644 dimos/message_codegen/_vendor/__init__.py diff --git a/dimos/message_codegen/__init__.py b/dimos/message_codegen/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/dimos/message_codegen/_vendor/__init__.py b/dimos/message_codegen/_vendor/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/dimos/message_codegen/_vendor/rosidl_parser.py b/dimos/message_codegen/_vendor/rosidl_parser.py index cdf64bc3ae6..2063a08b75a 100644 --- a/dimos/message_codegen/_vendor/rosidl_parser.py +++ b/dimos/message_codegen/_vendor/rosidl_parser.py @@ -907,7 +907,7 @@ def parse_action_string(pkg_name, action_name, action_string): pkg_name, action_name + ACTION_RESULT_SUFFIX, result_string) feedback_message = parse_message_string( pkg_name, action_name + ACTION_FEEDBACK_SUFFIX, feedback_string) - # --------------------------------------------------------------------------------------------- + # Parse action definitions. return ActionSpecification( pkg_name, action_name, goal_message, result_message, feedback_message) diff --git a/scripts/test_message_codegen.sh b/scripts/test_message_codegen.sh index 7adcb9b0194..d8d312c287e 100644 --- a/scripts/test_message_codegen.sh +++ b/scripts/test_message_codegen.sh @@ -16,7 +16,7 @@ mkdir -p build/message-codegen/demo/rust/src/bin build/message-codegen/demo/evid cp examples/message-codegen/relay.rs build/message-codegen/demo/rust/src/bin/relay.rs cargo build --manifest-path build/message-codegen/demo/rust/Cargo.toml export PYTHONPATH="$PWD/build/message-codegen/demo/cpp/build${PYTHONPATH:+:$PYTHONPATH}" -.venv/bin/pytest dimos/message_codegen --noconftest -o addopts='' -q \ +.venv/bin/python -m pytest dimos/message_codegen --noconftest -o addopts='' -q \ | tee build/message-codegen/demo/evidence/pytest.txt .venv/bin/python examples/message-codegen/demo_relay.py --build build/message-codegen/demo \ | tee build/message-codegen/demo/evidence/relay.txt From 4749cc9162b3e4f42b65e91c7e44ebc5957f4b01 Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 1 Oct 2026 12:16:44 -0700 Subject: [PATCH 06/55] refactor: generate Python message source without native extensions --- .github/workflows/message-codegen.yml | 2 +- dimos/message_codegen/README.md | 3 +- dimos/message_codegen/generate.py | 22 +- dimos/message_codegen/python.py | 216 +++++----- .../templates/dimos_python.hpp | 151 ------- dimos/message_codegen/templates/runtime.py | 398 ++++++++++++++++++ dimos/message_codegen/test_python_source.py | 60 +++ examples/message-codegen/README.md | 23 +- examples/message-codegen/demo_buffers.py | 9 + .../replace-lcm-message-encoding/design.md | 14 +- .../replace-lcm-message-encoding/proposal.md | 2 +- .../replace-lcm-message-encoding/tasks.md | 2 +- scripts/test_message_codegen.sh | 8 +- 13 files changed, 620 insertions(+), 290 deletions(-) delete mode 100644 dimos/message_codegen/templates/dimos_python.hpp create mode 100644 dimos/message_codegen/templates/runtime.py create mode 100644 dimos/message_codegen/test_python_source.py diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml index 59085c86b28..05803620f28 100644 --- a/.github/workflows/message-codegen.yml +++ b/.github/workflows/message-codegen.yml @@ -28,7 +28,7 @@ jobs: run: | test ! -d /opt/ros uv venv .venv --python 3.12 - uv pip install --python .venv/bin/python pybind11==3.0.1 rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env lcm-dimos-fork + uv pip install --python .venv/bin/python rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env lcm-dimos-fork .venv/bin/python -c "import importlib.util; assert importlib.util.find_spec('rclpy') is None" - name: Build the pinned standalone CDR library run: bash scripts/setup_message_codegen.sh diff --git a/dimos/message_codegen/README.md b/dimos/message_codegen/README.md index 447d5f58602..17915a0160b 100644 --- a/dimos/message_codegen/README.md +++ b/dimos/message_codegen/README.md @@ -17,7 +17,8 @@ before output is written. Repeat `--package-root` and `--type` for multiple inpu omitting `--type` generates all available definitions. The output belongs in an ignored build directory. Generation never downloads dependencies. -Python and C++ use Fast CDR 2.4.0; Python bindings use pybind11 3.0.1. Rust uses +Python emits plain source values and uses rosbags 0.11.0 for CDR; C++ uses +Fast CDR 2.4.0. Python message use requires no native message compilation. Rust uses `re_cdr` 0.1.0 and `serde-big-array` 0.5.1. The current generator explicitly rejects `wstring` because the selected Rust backend has no matching wide-string Serde representation. No bundled definition uses it. Service/action generation is out diff --git a/dimos/message_codegen/generate.py b/dimos/message_codegen/generate.py index 6ee47e1443a..aa61e8e96c6 100644 --- a/dimos/message_codegen/generate.py +++ b/dimos/message_codegen/generate.py @@ -48,21 +48,21 @@ def generate( native.mkdir(exist_ok=True) (native / "messages.hpp").write_text(cpp.generate(messages)) shutil.copyfile(TEMPLATES / "dimos_cdr.hpp", native / "dimos_cdr.hpp") - shutil.copyfile(TEMPLATES / "dimos_python.hpp", native / "dimos_python.hpp") - bindings = python.generate(messages, definitions, module) - for name, content in bindings.items(): - (native / name).write_text(content) - sources = " ".join(sorted(bindings)) + package = output / "python" / module + if package.exists(): + shutil.rmtree(package) + for name, content in python.generate(messages, definitions, module).items(): + path = package / name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content) (native / "CMakeLists.txt").write_text( "cmake_minimum_required(VERSION 3.20)\n" "project(dimos_generated_messages LANGUAGES CXX)\n" "find_package(fastcdr 2.4.0 EXACT REQUIRED)\n" - "find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)\n" - 'execute_process(COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir OUTPUT_VARIABLE pybind11_DIR OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)\n' - "find_package(pybind11 3.0.1 EXACT REQUIRED)\n" - f"pybind11_add_module({module} NO_EXTRAS {sources})\n" - f"target_compile_features({module} PRIVATE cxx_std_17)\n" - f"target_link_libraries({module} PRIVATE fastcdr)\n" + f"add_library({module}_messages INTERFACE)\n" + f"target_compile_features({module}_messages INTERFACE cxx_std_17)\n" + f"target_include_directories({module}_messages INTERFACE ${{CMAKE_CURRENT_SOURCE_DIR}})\n" + f"target_link_libraries({module}_messages INTERFACE fastcdr)\n" ) crate = output / "rust" (crate / "src").mkdir(parents=True, exist_ok=True) diff --git a/dimos/message_codegen/python.py b/dimos/message_codegen/python.py index 4a653aa64e3..63f89cd893f 100644 --- a/dimos/message_codegen/python.py +++ b/dimos/message_codegen/python.py @@ -12,119 +12,135 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Generate Python bindings to the same native types/codecs used by C++.""" +"""Generate ordinary Python source values using the shared pure-Python CDR runtime.""" from __future__ import annotations -import json +from pathlib import Path +from typing import Any -from dimos.message_codegen import cpp from dimos.message_codegen.definitions import Definitions, Message +ABI = "dimos-cdr-source-rosbags-0.11.0-v1" -def string_literal(value: str) -> str: - delimiter = "msg" - while f'){delimiter}"' in value: - delimiter += "_" - return f'R"{delimiter}({value}){delimiter}"' + +def literal(value: Any) -> str: + if isinstance(value, float) and not (-float("inf") < value < float("inf")): + return f"float({str(value)!r})" + if isinstance(value, (list, tuple)): + return "[" + ", ".join(literal(item) for item in value) + "]" + return repr(value) def generate( - messages: tuple[Message, ...], definitions: Definitions, module: str + messages: tuple[Message, ...], + definitions: Definitions, + module: str, + *, + imports: tuple[str, ...] = (), + shared: bool = False, + version: str = "0.1.0", + imported: dict[str, str] | None = None, + dependency_versions: dict[str, str] | None = None, ) -> dict[str, str]: - sources: dict[str, str] = {} - containers = sorted( - { - cpp.type_name(field.type) - for message in messages - for field in message.fields - if field.type.is_array - } - ) - container_names = {native: f"_Sequence{index}" for index, native in enumerate(containers)} - functions = [] - for offset in range(0, len(messages), 10): - function = f"bind_{offset // 10}" - functions.append(function) - lines = [ - "// Generated from ROS2 .msg definitions. Do not edit.", - "#include ", - "#include ", - '#include "messages.hpp"', - '#include "dimos_python.hpp"', - "namespace py = pybind11;", - f"void {function}(py::module_& root) {{", - ] - for message in messages[offset : offset + 10]: - native = cpp.qualified(message.name) - lines.extend( - [ - "{", - f'auto package = py::hasattr(root, "{message.package}") ? root.attr("{message.package}").cast() : root.def_submodule("{message.package}");', - 'auto module = py::hasattr(package, "msg") ? package.attr("msg").cast() : package.def_submodule("msg");', - f'auto cls = py::class_<{native}>(module, "{message.short_name}", py::dynamic_attr(), py::module_local());', - f"cls.def(py::init([](py::kwargs kwargs) {{ {native} value{{}};", - "for (auto item : kwargs) { auto key = py::cast(item.first);", - ] + """Emit importable packages; dependency messages retain their canonical class identity.""" + imported = imported or {} + lines = [ + "# Generated from ROS2 .msg definitions. Do not edit.", + "from __future__ import annotations", + "from ._runtime import Codec, Message, Sequence", + ] + lines.extend(f"import {name}" for name in imports) + for dependency, expected in sorted((dependency_versions or {}).items()): + lines.extend( + [ + f"if {dependency}.__dimos_version__ != {expected!r} or {dependency}.__dimos_abi__ != {ABI!r}:", + f" raise ImportError('Incompatible message dependency: {dependency}')", + ] + ) + for name, owner in sorted(imported.items()): + symbol = name.replace("/", "__") + lines.append(f"{symbol} = {owner}.{name.replace('/', '.')}") + lines.extend( + [ + f"if {symbol}.schema != {definitions.schema(name)!r}:", + f" raise ImportError('Dependency schema mismatch: {name}')", + ] + ) + for message in messages: + symbol = message.name.replace("/", "__") + lines.extend( + [ + f"class {symbol}(Message):", + f" msg_name = {message.name!r}", + f" schema = {definitions.schema(message.name)!r}", + " _fields = (", + ] + ) + for field in message.fields: + kind = field.type + spec = ( + field.name, + kind.name, + kind.is_array, + kind.array_size, + kind.array_bounded, + kind.string_bound, + field.default, ) - for index, field in enumerate(message.fields): - condition = "if" if index == 0 else "else if" - cast = "dimos::python::sequence_from_python" if field.type.is_array else "py::cast" - lines.append( - f'{condition} (key == "{field.name}") value.{cpp.identifier(field.name)} = {cast}<{cpp.type_name(field.type)}>(item.second);' - ) - fallback = "else " if message.fields else "" - lines.append(f'{fallback}throw py::type_error("Unknown message field: " + key);') - lines.extend(["}", "value.validate(); return value; }));"]) - for field in message.fields: - field_native = cpp.type_name(field.type) - member = f"self.cast<{native}&>().{cpp.identifier(field.name)}" - if field.type.is_array: - lines.extend( - [ - f'dimos::python::bind_sequence<{field_native}>(root, "{container_names[field_native]}");', - f'cls.def_property("{field.name}", [](py::object self) {{ return dimos::python::Sequence<{field_native}>{{ &{member}, dimos::python::owner_root(self) }}; }},', - f"[](py::object self, py::handle input) {{ dimos::python::require_unborrowed(self); {member} = dimos::python::sequence_from_python<{field_native}>(input); }});", - ] - ) - elif field.type.nested: - lines.extend( - [ - f'cls.def_property("{field.name}", [](py::object self) {{ auto child = py::cast(&{member}, py::return_value_policy::reference_internal, self); child.attr("__dimos_owner") = dimos::python::owner_root(self); return child; }},', - f"[](py::object self, const {field_native}& input) {{ dimos::python::require_unborrowed(self); {member} = input; }});", - ] - ) - else: - lines.append( - f'cls.def_readwrite("{field.name}", &{native}::{cpp.identifier(field.name)});' - ) - for constant in message.constants: - lines.append( - f'cls.attr("{constant.name}") = py::cast({native}::{cpp.identifier(constant.name)});' - ) - lines.extend( - [ - f'cls.def("encode", [](const {native}& value, bool little_endian) {{ auto bytes = dimos::cdr::encode(value, little_endian); return py::bytes(reinterpret_cast(bytes.data()), bytes.size()); }}, py::arg("little_endian") = true);', - f'cls.def_static("decode", [](py::bytes input) {{ std::string bytes = input; return dimos::cdr::decode<{native}>(reinterpret_cast(bytes.data()), bytes.size()); }});', - f"cls.def(py::pickle([](const {native}& value) {{ auto bytes = dimos::cdr::encode(value); return py::bytes(reinterpret_cast(bytes.data()), bytes.size()); }}, [](py::bytes input) {{ std::string bytes = input; return dimos::cdr::decode<{native}>(reinterpret_cast(bytes.data()), bytes.size()); }}));", - f'cls.attr("msg_name") = {json.dumps(message.name)};', - f'cls.attr("schema") = {string_literal(definitions.schema(message.name))};', - "}", - ] + lines.append(" (" + ", ".join(literal(item) for item in spec) + "),") + lines.append(" )") + for field in message.fields: + kind = field.type + annotation = ( + "Sequence" + if kind.is_array + else kind.name.replace("/", "__") + if kind.nested + else "str" + if kind.name == "string" + else "bool" + if kind.name == "bool" + else "float" + if kind.name.startswith("float") + else "int" ) - lines.append("}") - sources[function + ".cpp"] = "\n".join(lines) + "\n" - sources["bindings.cpp"] = ( - "\n".join( + lines.append(f" {field.name}: {annotation}") + for constant in message.constants: + lines.append(f" {constant.name} = {literal(constant.value)}") + lines.append("") + names = [message.name for message in messages] + list(imported) + lines.append( + "_types = {" + ", ".join(f"{name!r}: {name.replace('/', '__')}" for name in names) + "}" + ) + lines.append( + "_codec = Codec({" + + ", ".join(f"{name!r}: {definitions.schema(name)!r}" for name in names) + + "}, _types)" + ) + for message in messages: + symbol = message.name.replace("/", "__") + lines.extend( [ - "// Generated from ROS2 .msg definitions. Do not edit.", - "#include ", - *(f"void {function}(pybind11::module_&);" for function in functions), - f"PYBIND11_MODULE({module}, root) {{", - *(f"{function}(root);" for function in functions), - "}", + f"{symbol}._codec = _codec", + f"{symbol}.__name__ = {message.short_name!r}", + f"{symbol}.__qualname__ = {message.short_name!r}", + f"{symbol}.__module__ = {module + '.' + message.package + '.msg'!r}", ] ) - + "\n" - ) - return sources + packages = sorted({message.package for message in messages}) + result = { + "_types.py": "\n".join(lines) + "\n", + "_runtime.py": Path(__file__).with_name("templates").joinpath("runtime.py").read_text(), + "__init__.py": f"__dimos_version__ = {version!r}\n__dimos_abi__ = {ABI!r}\n" + + "".join(f"from . import {package}\n" for package in packages), + "py.typed": "", + } + for package in packages: + result[f"{package}/__init__.py"] = "from . import msg\n" + result[f"{package}/msg/__init__.py"] = "".join( + f"from ..._types import {message.name.replace('/', '__')} as {message.short_name}\n" + for message in messages + if message.package == package + ) + return result diff --git a/dimos/message_codegen/templates/dimos_python.hpp b/dimos/message_codegen/templates/dimos_python.hpp deleted file mode 100644 index 8772cc3696a..00000000000 --- a/dimos/message_codegen/templates/dimos_python.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2026 Dimensional Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace dimos::python { -namespace py = pybind11; - -struct BorrowState { - size_t count = 0; -}; - -inline py::object owner_root(py::object owner) { - return py::hasattr(owner, "__dimos_owner") ? owner.attr("__dimos_owner") : owner; -} - -inline std::shared_ptr borrow_state(py::object owner) { - owner = owner_root(owner); - if (!py::hasattr(owner, "__dimos_buffers")) { - owner.attr("__dimos_buffers") = py::capsule( - new std::shared_ptr(std::make_shared()), - [](void* value) { delete static_cast*>(value); }); - } - auto capsule = owner.attr("__dimos_buffers").cast(); - return *static_cast*>(capsule.get_pointer()); -} - -inline void require_unborrowed(py::object owner) { - if (borrow_state(owner)->count != 0) { - throw py::buffer_error("Cannot replace or resize message storage while a NumPy view is borrowed"); - } -} - -struct Borrow { - py::object owner; - std::shared_ptr state; - - explicit Borrow(py::object value) : owner(owner_root(value)), state(borrow_state(owner)) { - ++state->count; - } - ~Borrow() { --state->count; } -}; - -template -struct Sequence { - Container* values; - py::object owner; -}; - -template -Container sequence_from_python(py::handle value) { - using T = typename Container::value_type; - if constexpr (std::is_arithmetic_v && !std::is_same_v) { - if (PyObject_CheckBuffer(value.ptr())) { - auto info = py::reinterpret_borrow(value).request(); - if (info.ndim == 1 && info.itemsize == sizeof(T) && - info.format == py::format_descriptor::format() && info.strides[0] == sizeof(T)) { - const auto* first = static_cast(info.ptr); - if constexpr (std::is_same_v>) { - return Container(first, first + info.size); - } else { - Container result{}; - if (static_cast(info.size) != result.size()) { - throw py::value_error("Incorrect fixed-array length"); - } - std::copy(first, first + info.size, result.begin()); - return result; - } - } - } - } - return py::cast(value); -} - -template -void bind_sequence(py::module_& module, const char* name) { - if (py::hasattr(module, name)) return; - using T = typename Container::value_type; - using View = Sequence; - auto cls = py::class_(module, name, py::module_local()); - cls.def("__len__", [](const View& self) { return self.values->size(); }); - cls.def("__getitem__", [](const View& self, py::ssize_t index) { - if (index < 0) index += self.values->size(); - if (index < 0 || static_cast(index) >= self.values->size()) throw py::index_error(); - // Message elements are values. Assign an edited element back explicitly; - // a vector resize must never leave a Python object pointing into it. - return T((*self.values)[index]); - }); - cls.def("__setitem__", [](View& self, py::ssize_t index, const T& value) { - if (index < 0) index += self.values->size(); - if (index < 0 || static_cast(index) >= self.values->size()) throw py::index_error(); - (*self.values)[index] = value; - }); - cls.def("__iter__", [](const View& self) { - return py::iter(py::cast(Container(*self.values))); - }); - cls.def("__repr__", [](const View& self) { return py::repr(py::cast(*self.values)); }); - cls.def("__eq__", [](const View& self, py::object other) { - if (!PySequence_Check(other.ptr())) return false; - return py::cast(*self.values).equal(py::list(other)); - }); - if constexpr (std::is_same_v>) { - cls.def("append", [](View& self, const T& value) { - require_unborrowed(self.owner); - self.values->push_back(value); - }); - cls.def("extend", [](View& self, py::iterable values) { - require_unborrowed(self.owner); - auto extra = sequence_from_python(values); - self.values->insert(self.values->end(), extra.begin(), extra.end()); - }); - cls.def("clear", [](View& self) { - require_unborrowed(self.owner); - self.values->clear(); - }); - } - if constexpr (std::is_arithmetic_v && !std::is_same_v) { - cls.def("view", [](const View& self) { - py::capsule owner(new Borrow(self.owner), [](void* value) { delete static_cast(value); }); - py::array result(py::dtype::of(), {self.values->size()}, {sizeof(T)}, self.values->data(), owner); - result.attr("setflags")(py::arg("write") = false); - return result; - }); - cls.def("copy", [](const View& self) { - py::array_t result(self.values->size()); - std::copy(self.values->begin(), self.values->end(), result.mutable_data()); - return result; - }); - } -} - -} // namespace dimos::python diff --git a/dimos/message_codegen/templates/runtime.py b/dimos/message_codegen/templates/runtime.py new file mode 100644 index 00000000000..8745fb6b67b --- /dev/null +++ b/dimos/message_codegen/templates/runtime.py @@ -0,0 +1,398 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Shared pure-Python value/buffer contracts; CDR encoding is supplied by rosbags.""" + +from __future__ import annotations + +import copy +import struct +from typing import Any, ClassVar, cast +import weakref + +import numpy as np +from rosbags.typesys import Stores, get_types_from_msg, get_typestore + +_DTYPES = { + "bool": "bool", + "byte": "uint8", + "char": "uint8", + "int8": "int8", + "uint8": "uint8", + "int16": "int16", + "uint16": "uint16", + "int32": "int32", + "uint32": "uint32", + "int64": "int64", + "uint64": "uint64", + "float32": "float32", + "float64": "float64", +} +# name, scalar type, array, size/bound, bounded sequence, string bound, default +Field = tuple[str, str, bool, int | None, bool, int | None, Any] + + +def _scalar(kind: str, value: Any, codec: Codec, bound: int | None = None) -> Any: + if "/" in kind: + expected = codec.types[kind] + if not isinstance(value, expected): + raise TypeError(f"Expected {kind}, got {type(value).__name__}") + return copy.deepcopy(value) + if kind == "string": + if not isinstance(value, str): + raise TypeError("Expected string") + if bound is not None and len(value.encode()) > bound: + raise ValueError("String exceeds string bound") + return value + if kind == "bool": + if not isinstance(value, (bool, np.bool_)): + raise TypeError("Expected bool") + return bool(value) + if kind.startswith("float"): + if not isinstance(value, (int, float, np.number)): + raise TypeError(f"Expected {kind}") + return float(np.asarray(value, dtype=_DTYPES[kind])) + if not isinstance(value, (int, np.integer)): + raise TypeError(f"Expected {kind}") + limits = np.iinfo(_DTYPES[kind]) + if not limits.min <= int(value) <= limits.max: + raise ValueError(f"Value outside {kind} range") + return int(value) + + +class Sequence: + """Owned sequence with read-only borrowed NumPy views and explicit mutable copies.""" + + def __init__(self, field: Field, values: Any, owner: Message) -> None: + self.field, self.owner = field, owner + kind = field[1] + self.values: np.ndarray[Any, Any] | list[Any] + if kind in _DTYPES: + array = np.asarray(values) + if array.ndim != 1: + raise ValueError("Expected a one-dimensional sequence") + if kind != "bool" and not kind.startswith("float") and array.size: + limits = np.iinfo(_DTYPES[kind]) + if ( + not np.issubdtype(array.dtype, np.integer) + or np.any(array < limits.min) + or np.any(array > limits.max) + ): + raise ValueError(f"Sequence element outside {kind} range") + self.values = np.array(array, dtype=_DTYPES[kind], copy=True) + else: + self.values = [_scalar(kind, item, owner._codec) for item in values] + if field[3] is not None and not field[4] and len(self) != field[3]: + raise ValueError("Incorrect fixed-array length") + self._attach() + + def _attach(self) -> None: + if self.field[1] not in _DTYPES: + for value in self.values: + if hasattr(value, "_fields"): + value._attach(self.owner) + + def validate(self) -> None: + size = self.field[3] + if size is not None and (len(self) > size if self.field[4] else len(self) != size): + raise ValueError("Sequence exceeds sequence bound or fixed-array length") + if self.field[1] not in _DTYPES: + for value in self.values: + if hasattr(value, "_fields"): + value.validate() + elif self.field[5] is not None and len(value.encode()) > self.field[5]: + raise ValueError("String exceeds string bound") + + def __len__(self) -> int: + return len(self.values) + + def __getitem__(self, index: int) -> Any: + value = self.values[index] + return ( + copy.deepcopy(value) + if hasattr(value, "_fields") + else value.item() + if isinstance(value, np.generic) + else value + ) + + def __setitem__(self, index: int, value: Any) -> None: + converted = _scalar(self.field[1], value, self.owner._codec, self.field[5]) + if hasattr(converted, "_fields"): + converted._attach(self.owner) + self.values[index] = converted + + def __iter__(self) -> Any: + return (self[index] for index in range(len(self))) + + def __repr__(self) -> str: + return repr(list(self)) + + def __eq__(self, other: Any) -> bool: + try: + return list(self) == list(other) + except TypeError: + return False + + def extend(self, values: Any) -> None: + if self.field[3] is not None and not self.field[4]: + raise AttributeError("Fixed arrays cannot resize") + self.owner._check_borrow() + extra = Sequence((*self.field[:3], None, *self.field[4:]), values, self.owner) + combined = ( + np.concatenate((self.values, extra.values)) + if isinstance(self.values, np.ndarray) + else self.values + extra.values + ) + self.values = combined + self._attach() + + def append(self, value: Any) -> None: + self.extend([value]) + + def clear(self) -> None: + if self.field[3] is not None and not self.field[4]: + raise AttributeError("Fixed arrays cannot resize") + self.owner._check_borrow() + self.values = ( + np.empty(0, dtype=self.values.dtype) if isinstance(self.values, np.ndarray) else [] + ) + + def view(self, dtype: Any = None) -> np.ndarray[Any, Any]: + if not isinstance(self.values, np.ndarray): + raise TypeError("Only numeric sequences have NumPy views") + result = self.values.view(dtype) if dtype is not None else self.values.view() + result.setflags(write=False) + owner = self.owner._root() + owner._borrows += 1 + weakref.finalize(result, owner._release) + return result + + def copy(self) -> np.ndarray[Any, Any]: + if not isinstance(self.values, np.ndarray): + raise TypeError("Only numeric sequences have NumPy copies") + return self.values.copy() + + def byteswap(self) -> np.ndarray[Any, Any]: + if not isinstance(self.values, np.ndarray): + raise TypeError("Only numeric sequences support byte swapping") + return self.values.byteswap() + + +class Message: + msg_name: ClassVar[str] + schema: ClassVar[str] + _fields: ClassVar[tuple[Field, ...]] = () + _codec: ClassVar[Codec] + + def __init__(self, *args: Any, **kwargs: Any) -> None: + if len(args) > len(self._fields): + if self._fields or len(args) != 1: + raise TypeError("Too many message arguments") + args = () + self._owner: Message | None = None + self._borrows = 0 + if not self._fields: + self.structure_needs_at_least_one_member = 0 + positional = {field[0]: value for field, value in zip(self._fields, args, strict=False)} + if positional.keys() & kwargs.keys(): + raise TypeError("Duplicate message arguments") + values = positional | kwargs + unknown = values.keys() - {field[0] for field in self._fields} + if unknown: + raise TypeError(f"Unknown message field: {sorted(unknown)[0]}") + for field in self._fields: + name, kind, array, size, bounded, _, default = field + if name in values: + value = values[name] + elif default is not None: + value = default + elif array: + value = ( + [] if size is None or bounded else [self._default(kind) for _ in range(size)] + ) + else: + value = self._default(kind) + setattr(self, name, value) + self.validate() + + def _default(self, kind: str) -> Any: + if "/" in kind: + return self._codec.types[kind]() + return ( + "" + if kind == "string" + else False + if kind == "bool" + else 0.0 + if kind.startswith("float") + else 0 + ) + + def __setattr__(self, name: str, value: Any) -> None: + field = next((item for item in self._fields if item[0] == name), None) + if field is not None: + if field[2] or "/" in field[1]: + self._check_borrow() + value = ( + Sequence(field, value, self) if field[2] else _scalar(field[1], value, self._codec) + ) + if hasattr(value, "_fields"): + value._attach(self) + object.__setattr__(self, name, value) + + def _root(self) -> Message: + return self._owner._root() if self._owner is not None else self + + def _attach(self, owner: Message) -> None: + object.__setattr__(self, "_owner", owner) + + def _check_borrow(self) -> None: + if getattr(self._root(), "_borrows", 0): + raise BufferError( + "Cannot replace or resize message storage while a NumPy view is borrowed" + ) + + def _release(self) -> None: + self._borrows -= 1 + + def validate(self) -> None: + for field in self._fields: + value = getattr(self, field[0]) + if field[2] or hasattr(value, "_fields"): + value.validate() + else: + _scalar(field[1], value, self._codec, field[5]) + + def __deepcopy__(self, memo: dict[int, Any]) -> Message: + return type(self)( + **{ + field[0]: getattr(self, field[0]).values if field[2] else getattr(self, field[0]) + for field in self._fields + } + ) + + def __eq__(self, other: Any) -> bool: + return type(self) is type(other) and all( + getattr(self, field[0]) == getattr(other, field[0]) for field in self._fields + ) + + def __repr__(self) -> str: + return ( + f"{type(self).__name__}(" + + ", ".join(f"{field[0]}={getattr(self, field[0])!r}" for field in self._fields) + + ")" + ) + + def __reduce__(self) -> Any: + return type(self).decode, (self.encode(),) + + def encode(self, little_endian: bool = True) -> bytes: + self.validate() + return bytes( + self._codec.store.serialize_cdr(self, self.msg_name, little_endian=little_endian) + ) + + @classmethod + def decode(cls, data: bytes) -> Message: + if len(data) < 4 or data[:1] != b"\0" or data[1] not in (0, 1) or data[2:4] != b"\0\0": + raise ValueError("Expected plain CDR/XCDR1 encapsulation") + body = memoryview(data)[4:] + cls._codec.check(cls, body, bool(data[1])) + definition = cls._codec.store.get_msgdef(cls.msg_name) + decoder = definition.deserialize_cdr_le if data[1] else definition.deserialize_cdr_be + try: + value, position = decoder(body, 0, cls, cls._codec.store) + if position != len(body): + raise ValueError("Trailing bytes after CDR message") + return cast("Message", value) + except (struct.error, IndexError, OverflowError, AssertionError) as error: + raise ValueError("Invalid or truncated CDR message") from error + + +class Codec: + def __init__(self, schemas: dict[str, str], types: dict[str, type[Message]]) -> None: + self.types = types + self.store = get_typestore(Stores.EMPTY) + definitions = {} + for name, schema in schemas.items(): + definitions.update(get_types_from_msg(schema, name)) + self.store.register(definitions) + # Rosbags accepts constructor-compatible generated classes, not only its dataclasses. + self.store.types.update(cast("Any", types)) + self.store.cache.clear() + + def check(self, cls: type[Message], body: memoryview, little: bool) -> None: + """Check lengths/bounds before library decoding; numeric arrays are scanned in bulk.""" + endian = "<" if little else ">" + + def scalar(kind: str, position: int, bound: int | None) -> int: + if "/" in kind: + return message(self.types[kind], position) + if kind == "string": + position = (position + 3) & ~3 + size = length(position) + position += 4 + if size == 0 or position + size > len(body) or body[position + size - 1] != 0: + raise ValueError("Invalid or truncated CDR string") + if bound is not None and size - 1 > bound: + raise ValueError("String exceeds string bound") + bytes(body[position : position + size - 1]).decode() + return position + size + size = np.dtype(_DTYPES[kind]).itemsize + position = (position + size - 1) & -size + if position + size > len(body): + raise ValueError("Truncated CDR scalar") + if kind == "bool" and body[position] not in (0, 1): + raise ValueError("Invalid CDR bool") + return position + size + + def length(position: int) -> int: + if position + 4 > len(body): + raise ValueError("Truncated CDR length") + return int(struct.unpack_from(endian + "I", body, position)[0]) + + def message(kind: type[Message], position: int) -> int: + if not kind._fields: + return scalar("uint8", position, None) + for field in kind._fields: + _, name, array, size, bounded, bound, _ = field + if not array: + position = scalar(name, position, bound) + continue + if size is None or bounded: + position = (position + 3) & ~3 + count = length(position) + position += 4 + if size is not None and count > size: + raise ValueError("Sequence exceeds its declared bound") + else: + count = size + if name in _DTYPES: + width = np.dtype(_DTYPES[name]).itemsize + if count: + position = (position + width - 1) & -width + end = position + count * width + if end > len(body): + raise ValueError("Truncated CDR sequence") + if name == "bool" and any(item not in (0, 1) for item in body[position:end]): + raise ValueError("Invalid CDR bool") + position = end + else: + for _ in range(count): + position = scalar(name, position, bound) + return position + + if message(cls, 0) != len(body): + raise ValueError("Trailing bytes after CDR message") diff --git a/dimos/message_codegen/test_python_source.py b/dimos/message_codegen/test_python_source.py new file mode 100644 index 00000000000..c25de36f499 --- /dev/null +++ b/dimos/message_codegen/test_python_source.py @@ -0,0 +1,60 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Malformed wire data is rejected before constructing generated Python values.""" + +import struct + +generated = pytest.importorskip("dimos_generated", reason="Generate the source example first") +if not hasattr(generated, "demo_msgs"): + pytest.skip("Generate the source example first", allow_module_level=True) +Telemetry = generated.demo_msgs.msg.Telemetry +Bool = generated.std_msgs.msg.Bool +String = generated.std_msgs.msg.String +UInt32MultiArray = generated.std_msgs.msg.UInt32MultiArray +import pytest + + +@pytest.mark.parametrize("little", [True, False]) +def test_every_truncation_of_nested_message_is_rejected(little): + message = Telemetry(sequence=42, label="café", payload=[0, 255], hops=[-1, 2]) + encoded = message.encode(little_endian=little) + for end in range(len(encoded)): + with pytest.raises(ValueError): + Telemetry.decode(encoded[:end]) + with pytest.raises(ValueError, match="Trailing"): + Telemetry.decode(encoded + b"\0") + assert Telemetry.decode(encoded).encode(little_endian=little) == encoded + + +@pytest.mark.parametrize("little", [True, False]) +def test_string_requires_positive_length_terminator_and_valid_utf8(little): + endian = "<" if little else ">" + header = bytes([0, int(little), 0, 0]) + for length, payload in [(0, b""), (2, b"ab"), (2, b"\xff\0"), (0xFFFFFFFF, b"\0")]: + with pytest.raises(ValueError): + String.decode(header + struct.pack(endian + "I", length) + payload) + value = String(data="café") + assert String.decode(value.encode(little_endian=little)) == value + + +def test_invalid_encapsulation_bool_and_huge_sequence_are_rejected(): + with pytest.raises(ValueError, match="encapsulation"): + Bool.decode(b"\0\3\0\0\1") + with pytest.raises(ValueError, match="bool"): + Bool.decode(b"\0\1\0\0\2") + encoded = bytearray(UInt32MultiArray().encode()) + encoded[-4:] = struct.pack(" None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--functional-only", action="store_true", help="Verify buffer safety without timing loops" + ) + args = parser.parse_args() pixels = np.arange(640 * 480 * 3, dtype=np.uint8) points = np.arange(100_000 * 3, dtype=np.float32).view(np.uint8) fixtures = { @@ -58,6 +64,9 @@ def main() -> None: del view durations = {"borrow": [], "copy": [], "encode": [], "decode": []} encoded = message.encode() + if args.functional_only: + assert type(message).decode(encoded).encode() == encoded + continue for _ in range(30): start = perf_counter_ns() borrowed = message.data.view() diff --git a/openspec/changes/replace-lcm-message-encoding/design.md b/openspec/changes/replace-lcm-message-encoding/design.md index c2c6d003a36..42e1af3a183 100644 --- a/openspec/changes/replace-lcm-message-encoding/design.md +++ b/openspec/changes/replace-lcm-message-encoding/design.md @@ -46,22 +46,22 @@ bundled Jazzy .msg + local/installed .msg | | generated C++/Fast CDR generated Rust/Serde | | - generated pybind11 native CDR backend + generated Python source native CDR backend | Python All outputs use the same CDR wire contract. ``` -Use Fast CDR-backed generated C++ serialization and generated pybind11 bindings for Python. Python and C++ share the implementation rather than maintaining separate Python wire layouts. Rust uses generated native types with a Serde-compatible CDR backend. The generator also emits qualified type metadata and complete schema text for recording and introspection. +Use generated plain Python values with rosbags CDR serialization, and Fast CDR-backed generated C++ serialization. Python source does not require per-message native compilation; independent C++/Rust and Jazzy conformance verify the shared wire contract. Rust uses generated native types with a Serde-compatible CDR backend. The generator also emits qualified type metadata and complete schema text for recording and introspection. -The implementation uses the pinned upstream `rosidl_adapter` parser, a shared normalized definition model, a C++ struct/Fast CDR customization emitter, generated pybind11 bindings, and a Rust struct emitter plus `re_cdr`. Fast CDR owns sizing, alignment, primitive representation, and containers; the emitter only supplies the declared fields, defaults, validation, and library calls. There is no second handwritten wire engine. +The implementation uses the pinned upstream `rosidl_adapter` parser, a shared normalized definition model, a C++ struct/Fast CDR customization emitter, generated Python source values, and a Rust struct emitter plus `re_cdr`. Fast CDR owns sizing, alignment, primitive representation, and containers; the emitter only supplies the declared fields, defaults, validation, and library calls. There is no second handwritten wire engine. -The Fast-DDS-Gen 4.3.0 candidate was built successfully without ROS, but its IDL default annotation did not accept a ROS fixed-array default (`@default({1.0, 2.0})`). Using it would require additional default handling and a second schema transformation. Directly emitting the small native value types from the same normalized model preserves scalar and array defaults across all languages and removes Java/Gradle from the user build requirements. The currently validated dependencies are Fast CDR 2.4.0, pybind11 3.0.1, and `re_cdr` 0.1.0. The full 142-type build, independent-codec checks, Jazzy reference, bounds, and buffer tests now pass locally; CI repeats these gates. Packaging is stage 2. +The Fast-DDS-Gen 4.3.0 candidate was built successfully without ROS, but its IDL default annotation did not accept a ROS fixed-array default (`@default({1.0, 2.0})`). Using it would require additional default handling and a second schema transformation. Directly emitting the small native value types from the same normalized model preserves scalar and array defaults across all languages and removes Java/Gradle from the user build requirements. The currently validated dependencies are Fast CDR 2.4.0, rosbags 0.11.0, and `re_cdr` 0.1.0. The full 142-type build, independent-codec checks, Jazzy reference, bounds, and buffer tests now pass locally; CI repeats these gates. Packaging is stage 2. Use encapsulated plain CDR/XCDR1 with little-endian emission as the initial wire profile; decode the supported big- and little-endian representations according to the encapsulation header and reject unsupported representations. Check layout against ROS2 Jazzy serialization in CI. No LCM fingerprint or DimOS schema-hash prefix is part of the CDR payload. -Provide transport-neutral Python `encode()` and class-level `decode()` operations, equivalent generated codec operations in C++ and Rust, and immutable type/schema metadata. Keep generated wire types free of visualization or geometry dependencies. Nested fields and sequences must have documented mutation semantics in Python; do not rely on pybind11's implicit STL copies as if they were live views. +Provide transport-neutral Python `encode()` and class-level `decode()` operations, equivalent generated codec operations in C++ and Rust, and immutable type/schema metadata. Keep generated wire types free of visualization or geometry dependencies. Nested fields and sequences must have documented mutation semantics in Python; preserve safe read-only NumPy views and explicit copies without native bindings. **Alternatives considered:** handwritten codecs, a dynamic Python-only codec system, and a single FFI runtime for all languages. Handwritten layouts recreate the maintenance bottleneck; Python-only generation misses the native-language requirement; sharing the C++ backend with Python while keeping native Rust limits FFI complexity. @@ -138,7 +138,7 @@ Rollback is source/release rollback as a unit; old and new processes or recordin No outstanding product decisions require another user interview. The stage-1 checks below are resolved by the implementation evidence that follows; CI repeats the executable checks: -1. Exact pinned parser, C++ generator/Fast CDR, pybind11, and Rust codec versions that pass the complete `.msg` and CDR conformance suite without ROS installed. +1. Exact pinned parser, C++ generator/Fast CDR, Python/rosbags, and Rust codec versions that pass the complete `.msg` and CDR conformance suite without ROS installed. 2. Measured Python buffer-copy and owner-lifetime behavior, with any unavoidable copies documented. 3. The license/provenance and build viability of extracting Rust's existing raw LCM transport, or the concrete maintained replacement if extraction is unsuitable. 4. The consumer inventory and any necessary subdivision of stage 4 into independently runnable PRs, each retaining the demo requirement. @@ -180,3 +180,5 @@ These references informed exploration; pinned versions and executable conformanc - [MCAP schema and encoding registry](https://mcap.dev/spec/registry) - [Foxglove custom schema encodings](https://docs.foxglove.dev/docs/getting-started/custom/custom-schema-encodings) - [Rerun 0.32 MCAP message formats](https://github.com/rerun-io/rerun/blob/0.32.0/docs/content/concepts/logging-and-ingestion/mcap/message-formats.md) + +The user-approved source-only Python revision supersedes the original pybind design. Python classes are generated source; a shared pure-Python runtime delegates serialization to rosbags and validates malformed data, defaults, bounds and borrowed-buffer ownership. C++/Rust compile generated source with consumers. Historical native-Python evidence remains pinned to its old HEAD; this revision requires fresh conformance/install acceptance. diff --git a/openspec/changes/replace-lcm-message-encoding/proposal.md b/openspec/changes/replace-lcm-message-encoding/proposal.md index 7a93d94d08b..de41d6e2678 100644 --- a/openspec/changes/replace-lcm-message-encoding/proposal.md +++ b/openspec/changes/replace-lcm-message-encoding/proposal.md @@ -31,4 +31,4 @@ None. This checkout has no existing OpenSpec capability specifications; the new Affected areas include `dimos/msgs`, typed pub/sub and transports, Python module consumers, C++ and Rust SDKs/examples, timestamp and geometry helpers, live Rerun, browser decoding, memory recorders/readers, build manifests, CI, and documentation. Existing ROS bridge consumers must be updated to the generated field shapes; this does not add a new ROS interoperability objective. -The intended implementation uses Fast CDR-backed C++ codecs and generated pybind11 bindings, plus generated native Rust types with a CDR backend. Stage 1 must validate and pin the standalone generation backends before the application cutover. Native compilation is acceptable for local custom Python message builds. ROS is allowed only in optional integration environments and the CI conformance job, not as a requirement for generation, installation, or ordinary runtime use. +The intended implementation uses pure generated Python values with rosbags CDR, Fast CDR-backed C++ codecs, plus generated native Rust types with a CDR backend. Stage 1 must validate and pin the standalone generation backends before the application cutover. Python message generation/install must not require native compilation. C++/Rust generated source compiles with native consumers. ROS is allowed only in optional integration environments and the CI conformance job, not as a requirement for generation, installation, or ordinary runtime use. diff --git a/openspec/changes/replace-lcm-message-encoding/tasks.md b/openspec/changes/replace-lcm-message-encoding/tasks.md index 0c6e633286b..f92bf67abaa 100644 --- a/openspec/changes/replace-lcm-message-encoding/tasks.md +++ b/openspec/changes/replace-lcm-message-encoding/tasks.md @@ -5,7 +5,7 @@ - [x] 1.3 Pin and vendor the required Jazzy `.msg` dependency closure with immutable upstream revisions, licenses, and notices. - [x] 1.4 Implement standalone package resolution and parsing, including qualified names, transitive dependencies, defaults/bounds, conflict rejection, and source diagnostics for unsupported or invalid definitions. - [x] 1.5 Validate and pin the shared-definition C++ emitter/Fast CDR pipeline without ROS or DDS runtime requirements; generate buildable types and encapsulated XCDR1 codecs rather than handwritten message layouts. -- [x] 1.6 Generate pybind11 bindings sharing the C++ codecs, with transport-neutral encode/decode, nested-field/sequence mutation semantics, and type/schema metadata. +- [x] 1.6 Generate plain Python source values using a pure-Python CDR library, with transport-neutral encode/decode, nested-field/sequence mutation semantics, and type/schema metadata. - [x] 1.7 Validate and pin the native Rust generation/CDR backend, emit equivalent types/metadata/codecs, and document any rejected candidates with evidence in design.md. - [x] 1.8 Implement and verify read-only image/point-cloud buffer views, explicit mutable copies, owner lifetimes, and rejection of storage-invalidating mutations while views exist; capture representative buffer performance and copying behavior. - [x] 1.9 Add all nine language encoder/decoder conformance combinations, endian/alignment cases, defaults, bounds, fixed/dynamic arrays, nested standard/custom messages, malformed inputs, and independent ROS2 Jazzy reference checks in a separate CI job. diff --git a/scripts/test_message_codegen.sh b/scripts/test_message_codegen.sh index d8d312c287e..f25e2b79836 100644 --- a/scripts/test_message_codegen.sh +++ b/scripts/test_message_codegen.sh @@ -5,24 +5,20 @@ set -euo pipefail cd "$(dirname "$0")/.." .venv/bin/python -m dimos.message_codegen.generate \ --package-root examples/message-codegen --output build/message-codegen/demo -cmake -S build/message-codegen/demo/cpp -B build/message-codegen/demo/cpp/build \ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$PWD/build/message-codegen/install" \ - -DPython_EXECUTABLE="$PWD/.venv/bin/python" -cmake --build build/message-codegen/demo/cpp/build -j 2 c++ -std=c++17 -Ibuild/message-codegen/install/include -Ibuild/message-codegen/demo/cpp \ examples/message-codegen/relay.cpp build/message-codegen/install/lib/libfastcdr.a \ -o build/message-codegen/demo/cpp-relay mkdir -p build/message-codegen/demo/rust/src/bin build/message-codegen/demo/evidence cp examples/message-codegen/relay.rs build/message-codegen/demo/rust/src/bin/relay.rs cargo build --manifest-path build/message-codegen/demo/rust/Cargo.toml -export PYTHONPATH="$PWD/build/message-codegen/demo/cpp/build${PYTHONPATH:+:$PYTHONPATH}" +export PYTHONPATH="$PWD/build/message-codegen/demo/python${PYTHONPATH:+:$PYTHONPATH}" .venv/bin/python -m pytest dimos/message_codegen --noconftest -o addopts='' -q \ | tee build/message-codegen/demo/evidence/pytest.txt .venv/bin/python examples/message-codegen/demo_relay.py --build build/message-codegen/demo \ | tee build/message-codegen/demo/evidence/relay.txt .venv/bin/python examples/message-codegen/demo_conformance.py --build build/message-codegen/demo \ | tee build/message-codegen/demo/evidence/conformance.txt -.venv/bin/python examples/message-codegen/demo_buffers.py \ +.venv/bin/python examples/message-codegen/demo_buffers.py --functional-only \ | tee build/message-codegen/demo/evidence/buffers.txt cargo test -p dimos-lcm-transport cargo build -p dimos-lcm-transport --example interop From 9a7ac76bf7d69af32c08bd074ff03ad51c4dcf37 Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 1 Oct 2026 12:29:30 -0700 Subject: [PATCH 07/55] fix: expose generated Python source exports and order test imports --- dimos/message_codegen/python.py | 18 +++++++++++------- dimos/message_codegen/test_python_source.py | 3 ++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/dimos/message_codegen/python.py b/dimos/message_codegen/python.py index 63f89cd893f..f9e74bc1594 100644 --- a/dimos/message_codegen/python.py +++ b/dimos/message_codegen/python.py @@ -46,6 +46,7 @@ def generate( """Emit importable packages; dependency messages retain their canonical class identity.""" imported = imported or {} lines = [ + *Path(__file__).read_text().splitlines()[:13], "# Generated from ROS2 .msg definitions. Do not edit.", "from __future__ import annotations", "from ._runtime import Codec, Message, Sequence", @@ -133,14 +134,17 @@ def generate( "_types.py": "\n".join(lines) + "\n", "_runtime.py": Path(__file__).with_name("templates").joinpath("runtime.py").read_text(), "__init__.py": f"__dimos_version__ = {version!r}\n__dimos_abi__ = {ABI!r}\n" - + "".join(f"from . import {package}\n" for package in packages), - "py.typed": "", + + "".join(f"from . import {package} as {package}\n" for package in packages), + "py.typed": "# Generated message packages contain inline type annotations.\n", } for package in packages: - result[f"{package}/__init__.py"] = "from . import msg\n" - result[f"{package}/msg/__init__.py"] = "".join( - f"from ..._types import {message.name.replace('/', '__')} as {message.short_name}\n" - for message in messages - if message.package == package + result[f"{package}/__init__.py"] = "from . import msg as msg\n" + result[f"{package}/msg/__init__.py"] = ( + "".join( + f"from ..._types import {message.name.replace('/', '__')} as {message.short_name}\n" + for message in messages + if message.package == package + ) + + f"__all__ = {[message.short_name for message in messages if message.package == package]!r}\n" ) return result diff --git a/dimos/message_codegen/test_python_source.py b/dimos/message_codegen/test_python_source.py index c25de36f499..4cd1f2950d5 100644 --- a/dimos/message_codegen/test_python_source.py +++ b/dimos/message_codegen/test_python_source.py @@ -16,6 +16,8 @@ import struct +import pytest + generated = pytest.importorskip("dimos_generated", reason="Generate the source example first") if not hasattr(generated, "demo_msgs"): pytest.skip("Generate the source example first", allow_module_level=True) @@ -23,7 +25,6 @@ Bool = generated.std_msgs.msg.Bool String = generated.std_msgs.msg.String UInt32MultiArray = generated.std_msgs.msg.UInt32MultiArray -import pytest @pytest.mark.parametrize("little", [True, False]) From 681e8746b05c41f4f82f178951519981b86d698f Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 1 Oct 2026 12:44:04 -0700 Subject: [PATCH 08/55] fix: preserve bulk byte payloads and immutable borrowed views --- dimos/message_codegen/templates/runtime.py | 11 ++++++++--- dimos/message_codegen/test_native.py | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dimos/message_codegen/templates/runtime.py b/dimos/message_codegen/templates/runtime.py index 8745fb6b67b..31e441d2a8d 100644 --- a/dimos/message_codegen/templates/runtime.py +++ b/dimos/message_codegen/templates/runtime.py @@ -79,7 +79,11 @@ def __init__(self, field: Field, values: Any, owner: Message) -> None: kind = field[1] self.values: np.ndarray[Any, Any] | list[Any] if kind in _DTYPES: - array = np.asarray(values) + array = ( + np.frombuffer(values, dtype=np.uint8) + if kind == "uint8" and isinstance(values, (bytes, bytearray)) + else np.asarray(values) + ) if array.ndim != 1: raise ValueError("Expected a one-dimensional sequence") if kind != "bool" and not kind.startswith("float") and array.size: @@ -172,8 +176,9 @@ def clear(self) -> None: def view(self, dtype: Any = None) -> np.ndarray[Any, Any]: if not isinstance(self.values, np.ndarray): raise TypeError("Only numeric sequences have NumPy views") - result = self.values.view(dtype) if dtype is not None else self.values.view() - result.setflags(write=False) + result = np.frombuffer(memoryview(self.values).toreadonly(), dtype=self.values.dtype) + if dtype is not None: + result = result.view(dtype) owner = self.owner._root() owner._borrows += 1 weakref.finalize(result, owner._release) diff --git a/dimos/message_codegen/test_native.py b/dimos/message_codegen/test_native.py index 7e29108028f..9555c7686a0 100644 --- a/dimos/message_codegen/test_native.py +++ b/dimos/message_codegen/test_native.py @@ -181,3 +181,22 @@ def test_standard_string_message_round_trips(): value = generated.std_msgs.msg.String(data="hello") assert value.decode(value.encode()).data == "hello" + + +def test_binary_sequence_copies_bytes_and_bytearray_without_scalar_conversion(): + payload = bytes(range(256)) * 3600 + image = Image(height=480, width=640, encoding="rgb8", step=1920, data=payload) + assert bytes(image.data.view()) == payload + assert bytes(Image.decode(image.encode()).data.view()) == payload + mutable = bytearray(payload) + image.data = mutable + mutable[0] = 255 + assert image.data[0] == 0 + + +def test_borrowed_numeric_view_cannot_reenable_writes(): + message = Image(data=bytes([1, 2, 3, 4])) + view = message.data.view() + with pytest.raises(ValueError, match="WRITEABLE"): + view.setflags(write=True) + assert bytes(view) == b"\x01\x02\x03\x04" From ee46c763b24f4ab7c528aaf162df93cc4add2c3a Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 1 Oct 2026 13:08:34 -0700 Subject: [PATCH 09/55] fix: preserve generated message type in Python decode typing --- dimos/message_codegen/templates/runtime.py | 7 ++++--- dimos/message_codegen/test_python_source.py | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/dimos/message_codegen/templates/runtime.py b/dimos/message_codegen/templates/runtime.py index 31e441d2a8d..724c3fa2313 100644 --- a/dimos/message_codegen/templates/runtime.py +++ b/dimos/message_codegen/templates/runtime.py @@ -18,7 +18,7 @@ import copy import struct -from typing import Any, ClassVar, cast +from typing import Any, ClassVar, TypeVar, cast import weakref import numpy as np @@ -41,6 +41,7 @@ } # name, scalar type, array, size/bound, bounded sequence, string bound, default Field = tuple[str, str, bool, int | None, bool, int | None, Any] +_MessageT = TypeVar("_MessageT", bound="Message") def _scalar(kind: str, value: Any, codec: Codec, bound: int | None = None) -> Any: @@ -310,7 +311,7 @@ def encode(self, little_endian: bool = True) -> bytes: ) @classmethod - def decode(cls, data: bytes) -> Message: + def decode(cls: type[_MessageT], data: bytes) -> _MessageT: if len(data) < 4 or data[:1] != b"\0" or data[1] not in (0, 1) or data[2:4] != b"\0\0": raise ValueError("Expected plain CDR/XCDR1 encapsulation") body = memoryview(data)[4:] @@ -321,7 +322,7 @@ def decode(cls, data: bytes) -> Message: value, position = decoder(body, 0, cls, cls._codec.store) if position != len(body): raise ValueError("Trailing bytes after CDR message") - return cast("Message", value) + return cast("_MessageT", value) except (struct.error, IndexError, OverflowError, AssertionError) as error: raise ValueError("Invalid or truncated CDR message") from error diff --git a/dimos/message_codegen/test_python_source.py b/dimos/message_codegen/test_python_source.py index 4cd1f2950d5..cb048b2199e 100644 --- a/dimos/message_codegen/test_python_source.py +++ b/dimos/message_codegen/test_python_source.py @@ -14,7 +14,11 @@ """Malformed wire data is rejected before constructing generated Python values.""" +import os +from pathlib import Path import struct +import subprocess +import sys import pytest @@ -59,3 +63,19 @@ def test_invalid_encapsulation_bool_and_huge_sequence_are_rejected(): encoded[-4:] = struct.pack(" Date: Thu, 1 Oct 2026 13:10:26 -0700 Subject: [PATCH 10/55] ci: install type checker for generated source consumer gate --- .github/workflows/message-codegen.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml index 05803620f28..ec40c434e71 100644 --- a/.github/workflows/message-codegen.yml +++ b/.github/workflows/message-codegen.yml @@ -28,7 +28,7 @@ jobs: run: | test ! -d /opt/ros uv venv .venv --python 3.12 - uv pip install --python .venv/bin/python rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env lcm-dimos-fork + uv pip install --python .venv/bin/python rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env lcm-dimos-fork mypy==1.19.0 .venv/bin/python -c "import importlib.util; assert importlib.util.find_spec('rclpy') is None" - name: Build the pinned standalone CDR library run: bash scripts/setup_message_codegen.sh From 53970241cb3f01d84724e0f90c75603cb4ecc8b9 Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 1 Oct 2026 13:19:06 -0700 Subject: [PATCH 11/55] ci: provide source codec dependency in lint environment --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 1e61e67ef9f..00868ce407d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -467,6 +467,8 @@ browser-tests = [ # Lint / format / type-check tooling for the dedicated `lint` CI job. lint = [ + # Generated source codec template is checked before the runtime cutover. + "rosbags==0.11.0", # Lint / format / type-check "ruff==0.14.3", "mypy==1.19.0", From baac948652b9c6dadd4857e3c51d8d1773f37df1 Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 8 Oct 2026 13:10:56 -0700 Subject: [PATCH 12/55] refactor: isolate generator review from message catalog and bus integration --- .github/workflows/message-codegen.yml | 4 +- Cargo.lock | 9 - Cargo.toml | 1 - dimos/experimental/memory/rust/flake.nix | 1 - dimos/message_codegen/README.md | 14 +- .../geometry_msgs => _vendor}/LICENSE | 0 .../rosidl_adapter.package.xml} | 0 dimos/message_codegen/definitions.py | 2 +- .../builtin_interfaces/msg/Duration.msg | 12 - .../schemas/builtin_interfaces/msg/Time.msg | 11 - .../schemas/builtin_interfaces/package.xml | 29 -- .../foxglove_msgs/msg/CompressedVideo.msg | 44 -- .../schemas/geometry_msgs/msg/Accel.msg | 3 - .../geometry_msgs/msg/AccelStamped.msg | 3 - .../geometry_msgs/msg/AccelWithCovariance.msg | 9 - .../msg/AccelWithCovarianceStamped.msg | 3 - .../schemas/geometry_msgs/msg/Inertia.msg | 16 - .../geometry_msgs/msg/InertiaStamped.msg | 4 - .../schemas/geometry_msgs/msg/Point.msg | 4 - .../schemas/geometry_msgs/msg/Point32.msg | 11 - .../geometry_msgs/msg/PointStamped.msg | 4 - .../schemas/geometry_msgs/msg/Polygon.msg | 3 - .../geometry_msgs/msg/PolygonInstance.msg | 5 - .../msg/PolygonInstanceStamped.msg | 5 - .../geometry_msgs/msg/PolygonStamped.msg | 4 - .../schemas/geometry_msgs/msg/Pose.msg | 4 - .../schemas/geometry_msgs/msg/Pose2D.msg | 10 - .../schemas/geometry_msgs/msg/PoseArray.msg | 5 - .../schemas/geometry_msgs/msg/PoseStamped.msg | 4 - .../geometry_msgs/msg/PoseWithCovariance.msg | 9 - .../msg/PoseWithCovarianceStamped.msg | 4 - .../schemas/geometry_msgs/msg/Quaternion.msg | 6 - .../geometry_msgs/msg/QuaternionStamped.msg | 4 - .../schemas/geometry_msgs/msg/Transform.msg | 4 - .../geometry_msgs/msg/TransformStamped.msg | 19 - .../schemas/geometry_msgs/msg/Twist.msg | 4 - .../geometry_msgs/msg/TwistStamped.msg | 4 - .../geometry_msgs/msg/TwistWithCovariance.msg | 9 - .../msg/TwistWithCovarianceStamped.msg | 4 - .../schemas/geometry_msgs/msg/Vector3.msg | 9 - .../geometry_msgs/msg/Vector3Stamped.msg | 7 - .../geometry_msgs/msg/VelocityStamped.msg | 8 - .../msg/VelocityWithCovarianceStamped.msg | 17 - .../schemas/geometry_msgs/msg/Wrench.msg | 4 - .../geometry_msgs/msg/WrenchStamped.msg | 4 - .../schemas/geometry_msgs/package.xml | 32 -- .../schemas/licenses/foxglove_schemas/LICENSE | 21 - .../ros-perception_vision_msgs/LICENSE | 201 --------- .../schemas/licenses/ros2_geometry2/LICENSE | 29 -- .../licenses/ros2_rcl_interfaces/LICENSE | 202 --------- .../schemas/licenses/ros2_rosidl/LICENSE | 202 --------- .../message_codegen/schemas/nav_msgs/LICENSE | 202 --------- .../schemas/nav_msgs/msg/Goals.msg | 12 - .../schemas/nav_msgs/msg/GridCells.msg | 12 - .../schemas/nav_msgs/msg/MapMetaData.msg | 17 - .../schemas/nav_msgs/msg/OccupancyGrid.msg | 13 - .../schemas/nav_msgs/msg/Odometry.msg | 15 - .../schemas/nav_msgs/msg/Path.msg | 7 - .../schemas/nav_msgs/msg/Trajectory.msg | 7 - .../schemas/nav_msgs/msg/TrajectoryPoint.msg | 16 - .../schemas/nav_msgs/package.xml | 34 -- .../schemas/sensor_msgs/LICENSE | 202 --------- .../schemas/sensor_msgs/msg/BatteryState.msg | 54 --- .../schemas/sensor_msgs/msg/CameraInfo.msg | 131 ------ .../sensor_msgs/msg/ChannelFloat32.msg | 24 -- .../sensor_msgs/msg/CompressedImage.msg | 41 -- .../schemas/sensor_msgs/msg/FluidPressure.msg | 12 - .../schemas/sensor_msgs/msg/Illuminance.msg | 20 - .../schemas/sensor_msgs/msg/Image.msg | 26 -- .../schemas/sensor_msgs/msg/Imu.msg | 24 -- .../schemas/sensor_msgs/msg/JointState.msg | 25 -- .../schemas/sensor_msgs/msg/Joy.msg | 10 - .../schemas/sensor_msgs/msg/JoyFeedback.msg | 14 - .../sensor_msgs/msg/JoyFeedbackArray.msg | 2 - .../schemas/sensor_msgs/msg/LaserEcho.msg | 5 - .../schemas/sensor_msgs/msg/LaserScan.msg | 30 -- .../schemas/sensor_msgs/msg/MagneticField.msg | 21 - .../sensor_msgs/msg/MultiDOFJointState.msg | 26 -- .../sensor_msgs/msg/MultiEchoLaserScan.msg | 32 -- .../schemas/sensor_msgs/msg/NavSatFix.msg | 45 -- .../schemas/sensor_msgs/msg/NavSatStatus.msg | 24 -- .../schemas/sensor_msgs/msg/PointCloud.msg | 17 - .../schemas/sensor_msgs/msg/PointCloud2.msg | 26 -- .../schemas/sensor_msgs/msg/PointField.msg | 16 - .../schemas/sensor_msgs/msg/Range.msg | 42 -- .../sensor_msgs/msg/RegionOfInterest.msg | 19 - .../sensor_msgs/msg/RelativeHumidity.msg | 13 - .../schemas/sensor_msgs/msg/Temperature.msg | 8 - .../schemas/sensor_msgs/msg/TimeReference.msg | 7 - .../schemas/sensor_msgs/package.xml | 37 -- .../schemas/shape_msgs/LICENSE | 202 --------- .../schemas/shape_msgs/msg/Mesh.msg | 7 - .../schemas/shape_msgs/msg/MeshTriangle.msg | 3 - .../schemas/shape_msgs/msg/Plane.msg | 7 - .../schemas/shape_msgs/msg/SolidPrimitive.msg | 50 --- .../schemas/shape_msgs/package.xml | 31 -- .../message_codegen/schemas/std_msgs/LICENSE | 202 --------- .../schemas/std_msgs/msg/Bool.msg | 6 - .../schemas/std_msgs/msg/Byte.msg | 6 - .../schemas/std_msgs/msg/ByteMultiArray.msg | 10 - .../schemas/std_msgs/msg/Char.msg | 6 - .../schemas/std_msgs/msg/ColorRGBA.msg | 4 - .../schemas/std_msgs/msg/Empty.msg | 0 .../schemas/std_msgs/msg/Float32.msg | 6 - .../std_msgs/msg/Float32MultiArray.msg | 10 - .../schemas/std_msgs/msg/Float64.msg | 6 - .../std_msgs/msg/Float64MultiArray.msg | 10 - .../schemas/std_msgs/msg/Header.msg | 9 - .../schemas/std_msgs/msg/Int16.msg | 6 - .../schemas/std_msgs/msg/Int16MultiArray.msg | 10 - .../schemas/std_msgs/msg/Int32.msg | 6 - .../schemas/std_msgs/msg/Int32MultiArray.msg | 10 - .../schemas/std_msgs/msg/Int64.msg | 6 - .../schemas/std_msgs/msg/Int64MultiArray.msg | 10 - .../schemas/std_msgs/msg/Int8.msg | 6 - .../schemas/std_msgs/msg/Int8MultiArray.msg | 10 - .../std_msgs/msg/MultiArrayDimension.msg | 8 - .../schemas/std_msgs/msg/MultiArrayLayout.msg | 31 -- .../schemas/std_msgs/msg/String.msg | 6 - .../schemas/std_msgs/msg/UInt16.msg | 6 - .../schemas/std_msgs/msg/UInt16MultiArray.msg | 10 - .../schemas/std_msgs/msg/UInt32.msg | 6 - .../schemas/std_msgs/msg/UInt32MultiArray.msg | 10 - .../schemas/std_msgs/msg/UInt64.msg | 6 - .../schemas/std_msgs/msg/UInt64MultiArray.msg | 10 - .../schemas/std_msgs/msg/UInt8.msg | 6 - .../schemas/std_msgs/msg/UInt8MultiArray.msg | 10 - .../schemas/std_msgs/package.xml | 31 -- .../schemas/tf2_msgs/msg/TF2Error.msg | 10 - .../schemas/tf2_msgs/msg/TFMessage.msg | 1 - .../schemas/tf2_msgs/package.xml | 36 -- .../schemas/trajectory_msgs/LICENSE | 202 --------- .../trajectory_msgs/msg/JointTrajectory.msg | 11 - .../msg/JointTrajectoryPoint.msg | 26 -- .../msg/MultiDOFJointTrajectory.msg | 10 - .../msg/MultiDOFJointTrajectoryPoint.msg | 11 - .../schemas/trajectory_msgs/package.xml | 34 -- .../schemas/vision_msgs/msg/BoundingBox2D.msg | 13 - .../vision_msgs/msg/BoundingBox2DArray.msg | 2 - .../schemas/vision_msgs/msg/BoundingBox3D.msg | 10 - .../vision_msgs/msg/BoundingBox3DArray.msg | 2 - .../vision_msgs/msg/Classification.msg | 17 - .../schemas/vision_msgs/msg/Detection2D.msg | 23 - .../vision_msgs/msg/Detection2DArray.msg | 7 - .../schemas/vision_msgs/msg/Detection3D.msg | 23 - .../vision_msgs/msg/Detection3DArray.msg | 7 - .../schemas/vision_msgs/msg/LabelInfo.msg | 25 -- .../vision_msgs/msg/ObjectHypothesis.msg | 12 - .../msg/ObjectHypothesisWithPose.msg | 16 - .../schemas/vision_msgs/msg/Point2D.msg | 5 - .../schemas/vision_msgs/msg/Pose2D.msg | 4 - .../schemas/vision_msgs/msg/VisionClass.msg | 12 - .../schemas/vision_msgs/msg/VisionInfo.msg | 40 -- .../schemas/vision_msgs/package.xml | 37 -- .../schemas/visualization_msgs/LICENSE | 202 --------- .../visualization_msgs/msg/ImageMarker.msg | 36 -- .../msg/InteractiveMarker.msg | 26 -- .../msg/InteractiveMarkerControl.msg | 77 ---- .../msg/InteractiveMarkerFeedback.msg | 42 -- .../msg/InteractiveMarkerInit.msg | 14 - .../msg/InteractiveMarkerPose.msg | 10 - .../msg/InteractiveMarkerUpdate.msg | 32 -- .../schemas/visualization_msgs/msg/Marker.msg | 81 ---- .../visualization_msgs/msg/MarkerArray.msg | 1 - .../visualization_msgs/msg/MenuEntry.msg | 54 --- .../visualization_msgs/msg/MeshFile.msg | 8 - .../visualization_msgs/msg/UVCoordinate.msg | 4 - .../schemas/visualization_msgs/package.xml | 35 -- dimos/message_codegen/sources.json | 199 +-------- dimos/message_codegen/test_definitions.py | 14 +- dimos/message_codegen/test_native.py | 6 +- .../builtin_interfaces/msg/Time.msg | 2 + examples/message-codegen/demo_transport.py | 66 --- .../geometry_msgs/msg/Point.msg | 3 + .../message-codegen/sensor_msgs/msg/Image.msg | 7 + .../sensor_msgs/msg/PointCloud2.msg | 9 + .../sensor_msgs/msg/PointField.msg | 12 + .../message-codegen/std_msgs/msg/Bool.msg | 1 + .../message-codegen/std_msgs/msg/Header.msg | 2 + .../std_msgs/msg/MultiArrayDimension.msg | 3 + .../std_msgs/msg/MultiArrayLayout.msg | 2 + .../message-codegen/std_msgs/msg/String.msg | 1 + .../std_msgs/msg/UInt32MultiArray.msg | 2 + native/rust/dimos-lcm-transport/Cargo.toml | 11 - native/rust/dimos-lcm-transport/README.md | 27 -- .../dimos-lcm-transport/examples/interop.rs | 46 -- native/rust/dimos-lcm-transport/src/lib.rs | 41 -- .../rust/dimos-lcm-transport/src/transport.rs | 395 ------------------ scripts/test_message_codegen.sh | 4 - scripts/vendor_message_definitions.py | 117 ------ 190 files changed, 63 insertions(+), 5219 deletions(-) rename dimos/message_codegen/{schemas/geometry_msgs => _vendor}/LICENSE (100%) rename dimos/message_codegen/{schemas/rosidl_adapter/package.xml => _vendor/rosidl_adapter.package.xml} (100%) delete mode 100644 dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg delete mode 100644 dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg delete mode 100644 dimos/message_codegen/schemas/builtin_interfaces/package.xml delete mode 100644 dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg delete mode 100644 dimos/message_codegen/schemas/geometry_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE delete mode 100644 dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE delete mode 100644 dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE delete mode 100644 dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE delete mode 100644 dimos/message_codegen/schemas/nav_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Path.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg delete mode 100644 dimos/message_codegen/schemas/nav_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg delete mode 100644 dimos/message_codegen/schemas/sensor_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/shape_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg delete mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg delete mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg delete mode 100644 dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg delete mode 100644 dimos/message_codegen/schemas/shape_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/std_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Bool.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Byte.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Char.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Empty.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float32.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float64.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Header.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int16.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int32.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int64.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int8.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/String.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg delete mode 100644 dimos/message_codegen/schemas/std_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg delete mode 100644 dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg delete mode 100644 dimos/message_codegen/schemas/tf2_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/trajectory_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg delete mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg delete mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg delete mode 100644 dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg delete mode 100644 dimos/message_codegen/schemas/trajectory_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg delete mode 100644 dimos/message_codegen/schemas/vision_msgs/package.xml delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/LICENSE delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg delete mode 100644 dimos/message_codegen/schemas/visualization_msgs/package.xml create mode 100644 examples/message-codegen/builtin_interfaces/msg/Time.msg delete mode 100644 examples/message-codegen/demo_transport.py create mode 100644 examples/message-codegen/geometry_msgs/msg/Point.msg create mode 100644 examples/message-codegen/sensor_msgs/msg/Image.msg create mode 100644 examples/message-codegen/sensor_msgs/msg/PointCloud2.msg create mode 100644 examples/message-codegen/sensor_msgs/msg/PointField.msg create mode 100644 examples/message-codegen/std_msgs/msg/Bool.msg create mode 100644 examples/message-codegen/std_msgs/msg/Header.msg create mode 100644 examples/message-codegen/std_msgs/msg/MultiArrayDimension.msg create mode 100644 examples/message-codegen/std_msgs/msg/MultiArrayLayout.msg create mode 100644 examples/message-codegen/std_msgs/msg/String.msg create mode 100644 examples/message-codegen/std_msgs/msg/UInt32MultiArray.msg delete mode 100644 native/rust/dimos-lcm-transport/Cargo.toml delete mode 100644 native/rust/dimos-lcm-transport/README.md delete mode 100644 native/rust/dimos-lcm-transport/examples/interop.rs delete mode 100644 native/rust/dimos-lcm-transport/src/lib.rs delete mode 100644 native/rust/dimos-lcm-transport/src/transport.rs delete mode 100644 scripts/vendor_message_definitions.py diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml index ec40c434e71..8f08bcfd85b 100644 --- a/.github/workflows/message-codegen.yml +++ b/.github/workflows/message-codegen.yml @@ -5,9 +5,7 @@ on: paths: - dimos/message_codegen/** - examples/message-codegen/** - - native/rust/dimos-lcm-transport/** - scripts/*message*codegen* - - scripts/vendor_message_definitions.py - .github/workflows/message-codegen.yml - .github/docker/message-codegen-reference.Dockerfile - Cargo.toml @@ -28,7 +26,7 @@ jobs: run: | test ! -d /opt/ros uv venv .venv --python 3.12 - uv pip install --python .venv/bin/python rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env lcm-dimos-fork mypy==1.19.0 + uv pip install --python .venv/bin/python rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env mypy==1.19.0 .venv/bin/python -c "import importlib.util; assert importlib.util.find_spec('rclpy') is None" - name: Build the pinned standalone CDR library run: bash scripts/setup_message_codegen.sh diff --git a/Cargo.lock b/Cargo.lock index 36eba2f6905..5b05f816169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,15 +657,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "dimos-lcm-transport" -version = "0.1.0" -dependencies = [ - "byteorder", - "socket2 0.5.10", - "tokio", -] - [[package]] name = "dimos-livox" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index da1f355be5b..33236ae92da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ members = [ "dimos/experimental/memory/rust", "native/rust/dimos-module", "native/rust/dimos-module-macros", - "native/rust/dimos-lcm-transport", "dimos/mapping/ray_tracing/rust", "dimos/mapping/ray_tracing/rust/py", "dimos/navigation/global_planner/mls_planner/rust", diff --git a/dimos/experimental/memory/rust/flake.nix b/dimos/experimental/memory/rust/flake.nix index 83a8badd620..368ebe32b3c 100644 --- a/dimos/experimental/memory/rust/flake.nix +++ b/dimos/experimental/memory/rust/flake.nix @@ -31,7 +31,6 @@ ../../../../Cargo.toml ../../../../dimos/experimental/memory/rust ../../../../native/rust/dimos-module - ../../../../native/rust/dimos-lcm-transport ../../../../native/rust/dimos-module-macros ../../../../dimos/mapping/ray_tracing/rust ../../../../dimos/mapping/ray_tracing/rust/py diff --git a/dimos/message_codegen/README.md b/dimos/message_codegen/README.md index 17915a0160b..811efc17367 100644 --- a/dimos/message_codegen/README.md +++ b/dimos/message_codegen/README.md @@ -2,8 +2,7 @@ This package reads ROS2 `.msg` files without importing or installing ROS. A pinned upstream `rosidl_adapter` parser validates syntax. DimOS resolves package names and -dependencies, then emits C++ value types and Fast CDR customizations, Python -bindings to those types, and native Rust types using Serde and `re_cdr`. +dependencies, then emits C++ value types and Fast CDR customizations, ordinary Python source values, and native Rust types using Serde and `re_cdr`. ```bash python -m dimos.message_codegen.generate \ @@ -32,9 +31,9 @@ emit plain CDR/XCDR1 with its standard four-byte encapsulation. ## Upstream sources and licenses `sources.json` records immutable revisions and SHA-256 hashes for the vendored -files. `schemas/*/package.xml` retains upstream authorship and declared licenses. -`schemas/licenses/` contains upstream license texts, including the Apache 2.0 -license shared by the standard interface packages and parser. The parser's +files. The full standard definition collection, licenses and generated message packages +belong to the following message-package layer. This layer contains only small +self-contained test definitions under `examples/message-codegen`. The parser's original copyright header is preserved. `rosidl_parser.pyi` is DimOS's type stub; the upstream implementation has one documented patch replacing an ambiguous constant-name regex with its linear-time equivalent. `sources.json` records both @@ -48,3 +47,8 @@ Applications and builds never run the maintenance downloader. This work is being delivered through the `replace-lcm-message-encoding` OpenSpec change. The generated pipeline is under development; the old runtime message APIs have not yet been replaced. + +Generation resolves only explicitly supplied roots by default in this layer. +The following package layer provides bundled standard definitions. Raw LCM bus +interop belongs to the runtime layer; this layer tests CDR bytes independently +of transport. diff --git a/dimos/message_codegen/schemas/geometry_msgs/LICENSE b/dimos/message_codegen/_vendor/LICENSE similarity index 100% rename from dimos/message_codegen/schemas/geometry_msgs/LICENSE rename to dimos/message_codegen/_vendor/LICENSE diff --git a/dimos/message_codegen/schemas/rosidl_adapter/package.xml b/dimos/message_codegen/_vendor/rosidl_adapter.package.xml similarity index 100% rename from dimos/message_codegen/schemas/rosidl_adapter/package.xml rename to dimos/message_codegen/_vendor/rosidl_adapter.package.xml diff --git a/dimos/message_codegen/definitions.py b/dimos/message_codegen/definitions.py index 380d5ac4a56..1a0105994ea 100644 --- a/dimos/message_codegen/definitions.py +++ b/dimos/message_codegen/definitions.py @@ -142,7 +142,7 @@ def parse_message(path: Path) -> Message: class Definitions: """A closed set of local definitions with dependency-first resolution.""" - def __init__(self, roots: Iterable[Path], *, bundled: bool = True) -> None: + def __init__(self, roots: Iterable[Path], *, bundled: bool = False) -> None: self._messages: dict[str, Message] = {} for root in ([BUNDLED_SCHEMAS] if bundled else []) + list(roots): if not root.is_dir(): diff --git a/dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg b/dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg deleted file mode 100644 index dc9e8f5a2bc..00000000000 --- a/dimos/message_codegen/schemas/builtin_interfaces/msg/Duration.msg +++ /dev/null @@ -1,12 +0,0 @@ -# Duration defines a period between two time points. -# Messages of this datatype are of ROS Time following this design: -# https://design.ros2.org/articles/clock_and_time.html - -# The seconds component, valid over all int32 values. -int32 sec - -# The nanoseconds component, valid in the range [0, 1e9), to be added to the seconds component. -# e.g. -# The duration -1.7 seconds is represented as {sec: -2, nanosec: 3e8} -# The duration 1.7 seconds is represented as {sec: 1, nanosec: 7e8} -uint32 nanosec diff --git a/dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg b/dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg deleted file mode 100644 index 03cc83f8622..00000000000 --- a/dimos/message_codegen/schemas/builtin_interfaces/msg/Time.msg +++ /dev/null @@ -1,11 +0,0 @@ -# This message communicates ROS Time defined here: -# https://design.ros2.org/articles/clock_and_time.html - -# The seconds component, valid over all int32 values. -int32 sec - -# The nanoseconds component, valid in the range [0, 1e9), to be added to the seconds component. -# e.g. -# The time -1.7 seconds is represented as {sec: -2, nanosec: 3e8} -# The time 1.7 seconds is represented as {sec: 1, nanosec: 7e8} -uint32 nanosec diff --git a/dimos/message_codegen/schemas/builtin_interfaces/package.xml b/dimos/message_codegen/schemas/builtin_interfaces/package.xml deleted file mode 100644 index 57540d0b204..00000000000 --- a/dimos/message_codegen/schemas/builtin_interfaces/package.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - builtin_interfaces - 2.0.4 - A package containing message and service definitions for types defined in the OMG IDL Platform Specific Model. - - Geoffrey Biggs - - Apache License 2.0 - - Chris Lalancette - Dirk Thomas - Michel Hidalgo - - ament_cmake - - rosidl_core_generators - - rosidl_core_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg b/dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg deleted file mode 100644 index 19041bc924a..00000000000 --- a/dimos/message_codegen/schemas/foxglove_msgs/msg/CompressedVideo.msg +++ /dev/null @@ -1,44 +0,0 @@ -# foxglove_msgs/msg/CompressedVideo -# A single frame of a compressed video bitstream - -# Generated by https://github.com/foxglove/foxglove-sdk - -# Timestamp of video frame -builtin_interfaces/Time timestamp - -# Frame of reference for the video. -# -# The origin of the frame is the optical center of the camera. +x points to the right in the video, +y points down, and +z points into the plane of the video. -string frame_id - -# Compressed video frame data. -# -# For packet-based video codecs this data must begin and end on packet boundaries (no partial packets), and must contain enough video packets to decode exactly one image (either a keyframe or delta frame). Note: Foxglove does not support video streams that include B frames because they require lookahead. -# -# Specifically, the requirements for different `format` values are: -# -# - `h264` -# - Use Annex B formatted data -# - Each CompressedVideo message should contain enough NAL units to decode exactly one video frame -# - Each message containing a key frame (IDR) must also include a SPS NAL unit -# -# - `h265` (HEVC) -# - Use Annex B formatted data -# - Each CompressedVideo message should contain enough NAL units to decode exactly one video frame -# - Each message containing a key frame (IRAP) must also include relevant VPS/SPS/PPS NAL units -# -# - `vp9` -# - Each CompressedVideo message should contain exactly one video frame -# -# - `av1` -# - Use the "Low overhead bitstream format" (section 5.2) -# - Each CompressedVideo message should contain enough OBUs to decode exactly one video frame -# - Each message containing a key frame must also include a Sequence Header OBU -uint8[] data - -# Video format. -# -# Supported values: `h264`, `h265`, `vp9`, `av1`. -# -# Note: compressed video support is subject to hardware limitations and patent licensing, so not all encodings may be supported on all platforms. See more about [H.265 support](https://caniuse.com/hevc), [VP9 support](https://caniuse.com/webm), and [AV1 support](https://caniuse.com/av1). -string format diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg deleted file mode 100644 index 19fef1411b7..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Accel.msg +++ /dev/null @@ -1,3 +0,0 @@ -# This expresses acceleration in free space broken into its linear and angular parts. -Vector3 linear -Vector3 angular diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg deleted file mode 100644 index 9283fbbd377..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelStamped.msg +++ /dev/null @@ -1,3 +0,0 @@ -# An accel with reference coordinate frame and timestamp -std_msgs/Header header -Accel accel diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg deleted file mode 100644 index fb9674d3061..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovariance.msg +++ /dev/null @@ -1,9 +0,0 @@ -# This expresses acceleration in free space with uncertainty. - -Accel accel - -# Row-major representation of the 6x6 covariance matrix -# The orientation parameters use a fixed-axis representation. -# In order, the parameters are: -# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis) -float64[36] covariance diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg deleted file mode 100644 index 90acd6edc5f..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg +++ /dev/null @@ -1,3 +0,0 @@ -# This represents an estimated accel with reference coordinate frame and timestamp. -std_msgs/Header header -AccelWithCovariance accel diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg deleted file mode 100644 index 912aa9530f2..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Inertia.msg +++ /dev/null @@ -1,16 +0,0 @@ -# Mass [kg] -float64 m - -# Center of mass [m] -geometry_msgs/Vector3 com - -# Inertia Tensor [kg-m^2] about the center of mass -# | ixx ixy ixz | -# I = | ixy iyy iyz | -# | ixz iyz izz | -float64 ixx -float64 ixy -float64 ixz -float64 iyy -float64 iyz -float64 izz diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg deleted file mode 100644 index 7da2662b572..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/InertiaStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# An Inertia with a time stamp and reference frame. - -std_msgs/Header header -Inertia inertia diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg deleted file mode 100644 index f1d3a71a853..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Point.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This contains the position of a point in free space -float64 x -float64 y -float64 z diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg deleted file mode 100644 index a7f5dc41354..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Point32.msg +++ /dev/null @@ -1,11 +0,0 @@ -# This contains the position of a point in free space(with 32 bits of precision). -# It is recommended to use Point wherever possible instead of Point32. -# -# This recommendation is to promote interoperability. -# -# This message is designed to take up less space when sending -# lots of points at once, as in the case of a PointCloud. - -float32 x -float32 y -float32 z diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg deleted file mode 100644 index 32a734cc5e9..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PointStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This represents a Point with reference coordinate frame and timestamp - -std_msgs/Header header -Point point diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg deleted file mode 100644 index 47aeb74db29..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Polygon.msg +++ /dev/null @@ -1,3 +0,0 @@ -# A specification of a polygon where the first and last points are assumed to be connected - -Point32[] points diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg deleted file mode 100644 index 61d6af5b905..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstance.msg +++ /dev/null @@ -1,5 +0,0 @@ -# A specification of a polygon where the first and last points are assumed to be connected -# It includes a unique identification field for disambiguating multiple instances - -geometry_msgs/Polygon polygon -int64 id diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg deleted file mode 100644 index cefda8de0f2..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonInstanceStamped.msg +++ /dev/null @@ -1,5 +0,0 @@ -# This represents a Polygon with reference coordinate frame and timestamp -# It includes a unique identification field for disambiguating multiple instances - -std_msgs/Header header -geometry_msgs/PolygonInstance polygon diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg deleted file mode 100644 index 3b87ac14c59..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PolygonStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This represents a Polygon with reference coordinate frame and timestamp - -std_msgs/Header header -Polygon polygon diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg deleted file mode 100644 index 277e2f0179a..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Pose.msg +++ /dev/null @@ -1,4 +0,0 @@ -# A representation of pose in free space, composed of position and orientation. - -Point position -Quaternion orientation diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg deleted file mode 100644 index e9cf0166685..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Pose2D.msg +++ /dev/null @@ -1,10 +0,0 @@ -# Deprecated as of Foxy and will potentially be removed in any following release. -# Please use the full 3D pose. - -# In general our recommendation is to use a full 3D representation of everything and for 2D specific applications make the appropriate projections into the plane for their calculations but optimally will preserve the 3D information during processing. - -# If we have parallel copies of 2D datatypes every UI and other pipeline will end up needing to have dual interfaces to plot everything. And you will end up with not being able to use 3D tools for 2D use cases even if they're completely valid, as you'd have to reimplement it with different inputs and outputs. It's not particularly hard to plot the 2D pose or compute the yaw error for the Pose message and there are already tools and libraries that can do this for you.# This expresses a position and orientation on a 2D manifold. - -float64 x -float64 y -float64 theta diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg deleted file mode 100644 index 80386e088e2..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseArray.msg +++ /dev/null @@ -1,5 +0,0 @@ -# An array of poses with a header for global reference. - -std_msgs/Header header - -Pose[] poses diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg deleted file mode 100644 index 2b43935ed33..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# A Pose with reference coordinate frame and timestamp - -std_msgs/Header header -Pose pose diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg deleted file mode 100644 index 86bc45adbb5..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovariance.msg +++ /dev/null @@ -1,9 +0,0 @@ -# This represents a pose in free space with uncertainty. - -Pose pose - -# Row-major representation of the 6x6 covariance matrix -# The orientation parameters use a fixed-axis representation. -# In order, the parameters are: -# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis) -float64[36] covariance diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg deleted file mode 100644 index d439cdf75b7..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This expresses an estimated pose with a reference coordinate frame and timestamp - -std_msgs/Header header -PoseWithCovariance pose diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg deleted file mode 100644 index 96d392779a2..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Quaternion.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This represents an orientation in free space in quaternion form. - -float64 x 0 -float64 y 0 -float64 z 0 -float64 w 1 diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg deleted file mode 100644 index f192883220f..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/QuaternionStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This represents an orientation with reference coordinate frame and timestamp. - -std_msgs/Header header -Quaternion quaternion diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg deleted file mode 100644 index f605c85ea8e..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Transform.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This represents the transform between two coordinate frames in free space. - -Vector3 translation -Quaternion rotation diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg deleted file mode 100644 index 24e97b80b39..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/TransformStamped.msg +++ /dev/null @@ -1,19 +0,0 @@ -# This expresses a transform from coordinate frame header.frame_id -# to the coordinate frame child_frame_id at the time of header.stamp -# -# This message is mostly used by the -# tf2 package. -# See its documentation for more information. -# -# The child_frame_id is necessary in addition to the frame_id -# in the Header to communicate the full reference for the transform -# in a self contained message. - -# The frame id in the header is used as the reference frame of this transform. -std_msgs/Header header - -# The frame id of the child frame to which this transform points. -string child_frame_id - -# Translation and rotation in 3-dimensions of child_frame_id from header.frame_id. -Transform transform diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg deleted file mode 100644 index ede73597b90..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Twist.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This expresses velocity in free space broken into its linear and angular parts. - -Vector3 linear -Vector3 angular diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg deleted file mode 100644 index 2dcbeac1b07..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# A twist with reference coordinate frame and timestamp - -std_msgs/Header header -Twist twist diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg deleted file mode 100644 index 111a19c5f7d..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovariance.msg +++ /dev/null @@ -1,9 +0,0 @@ -# This expresses velocity in free space with uncertainty. - -Twist twist - -# Row-major representation of the 6x6 covariance matrix -# The orientation parameters use a fixed-axis representation. -# In order, the parameters are: -# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis) -float64[36] covariance diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg deleted file mode 100644 index 90b65b1f3e9..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This represents an estimated twist with reference coordinate frame and timestamp. - -std_msgs/Header header -TwistWithCovariance twist diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg deleted file mode 100644 index b54588e117c..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3.msg +++ /dev/null @@ -1,9 +0,0 @@ -# This represents a vector in free space. - -# This is semantically different than a point. -# A vector is always anchored at the origin. -# When a transform is applied to a vector, only the rotational component is applied. - -float64 x -float64 y -float64 z diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg deleted file mode 100644 index aab1e0a9860..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Vector3Stamped.msg +++ /dev/null @@ -1,7 +0,0 @@ -# This represents a Vector3 with reference coordinate frame and timestamp - -# Note that this follows vector semantics with it always anchored at the origin, -# so the rotational elements of a transform are the only parts applied when transforming. - -std_msgs/Header header -Vector3 vector diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg deleted file mode 100644 index ff61c6ea244..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityStamped.msg +++ /dev/null @@ -1,8 +0,0 @@ -# This expresses the timestamped velocity vector of a frame 'body_frame_id' in the reference frame 'reference_frame_id' expressed from arbitrary observation frame 'header.frame_id'. -# - If the 'body_frame_id' and 'header.frame_id' are identical, the velocity is observed and defined in the local coordinates system of the body -# which is the usual use-case in mobile robotics and is also known as a body twist. - -std_msgs/Header header -string body_frame_id -string reference_frame_id -Twist velocity diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg deleted file mode 100644 index 391557a4b54..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg +++ /dev/null @@ -1,17 +0,0 @@ -# A timestamped velocity of a body whose frame is 'body_frame_id', measured -# relative to the reference frame 'reference_frame_id', with the velocity and -# covariance both expressed in the basis of the observation frame -# 'header.frame_id'. -# -# - If 'body_frame_id' and 'header.frame_id' are identical, the velocity and -# covariance are expressed in the body's own basis. This is functionally -# equivalent to the body-twist convention used by -# 'geometry_msgs/TwistStamped'. -# -# This message is the covariance-bearing analogue of -# 'geometry_msgs/VelocityStamped'. - -std_msgs/Header header -string body_frame_id -string reference_frame_id -TwistWithCovariance velocity diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg deleted file mode 100644 index 0b8efccbe33..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/Wrench.msg +++ /dev/null @@ -1,4 +0,0 @@ -# This represents force in free space, separated into its linear and angular parts. - -Vector3 force -Vector3 torque diff --git a/dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg b/dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg deleted file mode 100644 index 0d5ebd9674a..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/msg/WrenchStamped.msg +++ /dev/null @@ -1,4 +0,0 @@ -# A wrench with reference coordinate frame and timestamp - -std_msgs/Header header -Wrench wrench diff --git a/dimos/message_codegen/schemas/geometry_msgs/package.xml b/dimos/message_codegen/schemas/geometry_msgs/package.xml deleted file mode 100644 index 66313657cc7..00000000000 --- a/dimos/message_codegen/schemas/geometry_msgs/package.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - geometry_msgs - 5.3.8 - A package containing some geometry related message definitions. - - Tully Foote - - Apache License 2.0 - - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - William Woodall - - ament_cmake - - rosidl_default_generators - - std_msgs - - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE b/dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE deleted file mode 100644 index 0aa593ea8c2..00000000000 --- a/dimos/message_codegen/schemas/licenses/foxglove_schemas/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) Foxglove Technologies Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE b/dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/dimos/message_codegen/schemas/licenses/ros-perception_vision_msgs/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE b/dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE deleted file mode 100644 index d79557eefaf..00000000000 --- a/dimos/message_codegen/schemas/licenses/ros2_geometry2/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2008, Willow Garage, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE b/dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/licenses/ros2_rcl_interfaces/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE b/dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/licenses/ros2_rosidl/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/nav_msgs/LICENSE b/dimos/message_codegen/schemas/nav_msgs/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg deleted file mode 100644 index f07f5a8c317..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/Goals.msg +++ /dev/null @@ -1,12 +0,0 @@ -# An array of navigation goals - - -# This header will store the time at which the poses were computed (not to be confused with the stamps of the poses themselves) -# In the case that individual poses do not have their frame_id set or their timetamp set they will use the default value here. -std_msgs/Header header - -# An array of goals to for navigation to achieve. -# The goals should be executed in the order of the array. -# The header and stamp are intended to be used for computing the position of the goals. -# They may vary to support cases of goals that are moving with respect to the robot. -geometry_msgs/PoseStamped[] goals diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg b/dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg deleted file mode 100644 index 7154e6c57a6..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/GridCells.msg +++ /dev/null @@ -1,12 +0,0 @@ -# An array of cells in a 2D grid - -std_msgs/Header header - -# Width of each cell -float32 cell_width - -# Height of each cell -float32 cell_height - -# Each cell is represented by the Point at the center of the cell -geometry_msgs/Point[] cells diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg b/dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg deleted file mode 100644 index 1c11e290e22..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/MapMetaData.msg +++ /dev/null @@ -1,17 +0,0 @@ -# This hold basic information about the characteristics of the OccupancyGrid - -# The time at which the map was loaded -builtin_interfaces/Time map_load_time - -# The map resolution [m/cell] -float32 resolution - -# Map width [cells] -uint32 width - -# Map height [cells] -uint32 height - -# The origin of the map [m, m, rad]. This is the real-world pose of the -# bottom left corner of cell (0,0) in the map. -geometry_msgs/Pose origin diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg b/dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg deleted file mode 100644 index abbd189bd85..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/OccupancyGrid.msg +++ /dev/null @@ -1,13 +0,0 @@ -# This represents a 2-D grid map -std_msgs/Header header - -# MetaData for the map -MapMetaData info - -# The map data, in row-major order, starting with (0,0). -# Cell (1, 0) will be listed second, representing the next cell in the x direction. -# Cell (0, 1) will be at the index equal to info.width, followed by (1, 1). -# The values inside are application dependent, but frequently, -# 0 represents unoccupied, 1 represents definitely occupied, and -# -1 represents unknown. -int8[] data diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg deleted file mode 100644 index 7186f064bf6..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/Odometry.msg +++ /dev/null @@ -1,15 +0,0 @@ -# This represents an estimate of a position and velocity in free space. -# The pose in this message should be specified in the coordinate frame given by header.frame_id -# The twist in this message should be specified in the coordinate frame given by the child_frame_id - -# Includes the frame id of the pose parent. -std_msgs/Header header - -# Frame id the pose points to. The twist is in this coordinate frame. -string child_frame_id - -# Estimated pose that is typically relative to a fixed world frame. -geometry_msgs/PoseWithCovariance pose - -# Estimated linear and angular velocity relative to child_frame_id. -geometry_msgs/TwistWithCovariance twist diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Path.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Path.msg deleted file mode 100644 index 8be8de72916..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/Path.msg +++ /dev/null @@ -1,7 +0,0 @@ -# An array of poses that represents a Path for a robot to follow. - -# Indicates the frame_id of the path. -std_msgs/Header header - -# Array of poses to follow. -geometry_msgs/PoseStamped[] poses diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg b/dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg deleted file mode 100644 index cb796629465..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/Trajectory.msg +++ /dev/null @@ -1,7 +0,0 @@ -# An array of trajectory points that represents a trajectory for a robot to follow. - -# Indicates the frame_id in which the planner ran and timestamp represents when the trajectory was generated. -std_msgs/Header header - -# Array of trajectory points to follow. -TrajectoryPoint[] points diff --git a/dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg b/dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg deleted file mode 100644 index dde4b17fbc6..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/msg/TrajectoryPoint.msg +++ /dev/null @@ -1,16 +0,0 @@ -# Trajectory point state - -# Absolute time and frame of reference of the point along a trajectory -std_msgs/Header header - -# Pose of the trajectory sample. -geometry_msgs/Pose pose - -# Velocity of the trajectory sample. -geometry_msgs/Twist velocity - -# Acceleration of the trajectory (optional, linear.x component is NaN if not set). -geometry_msgs/Accel acceleration - -# Force/Torque to apply at trajectory sample (optional, force.x component is NaN if not set). -geometry_msgs/Wrench effort diff --git a/dimos/message_codegen/schemas/nav_msgs/package.xml b/dimos/message_codegen/schemas/nav_msgs/package.xml deleted file mode 100644 index 20e73abba5f..00000000000 --- a/dimos/message_codegen/schemas/nav_msgs/package.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - nav_msgs - 5.3.8 - A package containing some navigation related message and service definitions. - - Tully Foote - - Apache License 2.0 - - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - William Woodall - - ament_cmake - - rosidl_default_generators - - builtin_interfaces - geometry_msgs - std_msgs - - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/sensor_msgs/LICENSE b/dimos/message_codegen/schemas/sensor_msgs/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg deleted file mode 100644 index c42ed6e1133..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/BatteryState.msg +++ /dev/null @@ -1,54 +0,0 @@ - -# Constants are chosen to match the enums in the linux kernel -# defined in include/linux/power_supply.h as of version 3.7 -# The one difference is for style reasons the constants are -# all uppercase not mixed case. - -# Power supply status constants -uint8 POWER_SUPPLY_STATUS_UNKNOWN = 0 -uint8 POWER_SUPPLY_STATUS_CHARGING = 1 -uint8 POWER_SUPPLY_STATUS_DISCHARGING = 2 -uint8 POWER_SUPPLY_STATUS_NOT_CHARGING = 3 -uint8 POWER_SUPPLY_STATUS_FULL = 4 - -# Power supply health constants -uint8 POWER_SUPPLY_HEALTH_UNKNOWN = 0 -uint8 POWER_SUPPLY_HEALTH_GOOD = 1 -uint8 POWER_SUPPLY_HEALTH_OVERHEAT = 2 -uint8 POWER_SUPPLY_HEALTH_DEAD = 3 -uint8 POWER_SUPPLY_HEALTH_OVERVOLTAGE = 4 -uint8 POWER_SUPPLY_HEALTH_UNSPEC_FAILURE = 5 -uint8 POWER_SUPPLY_HEALTH_COLD = 6 -uint8 POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE = 7 -uint8 POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE = 8 - -# Power supply technology (chemistry) constants -uint8 POWER_SUPPLY_TECHNOLOGY_UNKNOWN = 0 # Unknown battery technology -uint8 POWER_SUPPLY_TECHNOLOGY_NIMH = 1 # Nickel-Metal Hydride battery -uint8 POWER_SUPPLY_TECHNOLOGY_LION = 2 # Lithium-ion battery -uint8 POWER_SUPPLY_TECHNOLOGY_LIPO = 3 # Lithium Polymer battery -uint8 POWER_SUPPLY_TECHNOLOGY_LIFE = 4 # Lithium Iron Phosphate battery -uint8 POWER_SUPPLY_TECHNOLOGY_NICD = 5 # Nickel-Cadmium battery -uint8 POWER_SUPPLY_TECHNOLOGY_LIMN = 6 # Lithium Manganese Dioxide battery -uint8 POWER_SUPPLY_TECHNOLOGY_TERNARY = 7 # Ternary Lithium battery -uint8 POWER_SUPPLY_TECHNOLOGY_VRLA = 8 # Valve Regulated Lead-Acid battery - -std_msgs/Header header -float32 voltage # Voltage in Volts (Mandatory) -float32 temperature # Temperature in Degrees Celsius (If unmeasured NaN) -float32 current # Negative when discharging (A) (If unmeasured NaN) -float32 charge # Current charge in Ah (If unmeasured NaN) -float32 capacity # Capacity in Ah (last full capacity) (If unmeasured NaN) -float32 design_capacity # Capacity in Ah (design capacity) (If unmeasured NaN) -float32 percentage # Charge percentage on 0 to 1 range (If unmeasured NaN) -uint8 power_supply_status # The charging status as reported. Values defined above -uint8 power_supply_health # The battery health metric. Values defined above -uint8 power_supply_technology # The battery chemistry. Values defined above -bool present # True if the battery is present - -float32[] cell_voltage # An array of individual cell voltages for each cell in the pack - # If individual voltages unknown but number of cells known set each to NaN -float32[] cell_temperature # An array of individual cell temperatures for each cell in the pack - # If individual temperatures unknown but number of cells known set each to NaN -string location # The location into which the battery is inserted. (slot number or plug) -string serial_number # The best approximation of the battery serial number diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg deleted file mode 100644 index f2e7b0608df..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/CameraInfo.msg +++ /dev/null @@ -1,131 +0,0 @@ -# This message defines meta information for a camera. It should be in a -# camera namespace on topic "camera_info" and accompanied by up to five -# image topics named: -# -# image_raw - raw data from the camera driver, possibly Bayer encoded -# image - monochrome, distorted -# image_color - color, distorted -# image_rect - monochrome, rectified -# image_rect_color - color, rectified -# -# The image_pipeline contains packages (image_proc, stereo_image_proc) -# for producing the four processed image topics from image_raw and -# camera_info. The meaning of the camera parameters are described in -# detail at http://www.ros.org/wiki/image_pipeline/CameraInfo. -# -# The image_geometry package provides a user-friendly interface to -# common operations using this meta information. If you want to, e.g., -# project a 3d point into image coordinates, we strongly recommend -# using image_geometry. -# -# If the camera is uncalibrated, the matrices D, K, R, P should be left -# zeroed out. In particular, clients may assume that K[0] == 0.0 -# indicates an uncalibrated camera. - -####################################################################### -# Image acquisition info # -####################################################################### - -# Time of image acquisition, camera coordinate frame ID -std_msgs/Header header # Header timestamp should be acquisition time of image - # Header frame_id should be optical frame of camera - # origin of frame should be optical center of camera - # +x should point to the right in the image - # +y should point down in the image - # +z should point into the plane of the image - - -####################################################################### -# Calibration Parameters # -####################################################################### -# These are fixed during camera calibration. Their values will be the # -# same in all messages until the camera is recalibrated. Note that # -# self-calibrating systems may "recalibrate" frequently. # -# # -# The internal parameters can be used to warp a raw (distorted) image # -# to: # -# 1. An undistorted image (requires D and K) # -# 2. A rectified image (requires D, K, R) # -# The projection matrix P projects 3D points into the rectified image.# -####################################################################### - -# The image dimensions with which the camera was calibrated. -# Normally this will be the full camera resolution in pixels. -uint32 height -uint32 width - -# The distortion model used. Supported models are listed in -# sensor_msgs/distortion_models.hpp. For most cameras, "plumb_bob" - a -# simple model of radial and tangential distortion - is sufficent. -string distortion_model - -# The distortion parameters, size depending on the distortion model. -# For "plumb_bob", the 5 parameters are: (k1, k2, t1, t2, k3). -float64[] d - -# Intrinsic camera matrix for the raw (distorted) images. -# [fx 0 cx] -# K = [ 0 fy cy] -# [ 0 0 1] -# Projects 3D points in the camera coordinate frame to 2D pixel -# coordinates using the focal lengths (fx, fy) and principal point -# (cx, cy). -float64[9] k # 3x3 row-major matrix - -# Rectification matrix (stereo cameras only) -# A rotation matrix aligning the camera coordinate system to the ideal -# stereo image plane so that epipolar lines in both stereo images are -# parallel. -float64[9] r # 3x3 row-major matrix - -# Projection/camera matrix -# [fx' 0 cx' Tx] -# P = [ 0 fy' cy' Ty] -# [ 0 0 1 0] -# By convention, this matrix specifies the intrinsic (camera) matrix -# of the processed (rectified) image. That is, the left 3x3 portion -# is the normal camera intrinsic matrix for the rectified image. -# It projects 3D points in the camera coordinate frame to 2D pixel -# coordinates using the focal lengths (fx', fy') and principal point -# (cx', cy') - these may differ from the values in K. -# For monocular cameras, Tx = Ty = 0. Normally, monocular cameras will -# also have R = the identity and P[1:3,1:3] = K. -# For a stereo pair, the fourth column [Tx Ty 0]' is related to the -# position of the optical center of the second camera in the first -# camera's frame. We assume Tz = 0 so both cameras are in the same -# stereo image plane. The first camera always has Tx = Ty = 0. For -# the right (second) camera of a horizontal stereo pair, Ty = 0 and -# Tx = -fx' * B, where B is the baseline between the cameras. -# Given a 3D point [X Y Z]', the projection (x, y) of the point onto -# the rectified image is given by: -# [u v w]' = P * [X Y Z 1]' -# x = u / w -# y = v / w -# This holds for both images of a stereo pair. -float64[12] p # 3x4 row-major matrix - - -####################################################################### -# Operational Parameters # -####################################################################### -# These define the image region actually captured by the camera # -# driver. Although they affect the geometry of the output image, they # -# may be changed freely without recalibrating the camera. # -####################################################################### - -# Binning refers here to any camera setting which combines rectangular -# neighborhoods of pixels into larger "super-pixels." It reduces the -# resolution of the output image to -# (width / binning_x) x (height / binning_y). -# The default values binning_x = binning_y = 0 is considered the same -# as binning_x = binning_y = 1 (no subsampling). -uint32 binning_x -uint32 binning_y - -# Region of interest (subwindow of full camera resolution), given in -# full resolution (unbinned) image coordinates. A particular ROI -# always denotes the same window of pixels on the camera sensor, -# regardless of binning settings. -# The default setting of roi (all values 0) is considered the same as -# full resolution (roi.width = width, roi.height = height). -RegionOfInterest roi diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg deleted file mode 100644 index 0518d8d45e1..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/ChannelFloat32.msg +++ /dev/null @@ -1,24 +0,0 @@ -# This message is used by the PointCloud message to hold optional data -# associated with each point in the cloud. The length of the values -# array should be the same as the length of the points array in the -# PointCloud, and each value should be associated with the corresponding -# point. -# -# Channel names in existing practice include: -# "u", "v" - row and column (respectively) in the left stereo image. -# This is opposite to usual conventions but remains for -# historical reasons. The newer PointCloud2 message has no -# such problem. -# "rgb" - For point clouds produced by color stereo cameras. uint8 -# (R,G,B) values packed into the least significant 24 bits, -# in order. -# "intensity" - laser or pixel intensity. -# "distance" - -# The channel name should give semantics of the channel (e.g. -# "intensity" instead of "value"). -string name - -# The values array should be 1-1 with the elements of the associated -# PointCloud. -float32[] values diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg deleted file mode 100644 index 12a724d5647..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/CompressedImage.msg +++ /dev/null @@ -1,41 +0,0 @@ -# This message contains a compressed image. - -std_msgs/Header header # Header timestamp should be acquisition time of image - # Header frame_id should be optical frame of camera - # origin of frame should be optical center of cameara - # +x should point to the right in the image - # +y should point down in the image - # +z should point into to plane of the image - -string format # Specifies the format of the data - # Acceptable values differ by the image transport used: - # - compressed_image_transport: - # ORIG_PIXFMT; CODEC compressed [COMPRESSED_PIXFMT] - # where: - # - ORIG_PIXFMT is pixel format of the raw image, i.e. - # the content of sensor_msgs/Image/encoding with - # values from include/sensor_msgs/image_encodings.h - # - CODEC is one of [jpeg, png, tiff] - # - COMPRESSED_PIXFMT is only appended for color images - # and is the pixel format used by the compression - # algorithm. Valid values for jpeg encoding are: - # [bgr8, rgb8]. Valid values for png encoding are: - # [bgr8, rgb8, bgr16, rgb16]. - # If the field is empty or does not correspond to the - # above pattern, the image is treated as bgr8 or mono8 - # jpeg image (depending on the number of channels). - # - compressed_depth_image_transport: - # ORIG_PIXFMT; compressedDepth CODEC - # where: - # - ORIG_PIXFMT is pixel format of the raw image, i.e. - # the content of sensor_msgs/Image/encoding with - # values from include/sensor_msgs/image_encodings.h - # It is usually one of [16UC1, 32FC1]. - # - CODEC is one of [png, rvl] - # If the field is empty or does not correspond to the - # above pattern, the image is treated as png image. - # - Other image transports can store whatever values they - # need for successful decoding of the image. Refer to - # documentation of the other transports for details. - -uint8[] data # Compressed image buffer diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg deleted file mode 100644 index 2350d615ea8..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/FluidPressure.msg +++ /dev/null @@ -1,12 +0,0 @@ -# Single pressure reading. This message is appropriate for measuring the -# pressure inside of a fluid (air, water, etc). This also includes -# atmospheric or barometric pressure. -# -# This message is not appropriate for force/pressure contact sensors. - -std_msgs/Header header # timestamp of the measurement - # frame_id is the location of the pressure sensor - -float64 fluid_pressure # Absolute pressure reading in Pascals. - -float64 variance # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg deleted file mode 100644 index 43cd8e7196e..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/Illuminance.msg +++ /dev/null @@ -1,20 +0,0 @@ -# Single photometric illuminance measurement. Light should be assumed to be -# measured along the sensor's x-axis (the area of detection is the y-z plane). -# The illuminance should have a 0 or positive value and be received with -# the sensor's +X axis pointing toward the light source. -# -# Photometric illuminance is the measure of the human eye's sensitivity of the -# intensity of light encountering or passing through a surface. -# -# All other Photometric and Radiometric measurements should not use this message. -# This message cannot represent: -# - Luminous intensity (candela/light source output) -# - Luminance (nits/light output per area) -# - Irradiance (watt/area), etc. - -std_msgs/Header header # timestamp is the time the illuminance was measured - # frame_id is the location and direction of the reading - -float64 illuminance # Measurement of the Photometric Illuminance in Lux. - -float64 variance # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg deleted file mode 100644 index c13efdf78ed..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/Image.msg +++ /dev/null @@ -1,26 +0,0 @@ -# This message contains an uncompressed image -# (0, 0) is at top-left corner of image - -std_msgs/Header header # Header timestamp should be acquisition time of image - # Header frame_id should be optical frame of camera - # origin of frame should be optical center of cameara - # +x should point to the right in the image - # +y should point down in the image - # +z should point into to plane of the image - # If the frame_id here and the frame_id of the CameraInfo - # message associated with the image conflict - # the behavior is undefined - -uint32 height # image height, that is, number of rows -uint32 width # image width, that is, number of columns - -# The legal values for encoding are in file include/sensor_msgs/image_encodings.hpp -# If you want to standardize a new string format, join -# ros-users@lists.ros.org and send an email proposing a new encoding. - -string encoding # Encoding of pixels -- channel meaning, ordering, size - # taken from the list of strings in include/sensor_msgs/image_encodings.hpp - -uint8 is_bigendian # is this data bigendian? -uint32 step # Full row length in bytes -uint8[] data # actual matrix data, size is (step * rows) diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg deleted file mode 100644 index 8d8a6bdaf34..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/Imu.msg +++ /dev/null @@ -1,24 +0,0 @@ -# This is a message to hold data from an IMU (Inertial Measurement Unit) -# -# Accelerations should be in m/s^2 (not in g's), and rotational velocity should be in rad/sec -# -# If the covariance of the measurement is known, it should be filled in (if all you know is the -# variance of each measurement, e.g. from the datasheet, just put those along the diagonal) -# A covariance matrix of all zeros will be interpreted as "covariance unknown", and to use the -# data a covariance will have to be assumed or gotten from some other source -# -# If you have no estimate for one of the data elements (e.g. your IMU doesn't produce an -# orientation estimate), please set element 0 of the associated covariance matrix to -1 -# If you are interpreting this message, please check for a value of -1 in the first element of each -# covariance matrix, and disregard the associated estimate. - -std_msgs/Header header - -geometry_msgs/Quaternion orientation -float64[9] orientation_covariance # Row major about x, y, z axes - -geometry_msgs/Vector3 angular_velocity -float64[9] angular_velocity_covariance # Row major about x, y, z axes - -geometry_msgs/Vector3 linear_acceleration -float64[9] linear_acceleration_covariance # Row major x, y z diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg deleted file mode 100644 index ffaa9bfb005..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/JointState.msg +++ /dev/null @@ -1,25 +0,0 @@ -# This is a message that holds data to describe the state of a set of torque controlled joints. -# -# The state of each joint (revolute or prismatic) is defined by: -# * the position of the joint (rad or m), -# * the velocity of the joint (rad/s or m/s) and -# * the effort that is applied in the joint (Nm or N). -# -# Each joint is uniquely identified by its name -# The header specifies the time at which the joint states were recorded. All the joint states -# in one message have to be recorded at the same time. -# -# This message consists of a multiple arrays, one for each part of the joint state. -# The goal is to make each of the fields optional. When e.g. your joints have no -# effort associated with them, you can leave the effort array empty. -# -# All arrays in this message should have the same size, or be empty. -# This is the only way to uniquely associate the joint name with the correct -# states. - -std_msgs/Header header - -string[] name -float64[] position -float64[] velocity -float64[] effort diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg deleted file mode 100644 index ca7801fe286..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/Joy.msg +++ /dev/null @@ -1,10 +0,0 @@ -# Reports the state of a joystick's axes and buttons. - -# The timestamp is the time at which data is received from the joystick. -std_msgs/Header header - -# The axes measurements from a joystick. -float32[] axes - -# The buttons measurements from a joystick. -int32[] buttons diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg deleted file mode 100644 index 153cc093359..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedback.msg +++ /dev/null @@ -1,14 +0,0 @@ -# Declare of the type of feedback -uint8 TYPE_LED = 0 -uint8 TYPE_RUMBLE = 1 -uint8 TYPE_BUZZER = 2 - -uint8 type - -# This will hold an id number for each type of each feedback. -# Example, the first led would be id=0, the second would be id=1 -uint8 id - -# Intensity of the feedback, from 0.0 to 1.0, inclusive. If device is -# actually binary, driver should treat 0<=x<0.5 as off, 0.5<=x<=1 as on. -float32 intensity diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg deleted file mode 100644 index f6981b8c48b..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/JoyFeedbackArray.msg +++ /dev/null @@ -1,2 +0,0 @@ -# This message publishes values for multiple feedback at once. -JoyFeedback[] array diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg deleted file mode 100644 index cefdecfe0f2..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/LaserEcho.msg +++ /dev/null @@ -1,5 +0,0 @@ -# This message is a submessage of MultiEchoLaserScan and is not intended -# to be used separately. - -float32[] echoes # Multiple values of ranges or intensities. - # Each array represents data from the same angle increment. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg deleted file mode 100644 index 6e5c2a1c7cd..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/LaserScan.msg +++ /dev/null @@ -1,30 +0,0 @@ -# Single scan from a planar laser range-finder -# -# If you have another ranging device with different behavior (e.g. a sonar -# array), please find or create a different message, since applications -# will make fairly laser-specific assumptions about this data - -std_msgs/Header header # timestamp in the header is the acquisition time of - # the first ray in the scan. - # - # in frame frame_id, angles are measured around - # the positive Z axis (counterclockwise, if Z is up) - # with zero angle being forward along the x axis - -float32 angle_min # start angle of the scan [rad] -float32 angle_max # end angle of the scan [rad] -float32 angle_increment # angular distance between measurements [rad] - -float32 time_increment # time between measurements [seconds] - if your scanner - # is moving, this will be used in interpolating position - # of 3d points -float32 scan_time # time between scans [seconds] - -float32 range_min # minimum range value [m] -float32 range_max # maximum range value [m] - -float32[] ranges # range data [m] - # (Note: values < range_min or > range_max should be discarded) -float32[] intensities # intensity data [device-specific units]. If your - # device does not provide intensities, please leave - # the array empty. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg deleted file mode 100644 index a0468fa7c21..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/MagneticField.msg +++ /dev/null @@ -1,21 +0,0 @@ -# Measurement of the Magnetic Field vector at a specific location. -# -# If the covariance of the measurement is known, it should be filled in. -# If all you know is the variance of each measurement, e.g. from the datasheet, -# just put those along the diagonal. -# A covariance matrix of all zeros will be interpreted as "covariance unknown", -# and to use the data a covariance will have to be assumed or gotten from some -# other source. - -std_msgs/Header header # timestamp is the time the - # field was measured - # frame_id is the location and orientation - # of the field measurement - -geometry_msgs/Vector3 magnetic_field # x, y, and z components of the - # field vector in Tesla - # If your sensor does not output 3 axes, - # put NaNs in the components not reported. - -float64[9] magnetic_field_covariance # Row major about x, y, z axes - # 0 is interpreted as variance unknown \ No newline at end of file diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg deleted file mode 100644 index 59edcefbb17..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/MultiDOFJointState.msg +++ /dev/null @@ -1,26 +0,0 @@ -# Representation of state for joints with multiple degrees of freedom, -# following the structure of JointState which can only represent a single degree of freedom. -# -# It is assumed that a joint in a system corresponds to a transform that gets applied -# along the kinematic chain. For example, a planar joint (as in URDF) is 3DOF (x, y, yaw) -# and those 3DOF can be expressed as a transformation matrix, and that transformation -# matrix can be converted back to (x, y, yaw) -# -# Each joint is uniquely identified by its name -# The header specifies the time at which the joint states were recorded. All the joint states -# in one message have to be recorded at the same time. -# -# This message consists of a multiple arrays, one for each part of the joint state. -# The goal is to make each of the fields optional. When e.g. your joints have no -# wrench associated with them, you can leave the wrench array empty. -# -# All arrays in this message should have the same size, or be empty. -# This is the only way to uniquely associate the joint name with the correct -# states. - -std_msgs/Header header - -string[] joint_names -geometry_msgs/Transform[] transforms -geometry_msgs/Twist[] twist -geometry_msgs/Wrench[] wrench diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg deleted file mode 100644 index 47d1b9f7169..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/MultiEchoLaserScan.msg +++ /dev/null @@ -1,32 +0,0 @@ -# Single scan from a multi-echo planar laser range-finder -# -# If you have another ranging device with different behavior (e.g. a sonar -# array), please find or create a different message, since applications -# will make fairly laser-specific assumptions about this data - -std_msgs/Header header # timestamp in the header is the acquisition time of - # the first ray in the scan. - # - # in frame frame_id, angles are measured around - # the positive Z axis (counterclockwise, if Z is up) - # with zero angle being forward along the x axis - -float32 angle_min # start angle of the scan [rad] -float32 angle_max # end angle of the scan [rad] -float32 angle_increment # angular distance between measurements [rad] - -float32 time_increment # time between measurements [seconds] - if your scanner - # is moving, this will be used in interpolating position - # of 3d points -float32 scan_time # time between scans [seconds] - -float32 range_min # minimum range value [m] -float32 range_max # maximum range value [m] - -LaserEcho[] ranges # range data [m] - # (Note: NaNs, values < range_min or > range_max should be discarded) - # +Inf measurements are out of range - # -Inf measurements are too close to determine exact distance. -LaserEcho[] intensities # intensity data [device-specific units]. If your - # device does not provide intensities, please leave - # the array empty. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg deleted file mode 100644 index 3c4e9770a5d..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatFix.msg +++ /dev/null @@ -1,45 +0,0 @@ -# Navigation Satellite fix for any Global Navigation Satellite System -# -# Specified using the WGS 84 reference ellipsoid - -# header.stamp specifies the ROS time for this measurement (the -# corresponding satellite time may be reported using the -# sensor_msgs/TimeReference message). -# -# header.frame_id is the frame of reference reported by the satellite -# receiver, usually the location of the antenna. This is a -# Euclidean frame relative to the vehicle, not a reference -# ellipsoid. -std_msgs/Header header - -# Satellite fix status information. -NavSatStatus status - -# Latitude [degrees]. Positive is north of equator; negative is south. -float64 latitude - -# Longitude [degrees]. Positive is east of prime meridian; negative is west. -float64 longitude - -# Altitude [m]. Positive is above the WGS 84 ellipsoid -# (quiet NaN if no altitude is available). -float64 altitude - -# Position covariance [m^2] defined relative to a tangential plane -# through the reported position. The components are East, North, and -# Up (ENU), in row-major order. -# -# Beware: this coordinate system exhibits singularities at the poles. -float64[9] position_covariance - -# If the covariance of the fix is known, fill it in completely. If the -# GPS receiver provides the variance of each measurement, put them -# along the diagonal. If only Dilution of Precision is available, -# estimate an approximate covariance from that. - -uint8 COVARIANCE_TYPE_UNKNOWN = 0 -uint8 COVARIANCE_TYPE_APPROXIMATED = 1 -uint8 COVARIANCE_TYPE_DIAGONAL_KNOWN = 2 -uint8 COVARIANCE_TYPE_KNOWN = 3 - -uint8 position_covariance_type diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg deleted file mode 100644 index ae03056d82a..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/NavSatStatus.msg +++ /dev/null @@ -1,24 +0,0 @@ -# Navigation Satellite fix status for any Global Navigation Satellite System. -# -# Whether to output an augmented fix is determined by both the fix -# type and the last time differential corrections were received. A -# fix is valid when status >= STATUS_FIX. - -int8 STATUS_UNKNOWN = -2 # status is not yet set -int8 STATUS_NO_FIX = -1 # unable to fix position -int8 STATUS_FIX = 0 # unaugmented fix -int8 STATUS_SBAS_FIX = 1 # with satellite-based augmentation -int8 STATUS_GBAS_FIX = 2 # with ground-based augmentation - -int8 status -2 # STATUS_UNKNOWN - -# Bits defining which Global Navigation Satellite System signals were -# used by the receiver. - -uint16 SERVICE_UNKNOWN = 0 # Remember service is a bitfield, so checking (service & SERVICE_UNKNOWN) will not work. Use == instead. -uint16 SERVICE_GPS = 1 -uint16 SERVICE_GLONASS = 2 -uint16 SERVICE_COMPASS = 4 # includes BeiDou. -uint16 SERVICE_GALILEO = 8 - -uint16 service diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg deleted file mode 100644 index a07d45048e6..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud.msg +++ /dev/null @@ -1,17 +0,0 @@ -## THIS MESSAGE IS DEPRECATED AS OF FOXY -## Please use sensor_msgs/PointCloud2 - -# This message holds a collection of 3d points, plus optional additional -# information about each point. - -# Time of sensor data acquisition, coordinate frame ID. -std_msgs/Header header - -# Array of 3d points. Each Point32 should be interpreted as a 3d point -# in the frame given in the header. -geometry_msgs/Point32[] points - -# Each channel should have the same number of elements as points array, -# and the data in each channel should correspond 1:1 with each point. -# Channel names in common practice are listed in ChannelFloat32.msg. -ChannelFloat32[] channels diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg deleted file mode 100644 index 0b27897ec7c..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/PointCloud2.msg +++ /dev/null @@ -1,26 +0,0 @@ -# This message holds a collection of N-dimensional points, which may -# contain additional information such as normals, intensity, etc. The -# point data is stored as a binary blob, its layout described by the -# contents of the "fields" array. -# -# The point cloud data may be organized 2d (image-like) or 1d (unordered). -# Point clouds organized as 2d images may be produced by camera depth sensors -# such as stereo or time-of-flight. - -# Time of sensor data acquisition, and the coordinate frame ID (for 3d points). -std_msgs/Header header - -# 2D structure of the point cloud. If the cloud is unordered, height is -# 1 and width is the length of the point cloud. -uint32 height -uint32 width - -# Describes the channels and their layout in the binary data blob. -PointField[] fields - -bool is_bigendian # Is this data bigendian? -uint32 point_step # Length of a point in bytes -uint32 row_step # Length of a row in bytes -uint8[] data # Actual point data, size is (row_step*height) - -bool is_dense # True if there are no invalid points diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg deleted file mode 100644 index 920bc4dd6c7..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/PointField.msg +++ /dev/null @@ -1,16 +0,0 @@ -# This message holds the description of one point entry in the -# PointCloud2 message format. -uint8 INT8 = 1 -uint8 UINT8 = 2 -uint8 INT16 = 3 -uint8 UINT16 = 4 -uint8 INT32 = 5 -uint8 UINT32 = 6 -uint8 FLOAT32 = 7 -uint8 FLOAT64 = 8 - -# Common PointField names are x, y, z, intensity, rgb, rgba -string name # Name of field -uint32 offset # Offset from start of point struct -uint8 datatype # Datatype enumeration, see above -uint32 count # How many elements in the field diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg deleted file mode 100644 index ed3a93b0661..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/Range.msg +++ /dev/null @@ -1,42 +0,0 @@ -# Single range reading from an active ranger that emits energy and reports -# one range reading that is valid along an arc at the distance measured. -# This message is not appropriate for laser scanners. See the LaserScan -# message if you are working with a laser scanner. -# -# This message also can represent a fixed-distance (binary) ranger. This -# sensor will have min_range===max_range===distance of detection. -# These sensors follow REP 117 and will output -Inf if the object is detected -# and +Inf if the object is outside of the detection range. - -std_msgs/Header header # timestamp in the header is the time the ranger - # returned the distance reading - -# Radiation type enums -# If you want a value added to this list, send an email to the ros-users list -uint8 ULTRASOUND=0 -uint8 INFRARED=1 - -uint8 radiation_type # the type of radiation used by the sensor - # (sound, IR, etc) [enum] - -float32 field_of_view # the size of the arc that the distance reading is - # valid for [rad] - # the object causing the range reading may have - # been anywhere within -field_of_view/2 and - # field_of_view/2 at the measured range. - # 0 angle corresponds to the x-axis of the sensor. - -float32 min_range # minimum range value [m] -float32 max_range # maximum range value [m] - # Fixed distance rangers require min_range==max_range - -float32 range # range data [m] - # (Note: values < range_min or > range_max should be discarded) - # Fixed distance rangers only output -Inf or +Inf. - # -Inf represents a detection within fixed distance. - # (Detection too close to the sensor to quantify) - # +Inf represents no detection within the fixed distance. - # (Object out of range) - -float32 variance # variance of the range sensor - # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg deleted file mode 100644 index c423dcf8895..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/RegionOfInterest.msg +++ /dev/null @@ -1,19 +0,0 @@ -# This message is used to specify a region of interest within an image. -# -# When used to specify the ROI setting of the camera when the image was -# taken, the height and width fields should either match the height and -# width fields for the associated image; or height = width = 0 -# indicates that the full resolution image was captured. - -uint32 x_offset # Leftmost pixel of the ROI - # (0 if the ROI includes the left edge of the image) -uint32 y_offset # Topmost pixel of the ROI - # (0 if the ROI includes the top edge of the image) -uint32 height # Height of ROI -uint32 width # Width of ROI - -# True if a distinct rectified ROI should be calculated from the "raw" -# ROI in this message. Typically this should be False if the full image -# is captured (ROI not used), and True if a subwindow is captured (ROI -# used). -bool do_rectify diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg deleted file mode 100644 index b32398f81e8..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/RelativeHumidity.msg +++ /dev/null @@ -1,13 +0,0 @@ -# Single reading from a relative humidity sensor. -# Defines the ratio of partial pressure of water vapor to the saturated vapor -# pressure at a temperature. - -std_msgs/Header header # timestamp of the measurement - # frame_id is the location of the humidity sensor - -float64 relative_humidity # Expression of the relative humidity - # from 0.0 to 1.0. - # 0.0 is no partial pressure of water vapor - # 1.0 represents partial pressure of saturation - -float64 variance # 0 is interpreted as variance unknown diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg deleted file mode 100644 index ca992850b0e..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/Temperature.msg +++ /dev/null @@ -1,8 +0,0 @@ -# Single temperature reading. - -std_msgs/Header header # timestamp is the time the temperature was measured - # frame_id is the location of the temperature reading - -float64 temperature # Measurement of the Temperature in Degrees Celsius. - -float64 variance # 0 is interpreted as variance unknown. diff --git a/dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg b/dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg deleted file mode 100644 index 6f93c0e2b38..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/msg/TimeReference.msg +++ /dev/null @@ -1,7 +0,0 @@ -# Measurement from an external time source not actively synchronized with the system clock. - -std_msgs/Header header # stamp is system time for which measurement was valid - # frame_id is not used - -builtin_interfaces/Time time_ref # corresponding time from this external source -string source # (optional) name of time source diff --git a/dimos/message_codegen/schemas/sensor_msgs/package.xml b/dimos/message_codegen/schemas/sensor_msgs/package.xml deleted file mode 100644 index bfab23e6112..00000000000 --- a/dimos/message_codegen/schemas/sensor_msgs/package.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - sensor_msgs - 5.3.8 - A package containing some sensor data related message and service definitions. - - Tully Foote - - Apache License 2.0 - - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - William Woodall - - ament_cmake - - rosidl_default_generators - - builtin_interfaces - geometry_msgs - std_msgs - - rosidl_default_runtime - - ament_cmake_gtest - ament_lint_auto - ament_lint_common - rosidl_cmake - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/shape_msgs/LICENSE b/dimos/message_codegen/schemas/shape_msgs/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/shape_msgs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg b/dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg deleted file mode 100644 index 2c3b0d03df2..00000000000 --- a/dimos/message_codegen/schemas/shape_msgs/msg/Mesh.msg +++ /dev/null @@ -1,7 +0,0 @@ -# Definition of a mesh. - -# List of triangles; the index values refer to positions in vertices[]. -MeshTriangle[] triangles - -# The actual vertices that make up the mesh. -geometry_msgs/Point[] vertices diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg b/dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg deleted file mode 100644 index 9de74df9b0f..00000000000 --- a/dimos/message_codegen/schemas/shape_msgs/msg/MeshTriangle.msg +++ /dev/null @@ -1,3 +0,0 @@ -# Definition of a triangle's vertices. - -uint32[3] vertex_indices diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg b/dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg deleted file mode 100644 index 9d8a43a8459..00000000000 --- a/dimos/message_codegen/schemas/shape_msgs/msg/Plane.msg +++ /dev/null @@ -1,7 +0,0 @@ -# Representation of a plane, using the plane equation ax + by + cz + d = 0. -# -# a := coef[0] -# b := coef[1] -# c := coef[2] -# d := coef[3] -float64[4] coef diff --git a/dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg b/dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg deleted file mode 100644 index b9014ad75d2..00000000000 --- a/dimos/message_codegen/schemas/shape_msgs/msg/SolidPrimitive.msg +++ /dev/null @@ -1,50 +0,0 @@ -# Defines box, sphere, cylinder, cone and prism. -# All shapes are defined to have their bounding boxes centered around 0,0,0. - -uint8 BOX=1 -uint8 SPHERE=2 -uint8 CYLINDER=3 -uint8 CONE=4 -uint8 PRISM=5 - -# The type of the shape -uint8 type - -# The dimensions of the shape -float64[<=3] dimensions # At no point will dimensions have a length > 3. - -# The meaning of the shape dimensions: each constant defines the index in the 'dimensions' array. - -# For type BOX, the X, Y, and Z dimensions are the length of the corresponding sides of the box. -uint8 BOX_X=0 -uint8 BOX_Y=1 -uint8 BOX_Z=2 - -# For the SPHERE type, only one component is used, and it gives the radius of the sphere. -uint8 SPHERE_RADIUS=0 - -# For the CYLINDER and CONE types, the center line is oriented along the Z axis. -# Therefore the CYLINDER_HEIGHT (CONE_HEIGHT) component of dimensions gives the -# height of the cylinder (cone). -# The CYLINDER_RADIUS (CONE_RADIUS) component of dimensions gives the radius of -# the base of the cylinder (cone). -# Cone and cylinder primitives are defined to be circular. The tip of the cone -# is pointing up, along +Z axis. - -uint8 CYLINDER_HEIGHT=0 -uint8 CYLINDER_RADIUS=1 - -uint8 CONE_HEIGHT=0 -uint8 CONE_RADIUS=1 - -# For the type PRISM, the center line is oriented along Z axis. -# The PRISM_HEIGHT component of dimensions gives the -# height of the prism. -# The polygon defines the Z axis centered base of the prism. -# The prism is constructed by extruding the base in +Z and -Z -# directions by half of the PRISM_HEIGHT -# Only x and y fields of the points are used in the polygon. -# Points of the polygon are ordered counter-clockwise. - -uint8 PRISM_HEIGHT=0 -geometry_msgs/Polygon polygon diff --git a/dimos/message_codegen/schemas/shape_msgs/package.xml b/dimos/message_codegen/schemas/shape_msgs/package.xml deleted file mode 100644 index 43cd5cd3968..00000000000 --- a/dimos/message_codegen/schemas/shape_msgs/package.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - shape_msgs - 5.3.8 - A package containing some message definitions which describe geometric shapes. - - Tully Foote - - Apache License 2.0 - - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - William Woodall - - ament_cmake - - rosidl_default_generators - - geometry_msgs - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/std_msgs/LICENSE b/dimos/message_codegen/schemas/std_msgs/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Bool.msg b/dimos/message_codegen/schemas/std_msgs/msg/Bool.msg deleted file mode 100644 index ffd399ea7eb..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Bool.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -bool data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Byte.msg b/dimos/message_codegen/schemas/std_msgs/msg/Byte.msg deleted file mode 100644 index 400d445c18a..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Byte.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -byte data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg deleted file mode 100644 index ac6ce0c8c75..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/ByteMultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -byte[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Char.msg b/dimos/message_codegen/schemas/std_msgs/msg/Char.msg deleted file mode 100644 index eb3abbf6f86..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Char.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -char data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg b/dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg deleted file mode 100644 index 182dbc8349a..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/ColorRGBA.msg +++ /dev/null @@ -1,4 +0,0 @@ -float32 r -float32 g -float32 b -float32 a diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Empty.msg b/dimos/message_codegen/schemas/std_msgs/msg/Empty.msg deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float32.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float32.msg deleted file mode 100644 index ed3fc9d23a7..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Float32.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -float32 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg deleted file mode 100644 index 82a85ae3ae7..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Float32MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -float32[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float64.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float64.msg deleted file mode 100644 index 9f78c835392..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Float64.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -float64 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg deleted file mode 100644 index 43d7ab7378b..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Float64MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -float64[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Header.msg b/dimos/message_codegen/schemas/std_msgs/msg/Header.msg deleted file mode 100644 index 6966bb98863..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Header.msg +++ /dev/null @@ -1,9 +0,0 @@ -# Standard metadata for higher-level stamped data types. -# This is generally used to communicate timestamped data -# in a particular coordinate frame. - -# Two-integer timestamp that is expressed as seconds and nanoseconds. -builtin_interfaces/Time stamp - -# Transform frame with which this data is associated. -string frame_id diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int16.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int16.msg deleted file mode 100644 index 31429678cff..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int16.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -int16 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg deleted file mode 100644 index db6f56b78a0..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int16MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -int16[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int32.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int32.msg deleted file mode 100644 index e4dc836038e..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int32.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -int32 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg deleted file mode 100644 index 67c5f40f5bb..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int32MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -int32[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int64.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int64.msg deleted file mode 100644 index fbc143a7dcb..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int64.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -int64 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg deleted file mode 100644 index ea34ee81d5b..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int64MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -int64[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int8.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int8.msg deleted file mode 100644 index d44e8cbb116..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int8.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -int8 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg deleted file mode 100644 index 8ab6b543e8b..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/Int8MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -int8[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg b/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg deleted file mode 100644 index ab0376b4fc5..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayDimension.msg +++ /dev/null @@ -1,8 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -string label # label of given dimension -uint32 size # size of given dimension (in type units) -uint32 stride # stride of given dimension diff --git a/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg b/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg deleted file mode 100644 index 06f2fea3de3..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/MultiArrayLayout.msg +++ /dev/null @@ -1,31 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# The multiarray declares a generic multi-dimensional array of a -# particular data type. Dimensions are ordered from outer most -# to inner most. -# -# Accessors should ALWAYS be written in terms of dimension stride -# and specified outer-most dimension first. -# -# multiarray(i,j,k) = data[data_offset + dim_stride[1]*i + dim_stride[2]*j + k] -# -# A standard, 3-channel 640x480 image with interleaved color channels -# would be specified as: -# -# dim[0].label = "height" -# dim[0].size = 480 -# dim[0].stride = 3*640*480 = 921600 (note dim[0] stride is just size of image) -# dim[1].label = "width" -# dim[1].size = 640 -# dim[1].stride = 3*640 = 1920 -# dim[2].label = "channel" -# dim[2].size = 3 -# dim[2].stride = 3 -# -# multiarray(i,j,k) refers to the ith row, jth column, and kth channel. - -MultiArrayDimension[] dim # Array of dimension properties -uint32 data_offset # padding bytes at front of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/String.msg b/dimos/message_codegen/schemas/std_msgs/msg/String.msg deleted file mode 100644 index 82c18e55326..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/String.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -string data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg deleted file mode 100644 index 6e0c9054223..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt16.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -uint16 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg deleted file mode 100644 index cb51b70447c..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt16MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -uint16[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg deleted file mode 100644 index 5723cbc8edf..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt32.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -uint32 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg deleted file mode 100644 index 6750d1803ed..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt32MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -uint32[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg deleted file mode 100644 index 330cab9830d..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt64.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -uint64 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg deleted file mode 100644 index e5dc3f8ebd1..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt64MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -uint64[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg deleted file mode 100644 index f04b64f3d17..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt8.msg +++ /dev/null @@ -1,6 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -uint8 data diff --git a/dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg b/dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg deleted file mode 100644 index 74b3825b60f..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/msg/UInt8MultiArray.msg +++ /dev/null @@ -1,10 +0,0 @@ -# This was originally provided as an example message. -# It is deprecated as of Foxy -# It is recommended to create your own semantically meaningful message. -# However if you would like to continue using this please use the equivalent in example_msgs. - -# Please look at the MultiArrayLayout message definition for -# documentation on all multiarrays. - -MultiArrayLayout layout # specification of data layout -uint8[] data # array of data diff --git a/dimos/message_codegen/schemas/std_msgs/package.xml b/dimos/message_codegen/schemas/std_msgs/package.xml deleted file mode 100644 index 5b586c7ab24..00000000000 --- a/dimos/message_codegen/schemas/std_msgs/package.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - std_msgs - 5.3.8 - A package containing some standard message definitions. - - Tully Foote - - Apache License 2.0 - - Dirk Thomas - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - - ament_cmake - - rosidl_default_generators - - builtin_interfaces - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg b/dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg deleted file mode 100644 index e737b64698f..00000000000 --- a/dimos/message_codegen/schemas/tf2_msgs/msg/TF2Error.msg +++ /dev/null @@ -1,10 +0,0 @@ -uint8 NO_ERROR = 0 -uint8 LOOKUP_ERROR = 1 -uint8 CONNECTIVITY_ERROR = 2 -uint8 EXTRAPOLATION_ERROR = 3 -uint8 INVALID_ARGUMENT_ERROR = 4 -uint8 TIMEOUT_ERROR = 5 -uint8 TRANSFORM_ERROR = 6 - -uint8 error -string error_string diff --git a/dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg b/dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg deleted file mode 100644 index fda1e4d0985..00000000000 --- a/dimos/message_codegen/schemas/tf2_msgs/msg/TFMessage.msg +++ /dev/null @@ -1 +0,0 @@ -geometry_msgs/TransformStamped[] transforms diff --git a/dimos/message_codegen/schemas/tf2_msgs/package.xml b/dimos/message_codegen/schemas/tf2_msgs/package.xml deleted file mode 100644 index 17f6b9bdb88..00000000000 --- a/dimos/message_codegen/schemas/tf2_msgs/package.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - tf2_msgs - 0.36.23 - - tf2_msgs - - - Alejandro Hernandez Cordero - Chris Lalancette - - BSD - http://www.ros.org/wiki/tf2_msgs - - Eitan Marder-Eppstein - Tully Foote - - ament_cmake - rosidl_default_generators - - builtin_interfaces - geometry_msgs - - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - - - diff --git a/dimos/message_codegen/schemas/trajectory_msgs/LICENSE b/dimos/message_codegen/schemas/trajectory_msgs/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/trajectory_msgs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg deleted file mode 100644 index a5d219880f7..00000000000 --- a/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectory.msg +++ /dev/null @@ -1,11 +0,0 @@ -# The header is used to specify the coordinate frame and the reference time for -# the trajectory durations -std_msgs/Header header - -# The names of the active joints in each trajectory point. These names are -# ordered and must correspond to the values in each trajectory point. -string[] joint_names - -# Array of trajectory points, which describe the positions, velocities, -# accelerations and/or efforts of the joints at each time point. -JointTrajectoryPoint[] points diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg deleted file mode 100644 index 01e38a4562e..00000000000 --- a/dimos/message_codegen/schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg +++ /dev/null @@ -1,26 +0,0 @@ -# Each trajectory point specifies either positions[, velocities[, accelerations]] -# or positions[, effort] for the trajectory to be executed. -# All specified values are in the same order as the joint names in JointTrajectory.msg. - -# Single DOF joint positions for each joint relative to their "0" position. -# The units depend on the specific joint type: radians for revolute or -# continuous joints, and meters for prismatic joints. -float64[] positions - -# The rate of change in position of each joint. Units are joint type dependent. -# Radians/second for revolute or continuous joints, and meters/second for -# prismatic joints. -float64[] velocities - -# Rate of change in velocity of each joint. Units are joint type dependent. -# Radians/second^2 for revolute or continuous joints, and meters/second^2 for -# prismatic joints. -float64[] accelerations - -# The torque or the force to be applied at each joint. For revolute/continuous -# joints effort denotes a torque in newton-meters. For prismatic joints, effort -# denotes a force in newtons. -float64[] effort - -# Desired time from the trajectory start to arrive at this trajectory point. -builtin_interfaces/Duration time_from_start diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg deleted file mode 100644 index 155fdddf0b8..00000000000 --- a/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg +++ /dev/null @@ -1,10 +0,0 @@ -# The header is used to specify the coordinate frame and the reference time for the trajectory durations -std_msgs/Header header - -# A representation of a multi-dof joint trajectory (each point is a transformation) -# Each point along the trajectory will include an array of positions/velocities/accelerations -# that has the same length as the array of joint names, and has the same order of joints as -# the joint names array. - -string[] joint_names -MultiDOFJointTrajectoryPoint[] points diff --git a/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg b/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg deleted file mode 100644 index b5f6457f182..00000000000 --- a/dimos/message_codegen/schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg +++ /dev/null @@ -1,11 +0,0 @@ -# Each multi-dof joint can specify a transform (up to 6 DOF). -geometry_msgs/Transform[] transforms - -# There can be a velocity specified for the origin of the joint. -geometry_msgs/Twist[] velocities - -# There can be an acceleration specified for the origin of the joint. -geometry_msgs/Twist[] accelerations - -# Desired time from the trajectory start to arrive at this trajectory point. -builtin_interfaces/Duration time_from_start diff --git a/dimos/message_codegen/schemas/trajectory_msgs/package.xml b/dimos/message_codegen/schemas/trajectory_msgs/package.xml deleted file mode 100644 index b1a8ce6f0f7..00000000000 --- a/dimos/message_codegen/schemas/trajectory_msgs/package.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - trajectory_msgs - 5.3.8 - A package containing some robot trajectory message definitions. - - Tully Foote - - Apache License 2.0 - - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - William Woodall - - ament_cmake - - rosidl_default_generators - - builtin_interfaces - geometry_msgs - std_msgs - - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg deleted file mode 100644 index 1f9152d4f15..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2D.msg +++ /dev/null @@ -1,13 +0,0 @@ -# A 2D bounding box that can be rotated about its center. -# All dimensions are in pixels, but represented using floating-point -# values to allow sub-pixel precision. If an exact pixel crop is required -# for a rotated bounding box, it can be calculated using Bresenham's line -# algorithm. - -# The 2D position (in pixels) and orientation of the bounding box center. -vision_msgs/Pose2D center - -# The total size (in pixels) of the bounding box surrounding the object relative -# to the pose of its center. -float64 size_x -float64 size_y diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg deleted file mode 100644 index 31bd42f6c79..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox2DArray.msg +++ /dev/null @@ -1,2 +0,0 @@ -std_msgs/Header header -vision_msgs/BoundingBox2D[] boxes diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg deleted file mode 100644 index cb8f49da3c8..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3D.msg +++ /dev/null @@ -1,10 +0,0 @@ -# A 3D bounding box that can be positioned and rotated about its center (6 DOF) -# Dimensions of this box are in meters, and as such, it may be migrated to -# another package, such as geometry_msgs, in the future. - -# The 3D position and orientation of the bounding box center -geometry_msgs/Pose center - -# The total size of the bounding box, in meters, surrounding the object's center -# pose. -geometry_msgs/Vector3 size diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg deleted file mode 100644 index c998e699dd4..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/BoundingBox3DArray.msg +++ /dev/null @@ -1,2 +0,0 @@ -std_msgs/Header header -vision_msgs/BoundingBox3D[] boxes \ No newline at end of file diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg deleted file mode 100644 index ec1404c3a44..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Classification.msg +++ /dev/null @@ -1,17 +0,0 @@ -# Defines a classification result. -# -# This result does not contain any position information. It is designed for -# classifiers, which simply provide class probabilities given an instance of -# source data (e.g., an image or a point cloud). - -std_msgs/Header header - -# A list of class probabilities. This list need not provide a probability for -# every possible class, just ones that are nonzero, or above some -# user-defined threshold. -ObjectHypothesis[] results - -# Source data that generated this classification are not a part of the message. -# If you need to access them, use an exact or approximate time synchronizer in -# your code, as this message's header should match the header of the source -# data. diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg deleted file mode 100644 index c2eb7f41493..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Detection2D.msg +++ /dev/null @@ -1,23 +0,0 @@ -# Defines a 2D detection result. -# -# This is similar to a 2D classification, but includes position information, -# allowing a classification result for a specific crop or image point to -# to be located in the larger image. - -std_msgs/Header header - -# Class probabilities -ObjectHypothesisWithPose[] results - -# 2D bounding box surrounding the object. -BoundingBox2D bbox - -# ID used for consistency across multiple detection messages. Detections -# of the same object in different detection messages should have the same id. -# This field may be empty. -string id - -# Source data that generated this detection are not a part of the message. -# If you need to access them, use an exact or approximate time synchronizer in -# your code, as this message's header should match the header of the source -# data. diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg deleted file mode 100644 index 7d05be04092..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Detection2DArray.msg +++ /dev/null @@ -1,7 +0,0 @@ -# A list of 2D detections, for a multi-object 2D detector. - -std_msgs/Header header - -# A list of the detected proposals. A multi-proposal detector might generate -# this list with many candidate detections generated from a single input. -Detection2D[] detections diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg deleted file mode 100644 index bed3f72691d..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Detection3D.msg +++ /dev/null @@ -1,23 +0,0 @@ -# Defines a 3D detection result. -# -# This extends a basic 3D classification by including the pose of the -# detected object. - -std_msgs/Header header - -# Class probabilities. Does not have to include hypotheses for all possible -# object ids, the scores for any ids not listed are assumed to be 0. -ObjectHypothesisWithPose[] results - -# 3D bounding box surrounding the object. -BoundingBox3D bbox - -# ID used for consistency across multiple detection messages. Detections -# of the same object in different detection messages should have the same id. -# This field may be empty. -string id - -# Source data that generated this classification are not a part of the message. -# If you need to access them, use an exact or approximate time synchronizer in -# your code, as this message's header should match the header of the source -# data. diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg deleted file mode 100644 index b3d3011a82e..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Detection3DArray.msg +++ /dev/null @@ -1,7 +0,0 @@ -# A list of 3D detections, for a multi-object 3D detector. - -std_msgs/Header header - -# A list of the detected proposals. A multi-proposal detector might generate -# this list with many candidate detections generated from a single input. -Detection3D[] detections diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg b/dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg deleted file mode 100644 index d73a3c5e529..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/LabelInfo.msg +++ /dev/null @@ -1,25 +0,0 @@ -# Provides meta-information about a visual pipeline. -# -# This message serves a similar purpose to sensor_msgs/CameraInfo, but instead -# of being tied to hardware, it represents information about a specific -# computer vision pipeline. This information stays constant (or relatively -# constant) over time, and so it is wasteful to send it with each individual -# result. By listening to these messages, subscribers will receive -# the context in which published vision messages are to be interpreted. -# Each vision pipeline should publish its LabelInfo messages to its own topic, -# in a manner similar to CameraInfo. -# This message is meant to allow converting data from vision pipelines that -# return id based classifications back to human readable string class names. - -# Used for sequencing -std_msgs/Header header - -# An array of uint16 keys and string values containing the association -# between class identifiers and their names. According to the amount -# of classes and the datatype used to store their ids internally, the -# maxiumum class id allowed (65535 for uint16 and 255 for uint8) belongs to -# the "UNLABELED" class. -vision_msgs/VisionClass[] class_map - -# The value between 0-1 used as confidence threshold for the inference. -float32 threshold diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg b/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg deleted file mode 100644 index e6716e83bfe..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesis.msg +++ /dev/null @@ -1,12 +0,0 @@ -# An object hypothesis that contains no pose information. -# If you would like to define an array of ObjectHypothesis messages, -# please see the Classification message type. - -# The unique ID of the object class. To get additional information about -# this ID, such as its human-readable class name, listeners should perform a -# lookup in a metadata database. See vision_msgs/VisionInfo.msg for more detail. -string class_id - -# The probability or confidence value of the detected object. By convention, -# this value should lie in the range [0-1]. -float64 score diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg b/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg deleted file mode 100644 index bc6c6e8b0ce..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg +++ /dev/null @@ -1,16 +0,0 @@ -# An object hypothesis that contains pose information. -# If you would like to define an array of ObjectHypothesisWithPose messages, -# please see the Detection2D or Detection3D message types. - -# The object hypothesis (ID and score). -ObjectHypothesis hypothesis - -# The 6D pose of the object hypothesis. This pose should be -# defined as the pose of some fixed reference point on the object, such as -# the geometric center of the bounding box, the center of mass of the -# object or the origin of a reference mesh of the object. -# Note that this pose is not stamped; frame information can be defined by -# parent messages. -# Also note that different classes predicted for the same input data may have -# different predicted 6D poses. -geometry_msgs/PoseWithCovariance pose diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg deleted file mode 100644 index 01455417ab5..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Point2D.msg +++ /dev/null @@ -1,5 +0,0 @@ -# Represents a 2D point in pixel coordinates. -# XY matches the sensor_msgs/Image convention: X is positive right and Y is positive down. - -float64 x -float64 y diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg b/dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg deleted file mode 100644 index 367dcec904e..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/Pose2D.msg +++ /dev/null @@ -1,4 +0,0 @@ -# Represents a 2D pose (coordinates and a radian rotation). Rotation is positive counterclockwise. - -vision_msgs/Point2D position -float64 theta diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg b/dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg deleted file mode 100644 index 93f2181b876..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/VisionClass.msg +++ /dev/null @@ -1,12 +0,0 @@ -# A key value pair that maps an integer class_id to a string class label -# in computer vision systems. - -# The int value that identifies the class. -# Elements identified with 65535, the maximum uint16 value are assumed -# to belong to the "UNLABELED" class. For vision pipelines using less -# than 255 classes the "UNLABELED" is the maximum value in the uint8 -# range. -uint16 class_id - -# The name of the class represented by the class_id -string class_name diff --git a/dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg b/dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg deleted file mode 100644 index 8058070997d..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/msg/VisionInfo.msg +++ /dev/null @@ -1,40 +0,0 @@ -# Provides meta-information about a visual pipeline. -# -# This message serves a similar purpose to sensor_msgs/CameraInfo, but instead -# of being tied to hardware, it represents information about a specific -# computer vision pipeline. This information stays constant (or relatively -# constant) over time, and so it is wasteful to send it with each individual -# result. By listening to these messages, subscribers will receive -# the context in which published vision messages are to be interpreted. -# Each vision pipeline should publish its VisionInfo messages to its own topic, -# in a manner similar to CameraInfo. - -# Used for sequencing -std_msgs/Header header - -# Name of the vision pipeline. This should be a value that is meaningful to an -# outside user. -string method - -# Location where the metadata database is stored. The recommended location is -# as an XML string on the ROS parameter server, but the exact implementation -# and information is left up to the user. -# The database should store information attached to class ids. Each -# class id should map to an atomic, visually recognizable element. This -# definition is intentionally vague to allow extreme flexibility. The -# elements could be classes in a pixel segmentation algorithm, object classes -# in a detector, different people's faces in a face detection algorithm, etc. -# Vision pipelines report results in terms of numeric IDs, which map into -# this database. -# The information stored in this database is, again, left up to the user. The -# database could be as simple as a map from ID to class name, or it could -# include information such as object meshes or colors to use for -# visualization. -string database_location - -# Metadata database version. This counter is incremented -# each time the pipeline begins using a new version of the database (useful -# in the case of online training or user modifications). -# The counter value can be monitored by listeners to ensure that the pipeline -# and the listener are using the same metadata. -int32 database_version \ No newline at end of file diff --git a/dimos/message_codegen/schemas/vision_msgs/package.xml b/dimos/message_codegen/schemas/vision_msgs/package.xml deleted file mode 100644 index 6f60ee86bfb..00000000000 --- a/dimos/message_codegen/schemas/vision_msgs/package.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - vision_msgs - 4.1.1 - - Messages for interfacing with various computer vision pipelines, such as - object detectors. - - - Adam Allevato - - Apache License 2.0 - - Adam Allevato - Adam Allevato - Apache License 2.0 - - ament_cmake - rosidl_default_generators - - std_msgs - geometry_msgs - - std_msgs - geometry_msgs - rosidl_default_runtime - - ament_cmake_gtest - ament_lint_auto - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/schemas/visualization_msgs/LICENSE b/dimos/message_codegen/schemas/visualization_msgs/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg deleted file mode 100644 index 2b9e64a6e5b..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/ImageMarker.msg +++ /dev/null @@ -1,36 +0,0 @@ -int32 CIRCLE=0 -int32 LINE_STRIP=1 -int32 LINE_LIST=2 -int32 POLYGON=3 -int32 POINTS=4 - -int32 ADD=0 -int32 REMOVE=1 - -std_msgs/Header header -# Namespace which is used with the id to form a unique id. -string ns -# Unique id within the namespace. -int32 id -# One of the above types, e.g. CIRCLE, LINE_STRIP, etc. -int32 type -# Either ADD or REMOVE. -int32 action -# Two-dimensional coordinate position, in pixel-coordinates. -geometry_msgs/Point position -# The scale of the object, e.g. the diameter for a CIRCLE. -float32 scale -# The outline color of the marker. -std_msgs/ColorRGBA outline_color -# Whether or not to fill in the shape with color. -uint8 filled -# Fill color; in the range: [0.0-1.0] -std_msgs/ColorRGBA fill_color -# How long the object should last before being automatically deleted. -# 0 indicates forever. -builtin_interfaces/Duration lifetime - -# Coordinates in 2D in pixel coords. Used for LINE_STRIP, LINE_LIST, POINTS, etc. -geometry_msgs/Point[] points -# The color for each line, point, etc. in the points field. -std_msgs/ColorRGBA[] outline_colors diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg deleted file mode 100644 index c2af8dc97a4..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarker.msg +++ /dev/null @@ -1,26 +0,0 @@ -# Time/frame info. -# If header.time is set to 0, the marker will be retransformed into -# its frame on each timestep. You will receive the pose feedback -# in the same frame. -# Otherwise, you might receive feedback in a different frame. -# For rviz, this will be the current 'fixed frame' set by the user. -std_msgs/Header header - -# Initial pose. Also, defines the pivot point for rotations. -geometry_msgs/Pose pose - -# Identifying string. Must be globally unique in -# the topic that this message is sent through. -string name - -# Short description (< 40 characters). -string description - -# Scale to be used for default controls (default=1). -float32 scale - -# All menu and submenu entries associated with this marker. -MenuEntry[] menu_entries - -# List of controls displayed for this marker. -InteractiveMarkerControl[] controls diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg deleted file mode 100644 index 10f88c809cc..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerControl.msg +++ /dev/null @@ -1,77 +0,0 @@ -# Represents a control that is to be displayed together with an interactive marker - -# Identifying string for this control. -# You need to assign a unique value to this to receive feedback from the GUI -# on what actions the user performs on this control (e.g. a button click). -string name - - -# Defines the local coordinate frame (relative to the pose of the parent -# interactive marker) in which is being rotated and translated. -# Default: Identity -geometry_msgs/Quaternion orientation - - -# Orientation mode: controls how orientation changes. -# INHERIT: Follow orientation of interactive marker -# FIXED: Keep orientation fixed at initial state -# VIEW_FACING: Align y-z plane with screen (x: forward, y:left, z:up). -uint8 INHERIT = 0 -uint8 FIXED = 1 -uint8 VIEW_FACING = 2 - -uint8 orientation_mode - -# Interaction mode for this control -# -# NONE: This control is only meant for visualization; no context menu. -# MENU: Like NONE, but right-click menu is active. -# BUTTON: Element can be left-clicked. -# MOVE_AXIS: Translate along local x-axis. -# MOVE_PLANE: Translate in local y-z plane. -# ROTATE_AXIS: Rotate around local x-axis. -# MOVE_ROTATE: Combines MOVE_PLANE and ROTATE_AXIS. -uint8 NONE = 0 -uint8 MENU = 1 -uint8 BUTTON = 2 -uint8 MOVE_AXIS = 3 -uint8 MOVE_PLANE = 4 -uint8 ROTATE_AXIS = 5 -uint8 MOVE_ROTATE = 6 -# "3D" interaction modes work with the mouse+SHIFT+CTRL or with 3D cursors. -# MOVE_3D: Translate freely in 3D space. -# ROTATE_3D: Rotate freely in 3D space about the origin of parent frame. -# MOVE_ROTATE_3D: Full 6-DOF freedom of translation and rotation about the cursor origin. -uint8 MOVE_3D = 7 -uint8 ROTATE_3D = 8 -uint8 MOVE_ROTATE_3D = 9 - -uint8 interaction_mode - - -# If true, the contained markers will also be visible -# when the gui is not in interactive mode. -bool always_visible - - -# Markers to be displayed as custom visual representation. -# Leave this empty to use the default control handles. -# -# Note: -# - The markers can be defined in an arbitrary coordinate frame, -# but will be transformed into the local frame of the interactive marker. -# - If the header of a marker is empty, its pose will be interpreted as -# relative to the pose of the parent interactive marker. -Marker[] markers - - -# In VIEW_FACING mode, set this to true if you don't want the markers -# to be aligned with the camera view point. The markers will show up -# as in INHERIT mode. -bool independent_marker_orientation - - -# Short description (< 40 characters) of what this control does, -# e.g. "Move the robot". -# Default: A generic description based on the interaction mode -string description diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg deleted file mode 100644 index 43c754c97eb..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg +++ /dev/null @@ -1,42 +0,0 @@ -# Time/frame info. -std_msgs/Header header - -# Identifying string. Must be unique in the topic namespace. -string client_id - -# Feedback message sent back from the GUI, e.g. -# when the status of an interactive marker was modified by the user. - -# Specifies which interactive marker and control this message refers to -string marker_name -string control_name - -# Type of the event -# KEEP_ALIVE: sent while dragging to keep up control of the marker -# MENU_SELECT: a menu entry has been selected -# BUTTON_CLICK: a button control has been clicked -# POSE_UPDATE: the pose has been changed using one of the controls -uint8 KEEP_ALIVE = 0 -uint8 POSE_UPDATE = 1 -uint8 MENU_SELECT = 2 -uint8 BUTTON_CLICK = 3 - -uint8 MOUSE_DOWN = 4 -uint8 MOUSE_UP = 5 - -uint8 event_type - -# Current pose of the marker -# Note: Has to be valid for all feedback types. -geometry_msgs/Pose pose - -# Contains the ID of the selected menu entry -# Only valid for MENU_SELECT events. -uint32 menu_entry_id - -# If event_type is BUTTON_CLICK, MOUSE_DOWN, or MOUSE_UP, mouse_point -# may contain the 3 dimensional position of the event on the -# control. If it does, mouse_point_valid will be true. mouse_point -# will be relative to the frame listed in the header. -geometry_msgs/Point mouse_point -bool mouse_point_valid diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg deleted file mode 100644 index d73bcd0480c..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerInit.msg +++ /dev/null @@ -1,14 +0,0 @@ -# Identifying string. Must be unique in the topic namespace -# that this server works on. -string server_id - -# Sequence number. -# The client will use this to detect if it has missed a subsequent -# update. Every update message will have the same sequence number as -# an init message. Clients will likely want to unsubscribe from the -# init topic after a successful initialization to avoid receiving -# duplicate data. -uint64 seq_num - -# All markers. -InteractiveMarker[] markers diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg deleted file mode 100644 index 04a22e9a7eb..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerPose.msg +++ /dev/null @@ -1,10 +0,0 @@ - -# Time/frame info. -std_msgs/Header header - -# Initial pose. Also, defines the pivot point for rotations. -geometry_msgs/Pose pose - -# Identifying string. Must be globally unique in -# the topic that this message is sent through. -string name diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg deleted file mode 100644 index 2070a03ae8b..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg +++ /dev/null @@ -1,32 +0,0 @@ - -# Identifying string. Must be unique in the topic namespace -# that this server works on. -string server_id - -# Sequence number. -# The client will use this to detect if it has missed an update. -uint64 seq_num - -# Type holds the purpose of this message. It must be one of UPDATE or KEEP_ALIVE. -# UPDATE: Incremental update to previous state. -# The sequence number must be 1 higher than for -# the previous update. -# KEEP_ALIVE: Indicates the that the server is still living. -# The sequence number does not increase. -# No payload data should be filled out (markers, poses, or erases). -uint8 KEEP_ALIVE = 0 -uint8 UPDATE = 1 - -uint8 type - -# Note: No guarantees on the order of processing. -# Contents must be kept consistent by sender. - -# Markers to be added or updated -InteractiveMarker[] markers - -# Poses of markers that should be moved -InteractiveMarkerPose[] poses - -# Names of markers to be erased -string[] erases diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg deleted file mode 100644 index eb9938a11a0..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/Marker.msg +++ /dev/null @@ -1,81 +0,0 @@ -# See: -# - http://www.ros.org/wiki/rviz/DisplayTypes/Marker -# - http://www.ros.org/wiki/rviz/Tutorials/Markers%3A%20Basic%20Shapes -# -# for more information on using this message with rviz. - -int32 ARROW=0 -int32 CUBE=1 -int32 SPHERE=2 -int32 CYLINDER=3 -int32 LINE_STRIP=4 -int32 LINE_LIST=5 -int32 CUBE_LIST=6 -int32 SPHERE_LIST=7 -int32 POINTS=8 -int32 TEXT_VIEW_FACING=9 -int32 MESH_RESOURCE=10 -int32 TRIANGLE_LIST=11 -int32 ARROW_STRIP=12 - -int32 ADD=0 -int32 MODIFY=0 -int32 DELETE=2 -int32 DELETEALL=3 - -# Header for timestamp and frame id. -std_msgs/Header header -# Namespace in which to place the object. -# Used in conjunction with id to create a unique name for the object. -string ns -# Object ID used in conjunction with the namespace for manipulating and deleting the object later. -int32 id -# Type of object. -int32 type -# Action to take; one of: -# - 0 add/modify an object -# - 1 (deprecated) -# - 2 deletes an object (with the given ns and id) -# - 3 deletes all objects (or those with the given ns if any) -int32 action -# Pose of the object with respect the frame_id specified in the header. -geometry_msgs/Pose pose -# Scale of the object; 1,1,1 means default (usually 1 meter square). -geometry_msgs/Vector3 scale -# Color of the object; in the range: [0.0-1.0] -std_msgs/ColorRGBA color -# How long the object should last before being automatically deleted. -# 0 indicates forever. -builtin_interfaces/Duration lifetime -# If this marker should be frame-locked, i.e. retransformed into its frame every timestep. -bool frame_locked - -# Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, ARROW_STRIP, etc.) -geometry_msgs/Point[] points -# Only used if the type specified has some use for them (eg. POINTS, LINE_STRIP, etc.) -# The number of colors provided must either be 0 or equal to the number of points provided. -# NOTE: alpha is not yet used -std_msgs/ColorRGBA[] colors - -# Texture resource is a special URI that can either reference a texture file in -# a format acceptable to (resource retriever)[https://docs.ros.org/en/rolling/p/resource_retriever/] -# or an embedded texture via a string matching the format: -# "embedded://texture_name" -string texture_resource -# An image to be loaded into the rendering engine as the texture for this marker. -# This will be used iff texture_resource is set to embedded. -sensor_msgs/CompressedImage texture -# Location of each vertex within the texture; in the range: [0.0-1.0] -UVCoordinate[] uv_coordinates - -# Only used for text markers -string text - -# Only used for MESH_RESOURCE markers. -# Similar to texture_resource, mesh_resource uses resource retriever to load a mesh. -# Optionally, a mesh file can be sent in-message via the mesh_file field. If doing so, -# use the following format for mesh_resource: -# "embedded://mesh_name" -string mesh_resource -MeshFile mesh_file -bool mesh_use_embedded_materials diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg deleted file mode 100644 index dd0fab432ab..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/MarkerArray.msg +++ /dev/null @@ -1 +0,0 @@ -Marker[] markers diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg deleted file mode 100644 index aee5720dbf6..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/MenuEntry.msg +++ /dev/null @@ -1,54 +0,0 @@ -# MenuEntry message. -# -# Each InteractiveMarker message has an array of MenuEntry messages. -# A collection of MenuEntries together describe a -# menu/submenu/subsubmenu/etc tree, though they are stored in a flat -# array. The tree structure is represented by giving each menu entry -# an ID number and a "parent_id" field. Top-level entries are the -# ones with parent_id = 0. Menu entries are ordered within their -# level the same way they are ordered in the containing array. Parent -# entries must appear before their children. -# -# Example: -# - id = 3 -# parent_id = 0 -# title = "fun" -# - id = 2 -# parent_id = 0 -# title = "robot" -# - id = 4 -# parent_id = 2 -# title = "pr2" -# - id = 5 -# parent_id = 2 -# title = "turtle" -# -# Gives a menu tree like this: -# - fun -# - robot -# - pr2 -# - turtle - -# ID is a number for each menu entry. Must be unique within the -# control, and should never be 0. -uint32 id - -# ID of the parent of this menu entry, if it is a submenu. If this -# menu entry is a top-level entry, set parent_id to 0. -uint32 parent_id - -# menu / entry title -string title - -# Arguments to command indicated by command_type (below) -string command - -# Command_type stores the type of response desired when this menu -# entry is clicked. -# FEEDBACK: send an InteractiveMarkerFeedback message with menu_entry_id set to this entry's id. -# ROSRUN: execute "rosrun" with arguments given in the command field (above). -# ROSLAUNCH: execute "roslaunch" with arguments given in the command field (above). -uint8 FEEDBACK=0 -uint8 ROSRUN=1 -uint8 ROSLAUNCH=2 -uint8 command_type diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg deleted file mode 100644 index f7c43398365..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/MeshFile.msg +++ /dev/null @@ -1,8 +0,0 @@ -# Used to send raw mesh files. - -# The filename is used for both debug purposes and to provide a file extension -# for whatever parser is used. -string filename - -# This stores the raw text of the mesh file. -uint8[] data diff --git a/dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg b/dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg deleted file mode 100644 index d48b0f293e9..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/msg/UVCoordinate.msg +++ /dev/null @@ -1,4 +0,0 @@ -# Location of the pixel as a ratio of the width of a 2D texture. -# Values should be in range: [0.0-1.0]. -float32 u -float32 v diff --git a/dimos/message_codegen/schemas/visualization_msgs/package.xml b/dimos/message_codegen/schemas/visualization_msgs/package.xml deleted file mode 100644 index f18262ca40d..00000000000 --- a/dimos/message_codegen/schemas/visualization_msgs/package.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - visualization_msgs - 5.3.8 - A package containing some visualization and interaction related message definitions. - - Tully Foote - - Apache License 2.0 - - Geoffrey Biggs - Michael Carroll - Michel Hidalgo - William Woodall - - ament_cmake - - rosidl_default_generators - - builtin_interfaces - geometry_msgs - sensor_msgs - std_msgs - - rosidl_default_runtime - - ament_lint_common - - rosidl_interface_packages - - - ament_cmake - - diff --git a/dimos/message_codegen/sources.json b/dimos/message_codegen/sources.json index cf507a378e4..db12090a1c9 100644 --- a/dimos/message_codegen/sources.json +++ b/dimos/message_codegen/sources.json @@ -1,197 +1,11 @@ [ - { - "repository": "ros2/common_interfaces", - "revision": "a941f14bb318d8d904505ed935ccbb97f24a70a4", - "files": { - "schemas/geometry_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/geometry_msgs/msg/Accel.msg": "67f371aabfc8ec1bd58bbb01a1709222e685c549462984c9958cc89fcd9f6abb", - "schemas/geometry_msgs/msg/AccelStamped.msg": "c46e9fcf5551d2330b63b1efe0626f747bcda24ddcc9e281597a9354b3bd9eea", - "schemas/geometry_msgs/msg/AccelWithCovariance.msg": "59512bab4004aefda7a9dea2a6fdbeb625c66a3a5359aae33b4561cf4a41263b", - "schemas/geometry_msgs/msg/AccelWithCovarianceStamped.msg": "04d5dbf78d814f58f4a01b1e9a63b5a5fdd24f5164cf021908d05fb079e63de8", - "schemas/geometry_msgs/msg/Inertia.msg": "33bc8db637874153ba5261bb5e7c23ca12754e15e5a2e58a86533c1f5bd66dd4", - "schemas/geometry_msgs/msg/InertiaStamped.msg": "456743836340c5d638dba1fcae3211acfe61f0690dcc9fe5b7ae9af8991591f1", - "schemas/geometry_msgs/msg/Point.msg": "eb4c07e591cf0269ccb17245dcd4f998162feb09cc8add85fa082c8a30bfc91d", - "schemas/geometry_msgs/msg/Point32.msg": "acade2dacb4f1f7988f34e8221079eb1c757f51e8ef48adb5651f7dc478fed59", - "schemas/geometry_msgs/msg/PointStamped.msg": "c58b03c27604f45e9b0fd2f1b327dcbada7d6a389beb8c060d448abc25e76bfc", - "schemas/geometry_msgs/msg/Polygon.msg": "43679118501e3b294349c9ad73af9f03b476ef77c7096cd79b4ce46646823056", - "schemas/geometry_msgs/msg/PolygonInstance.msg": "2ba1b905a10593821b1f8f4c05ad27cf2d1a9bd1e9c2643b01297583993f7bd4", - "schemas/geometry_msgs/msg/PolygonInstanceStamped.msg": "0dd863a4fb199e8833d13df9802064884a8be7a7f439f2b6e378aebcf121a506", - "schemas/geometry_msgs/msg/PolygonStamped.msg": "ff0812e3cae3e92947ba4abe3f9ea6ad31e04af0f2d97399027786ad27d39f0a", - "schemas/geometry_msgs/msg/Pose.msg": "3eceb77c63ebbb544c11d7f991e475e9819e0cf534deb1a879392c1b3dc997de", - "schemas/geometry_msgs/msg/Pose2D.msg": "48bbdb9e593b50b3e4b4e4494ca6ce076f59937c1b4ad80bc7ea09e87891a899", - "schemas/geometry_msgs/msg/PoseArray.msg": "3f58a91730c78dbc5ec5092131945ccdfeeb775aa0f02df7ff09f6c979b1d398", - "schemas/geometry_msgs/msg/PoseStamped.msg": "31898ab0eb64a6c44c27ab4959819a32ec3bc3ee847c8fe1b01c897d48e311e5", - "schemas/geometry_msgs/msg/PoseWithCovariance.msg": "a22f234e91b9fcd4ba0c5b533496b43c62d7f6ade39082212ac9835679d29f94", - "schemas/geometry_msgs/msg/PoseWithCovarianceStamped.msg": "87b6851480902effb5232f87bf68e76f19bf7b26affa11001be9e515542c21fb", - "schemas/geometry_msgs/msg/Quaternion.msg": "298495eb67a139642ffd37cc9029eae085e6c39a8789828b7517868a487939ed", - "schemas/geometry_msgs/msg/QuaternionStamped.msg": "855d4fd0cecb74ed55477a8c1f19fc9498207e7833a4f923b56fd68a9ba99ec9", - "schemas/geometry_msgs/msg/Transform.msg": "c8916279f0a429dd9561158bd2133bc4e2d780277c3c594116b240a27e7a2993", - "schemas/geometry_msgs/msg/TransformStamped.msg": "f6e137c205e9187ac1dafdfbace7435de58bb3779a55e9c6b52c2cb513785c42", - "schemas/geometry_msgs/msg/Twist.msg": "ed471ef861f65af991b1f64d66ef941dd41dd4c0702f6222512b1a16c62d58b0", - "schemas/geometry_msgs/msg/TwistStamped.msg": "ffc9d5925412410b28d601c55cf386a0b3e4d5dba00920fbafb98d7201f582ca", - "schemas/geometry_msgs/msg/TwistWithCovariance.msg": "5690a1f109d4962c73b5ca7f3673c48052d02f37b6a38fe2fb37c899cf555c45", - "schemas/geometry_msgs/msg/TwistWithCovarianceStamped.msg": "af369aea38a14e57ff350a3f2c63c2c66335a367822d134fecdef60789e49682", - "schemas/geometry_msgs/msg/Vector3.msg": "d8b9ea9aad1f424faf4d2b94dae1e1368af1e5d59de11aeed019399cff7f9e1d", - "schemas/geometry_msgs/msg/Vector3Stamped.msg": "bfe690d1b7d907c039c9c1580cf8de557d546c8aeb3280c1bd5e0a60d84356cd", - "schemas/geometry_msgs/msg/VelocityStamped.msg": "48517d22e2485d0d018300aba815569d05614f7e0eb9c2959719081d8ca0bd5b", - "schemas/geometry_msgs/msg/VelocityWithCovarianceStamped.msg": "d04d9a70bba11e70baa146d05b02804f43c835c2caa733d8ddacc4b09528f43f", - "schemas/geometry_msgs/msg/Wrench.msg": "d9667abd3d2a67d5624113fa07a647b0d4806bf89d21c8a5cf914905a036bf25", - "schemas/geometry_msgs/msg/WrenchStamped.msg": "853a8534230b795b6c1afcb8483002f5d1cf14e967ffa0da2cba8da5453b2162", - "schemas/geometry_msgs/package.xml": "879da7003d6d2952701aa23146f0d78096143d5107dd6e775a23e591c2c376a0", - "schemas/nav_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/nav_msgs/msg/Goals.msg": "37006ffd5763454ccb2a9630eda00501e5cb9b874a6cb38deec7398c2abb919f", - "schemas/nav_msgs/msg/GridCells.msg": "4bc9802947dcd2bbfafcbcffbce165ce6ff87e5132b9511ab2994ef4b23ff2b3", - "schemas/nav_msgs/msg/MapMetaData.msg": "6868a7d604c6cc033dd0adfac8a0adb0a6dedae1b7b140dbb47c83f3bcc6f140", - "schemas/nav_msgs/msg/OccupancyGrid.msg": "3e54ec7e662bdd6d5528efab99c6e34ce3eed27ce628721fcdb4e5e1bbf8188b", - "schemas/nav_msgs/msg/Odometry.msg": "bb00547ddf498cdbae46fd991d9d85a59f507e12e7cf01fb18a86f1111524f4f", - "schemas/nav_msgs/msg/Path.msg": "fc1e2eff6c2bd63fb92b6cf29bad29873b026d7abe00d3a68965b40668bfdd5b", - "schemas/nav_msgs/msg/Trajectory.msg": "66345fad009bc64a3c313020ec78d33a0f6424698ca37a020e33038cc19511b1", - "schemas/nav_msgs/msg/TrajectoryPoint.msg": "aec0753c683e369c16253d018f6e97c4230e4f4ba0135d52050b333793f39796", - "schemas/nav_msgs/package.xml": "0d61b26dbf9ccfd2e993713d5d5cea913f0ab789d1a28bdb42eac2ef47c4a0a5", - "schemas/sensor_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/sensor_msgs/msg/BatteryState.msg": "ce13430f3c107274fb7123a6d1e79a9f83974d78cb0be1721695129e49240b25", - "schemas/sensor_msgs/msg/CameraInfo.msg": "1fced83678f5f2708aff8540987594692452de9f0b43905ce3bfba689226f3aa", - "schemas/sensor_msgs/msg/ChannelFloat32.msg": "6cf885a09a7f499ce2348bc3099e146a6273bb1e7ff875824ecbe05abaf0d086", - "schemas/sensor_msgs/msg/CompressedImage.msg": "75ca1003981c407148ff94a3470760985dd69233b8287a5d52848d45a312f144", - "schemas/sensor_msgs/msg/FluidPressure.msg": "a2a96aa57e9957549dbf5c739c3dba3fb4303f0dd8426c9178b7333b656bb0d9", - "schemas/sensor_msgs/msg/Illuminance.msg": "b55f46c55588f7d729feb7dd84b60b1796dcfdb2351a26982ff2505129702182", - "schemas/sensor_msgs/msg/Image.msg": "575cd3434771916c2b551db8ac484522ecef1d6105196e043a305887d2730704", - "schemas/sensor_msgs/msg/Imu.msg": "5800b7c2e6d3afed966ae229b1559f6e762c792ad34a88e55ad4288d8bbbd34b", - "schemas/sensor_msgs/msg/JointState.msg": "711d1771a002c7190e5bbe746a163a67477c1e2a45482a64f1fe339815ca6f5d", - "schemas/sensor_msgs/msg/Joy.msg": "5a7d133e7dc82f531e03bd4ff92c9240a828bb6ceb6f19d5cd767d5372adb757", - "schemas/sensor_msgs/msg/JoyFeedback.msg": "47f62324e13743dd7a14bb71d64dc4cc034f4ff7885688c235bc121e224e06c3", - "schemas/sensor_msgs/msg/JoyFeedbackArray.msg": "6930a74a9e38918bb6f872c3e30ee3bb172c3b71cb3daf5d07c6ea76ee44f0ab", - "schemas/sensor_msgs/msg/LaserEcho.msg": "57511740458bf605dd609aab1b43312ec0e884d702196993a29ea32cb67d4f5f", - "schemas/sensor_msgs/msg/LaserScan.msg": "bb688599d8787fa1b48393e50064013e58449055eb60e501eb01a07e8bc03357", - "schemas/sensor_msgs/msg/MagneticField.msg": "b1bf534a4175055d85ee4630788c67a960733c383a458b86f6dfdfa27786be64", - "schemas/sensor_msgs/msg/MultiDOFJointState.msg": "bb707259b63ea52101697daf624ff7ad73a1f9977117ce3798a36cc1858d99fd", - "schemas/sensor_msgs/msg/MultiEchoLaserScan.msg": "8e96fd2ff5e685bfed326fecd90797fade8485be7c02f54250e5ea535c42b5e3", - "schemas/sensor_msgs/msg/NavSatFix.msg": "7457a0d5afd253a69a9996288192fb9bf10fdd053989204d5aca8d56d95b65ac", - "schemas/sensor_msgs/msg/NavSatStatus.msg": "f41663c70f192cfb8af118403ced55171b9c42af40a4ef798536d8af23b3d4f9", - "schemas/sensor_msgs/msg/PointCloud.msg": "8bdec27b9f1b688448410d1c6de34b42af6ef56ad4e496a214793e9ec88db993", - "schemas/sensor_msgs/msg/PointCloud2.msg": "22699bfd6c68be148363a2e889408833a5a37d3464ea20032d1c757336b80f2a", - "schemas/sensor_msgs/msg/PointField.msg": "6e6d5d51d2e464d3074b44b112f219e67fcdc0b280260d93f8cefd9710ec972e", - "schemas/sensor_msgs/msg/Range.msg": "6aac2960a3702cad5c5a6b5eda68e252a97d199bd9b7385c975332edbbc170cf", - "schemas/sensor_msgs/msg/RegionOfInterest.msg": "9c07010ab5ffddd1202876a778b44c99cafa780bc0503041c3fd935870a14c6a", - "schemas/sensor_msgs/msg/RelativeHumidity.msg": "bd9cff7bdebac733030ec1de6a66f004bf4f31924078a3170984d338352e649a", - "schemas/sensor_msgs/msg/Temperature.msg": "20a8580f84dbc063d87c3e1b902494149428272749844fa1dbf24fa80575be82", - "schemas/sensor_msgs/msg/TimeReference.msg": "4fdb6fb81fc2e910c560d80dd21b161a72d7f09b2f0ea9bdfcb75d71ab342491", - "schemas/sensor_msgs/package.xml": "00cc932b8a1d2a9064c621bfacab56428a5175afe37269da38ba09361e8a4a5a", - "schemas/shape_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/shape_msgs/msg/Mesh.msg": "29507f9817d335be2f43addd1997e032f73aeeff156d13931b92db62715dfe01", - "schemas/shape_msgs/msg/MeshTriangle.msg": "2beff414354278b465ec50b0526756317a641c2165ca1d6938028ed630445b96", - "schemas/shape_msgs/msg/Plane.msg": "b3d30ea44df5e4cdd40eda15239e19e6b18d5bccdb227d8cea45c7875b8c6fd0", - "schemas/shape_msgs/msg/SolidPrimitive.msg": "b3ec61569b2b4e2c37428e0625d4a360c00c95fc9ad4c94f9c8399225b98b2d8", - "schemas/shape_msgs/package.xml": "6c815efae68e089af95fd6e224292275808eaaea6bd85e3cfb1071fc6b7cd8dc", - "schemas/std_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/std_msgs/msg/Bool.msg": "d989b95f2ba14d15eff5b274b5d1f379b938aaea2157d8bd707f942457ae18bf", - "schemas/std_msgs/msg/Byte.msg": "448fd1e2fba020e0e297156875162512d9f9cab89e45f7793cb48f5999bdb287", - "schemas/std_msgs/msg/ByteMultiArray.msg": "b1f5112522ff33249f4391e4bf8b02535acd99ef447dbd20f04cd7115f18cdfc", - "schemas/std_msgs/msg/Char.msg": "b39e71ef965c29b1d121af0c0104b4167b9f972836b160c2c18b8f76f959d793", - "schemas/std_msgs/msg/ColorRGBA.msg": "6a2ce596d968f23d8456ff1e0b1218dec75ce2542614e004c99d29aceb3be697", - "schemas/std_msgs/msg/Empty.msg": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "schemas/std_msgs/msg/Float32.msg": "fb905efdb5c7902255cad5a6e4953158384238d4652d9e7ed68d134da052f3af", - "schemas/std_msgs/msg/Float32MultiArray.msg": "06fdd671e03917b05d2f8be67ce6b1ed5934990c9361b2ec6ab24637f9ec5aef", - "schemas/std_msgs/msg/Float64.msg": "b319b310779a5bc2e1f16a47a204236d5c231f2e9a9bf1555d6d098ae5aba625", - "schemas/std_msgs/msg/Float64MultiArray.msg": "344f5d8e6215a6e994659fb272de97c47a02b435db94a6d0f983b1fb467e0775", - "schemas/std_msgs/msg/Header.msg": "d2cea14630e39ed0fa5b432ba9160a7c38855b9427d3344f99e83e83facb53c2", - "schemas/std_msgs/msg/Int16.msg": "ea0ed16cdc7adc6b93ed503f21391832bbad3968d39881d117184bf298f9c5f0", - "schemas/std_msgs/msg/Int16MultiArray.msg": "82c59adccac841bdcb69c9030866972f1008c894c7e4245a2c24a78f8379e3de", - "schemas/std_msgs/msg/Int32.msg": "4614a6d0154436fb9ff12b0b7637816f42a550e4f5e0c4705bedf11293b4f7a7", - "schemas/std_msgs/msg/Int32MultiArray.msg": "70dd821b52c083f05963b02d49a59214baaba0fc17a56eba7c30346a26183a4a", - "schemas/std_msgs/msg/Int64.msg": "117752e7d1f0e4709749c04a9251dcece8545c0dac7bbb6fb8f31262d6ace238", - "schemas/std_msgs/msg/Int64MultiArray.msg": "423483a9473b3e6f8e00170a4c16591d801fd61d987d38b46def6ec2cf3b05d1", - "schemas/std_msgs/msg/Int8.msg": "2ad86a195e6c5d3415b5b48f4c248c45bfe05d636735f88d821c44ab660c7f6f", - "schemas/std_msgs/msg/Int8MultiArray.msg": "8b4b59b15a32fb25353425041c33874f6667376df2f4e5c08f9af2d56d11e403", - "schemas/std_msgs/msg/MultiArrayDimension.msg": "94927d0ee40f1a1d9bf7bdddbca803e8b6e6d315d70c7295a9b0d2d6c380abed", - "schemas/std_msgs/msg/MultiArrayLayout.msg": "8f059b66610c5fe0532e3f12ff1022a10671caebf773f00816fd4c9303626914", - "schemas/std_msgs/msg/String.msg": "2022b3f1c32b578ff8d54a9948a51a10778761e0ad4ba60e50ae51292ca16884", - "schemas/std_msgs/msg/UInt16.msg": "1e221bc3043d630d8f0e9db8c6d50f3f47a19db3c0908a290e95e58e2d3a225b", - "schemas/std_msgs/msg/UInt16MultiArray.msg": "288489782bda9287b6f7045ea5b039126280f84acf3a5ca2fa0710f8a916d3d5", - "schemas/std_msgs/msg/UInt32.msg": "4db7deaede98bebcc6ddfa951cf4d55aaad57909f38a8c346a12ae25df2e58ae", - "schemas/std_msgs/msg/UInt32MultiArray.msg": "3a25d8463602c0f3eff61a14c3c17c10ef819aadf7ef19179e95cfdaea07b3ce", - "schemas/std_msgs/msg/UInt64.msg": "3c2e946558706bf4afa6fca53dac6e19865c19629bf43b28a5e7bb5a9109eb58", - "schemas/std_msgs/msg/UInt64MultiArray.msg": "2e9c7e85a430eb66905eea278c7de39fb16baeda225ced6b78d15e06cd426e4d", - "schemas/std_msgs/msg/UInt8.msg": "4f3a2f4948339ff1b3bdb947c1f5124d6da4766a36f0f7a7bdad63fbbac41b76", - "schemas/std_msgs/msg/UInt8MultiArray.msg": "5c042755bdeaa442d6bab5755790cef6a3f9434162dab9028fd8dc1b794d6bd4", - "schemas/std_msgs/package.xml": "a34587c4319cab814f6e092a4f2d30f96e8de0325c81f69c2701a9545383da23", - "schemas/trajectory_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/trajectory_msgs/msg/JointTrajectory.msg": "d63cda4a5ec81824ed4acd737e6b5903449fb1a7e2f5cdcdcc4c49285f01117c", - "schemas/trajectory_msgs/msg/JointTrajectoryPoint.msg": "2358055d26d27c0c302e921f90d5aa59cb5feb3e22937f8ac98314b0c52ba8f4", - "schemas/trajectory_msgs/msg/MultiDOFJointTrajectory.msg": "070af6b4c9f4238d9de36621105d78c999dbad2045d0cb2a633f86a17f73f6b7", - "schemas/trajectory_msgs/msg/MultiDOFJointTrajectoryPoint.msg": "7e3a4b150ff7ce8d7d897a480d8d324a244a0afb4a07fdf6241074071170ac7a", - "schemas/trajectory_msgs/package.xml": "c0d9fd1b3f17b2d3811086b67414d519850a75e8ce08e609e40d1b9fee821575", - "schemas/visualization_msgs/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/visualization_msgs/msg/ImageMarker.msg": "d9c80f1109ceb8764ca5c9198fb2dbad4e3c5bc073d94c2be2cbcd6ea0eccdc6", - "schemas/visualization_msgs/msg/InteractiveMarker.msg": "95fd14ff8172ac01847378ab836ae387f54ab458b715e93dc1a049a10daa4326", - "schemas/visualization_msgs/msg/InteractiveMarkerControl.msg": "d73f1e212bcbab4d191cc3254c9f6de0b9de4f420ab2d87ba122ef0a2683acc6", - "schemas/visualization_msgs/msg/InteractiveMarkerFeedback.msg": "27b820cb63c165a9966bdb5eed516eecc25d9d15bb66192f14e930eff7446915", - "schemas/visualization_msgs/msg/InteractiveMarkerInit.msg": "facc8236619cef328d291555f6bdc784e34fa3a1700d6d2390bab73c45d121fa", - "schemas/visualization_msgs/msg/InteractiveMarkerPose.msg": "b6e3a8d40bf9c99ea7837eb08b0e8e8189f3fc5d7bb370ce501141cc1966582c", - "schemas/visualization_msgs/msg/InteractiveMarkerUpdate.msg": "6d75ca37561c3497ee1991cb6e61e55b59ebf2e1d458bdce30ad023d36762bdb", - "schemas/visualization_msgs/msg/Marker.msg": "136042d6ddb4589159f23fe1d7a469420c556c0a37fa712d4fff9c2dd74e9239", - "schemas/visualization_msgs/msg/MarkerArray.msg": "38a122bed2014534668ad143f6b57a831b6edb3d4453b2feeef8669930f234cc", - "schemas/visualization_msgs/msg/MenuEntry.msg": "47056d0f57316473249d619dbe51d26680c56c329be668afab9b5fd7a1f2a0a5", - "schemas/visualization_msgs/msg/MeshFile.msg": "6c5393590d3765a6da1bc815f0dba8962b55efad40ab4fb1346673cf89c294ed", - "schemas/visualization_msgs/msg/UVCoordinate.msg": "544f2580cfb42e1e28dcb27856572abd52ad348d8f6197526f51f6d15acec1f0", - "schemas/visualization_msgs/package.xml": "19ed838dc5a99735e2dd9b45e308d1227f6ba7c411ce3675cca480620993750d" - }, - "patches": {} - }, - { - "repository": "ros2/rcl_interfaces", - "revision": "7aa3caf43377ea6ad615bc1040832e2c7566bfbe", - "files": { - "schemas/builtin_interfaces/msg/Duration.msg": "57da13a4201e7d258a2931323145b953e47e46967494e62ba66c2faca4fbade2", - "schemas/builtin_interfaces/msg/Time.msg": "dc5a01ddde3aecffee21eb24974fe77cc969f873218a2b1811aa0ac8a456b8bd", - "schemas/builtin_interfaces/package.xml": "0f709bdbc4742e9040e788adcc2df710542d9a095080cbcda2dcb4174461de51", - "schemas/licenses/ros2_rcl_interfaces/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" - }, - "patches": {} - }, - { - "repository": "ros2/geometry2", - "revision": "f702874b1c8535d6a038230ab2cda0ba5d521ebd", - "files": { - "schemas/licenses/ros2_geometry2/LICENSE": "1b1e5ebcad699924203feced7205a4bbdf4f153d34065a19a8a4e107cf1e154b", - "schemas/tf2_msgs/msg/TF2Error.msg": "f1f3603b877ed51a5a28b264257e9bc37312e32a767838f52310d07027d819ab", - "schemas/tf2_msgs/msg/TFMessage.msg": "f3fca610a59b31ee4c7b740522ecdd0fd8c76002170088111409e4df513f1dfc", - "schemas/tf2_msgs/package.xml": "ac78cb0ff503bc07b20358bbe7bcb7475db7b6f0d87d2a84e321b92755bfb14e" - }, - "patches": {} - }, - { - "repository": "ros-perception/vision_msgs", - "revision": "adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27", - "files": { - "schemas/licenses/ros-perception_vision_msgs/LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", - "schemas/vision_msgs/msg/BoundingBox2D.msg": "74ed6347e3c8f74b884a81c5a36925c0e320836c1a5ea55df2b8d03574cc25b1", - "schemas/vision_msgs/msg/BoundingBox2DArray.msg": "0045d22aad0e9ab13e54b365e56b1a8c99829086a5126a4ede2c1916850ffb44", - "schemas/vision_msgs/msg/BoundingBox3D.msg": "30502a6e247a84d87b4c2c0262fd07ce6ba3fa8d6d24e6e39c1522d7e469c450", - "schemas/vision_msgs/msg/BoundingBox3DArray.msg": "dac9423ac1a15724f3a068a3987e9702ddcff6ea7eedacc92d7352aa24ba478d", - "schemas/vision_msgs/msg/Classification.msg": "05c1206c9db5728e8e6a8528354bbc6a9d2c5be9147268227c887019c7ecaf34", - "schemas/vision_msgs/msg/Detection2D.msg": "868ffec733235c01bb5bfba3f3c528f193ea0fb3069650aaf95383a7fa9a8200", - "schemas/vision_msgs/msg/Detection2DArray.msg": "bb2eeef88b466103b89a7ae9f927164d2064e9d94e8455bb98ad2b69130331ae", - "schemas/vision_msgs/msg/Detection3D.msg": "68885eeededfc57231f171f2b3eb97f0d0a18580ca08307bc60b9b87216df985", - "schemas/vision_msgs/msg/Detection3DArray.msg": "077f34a634e6de6654265af5b26508eea1105bef72395cffae50fde61b713c41", - "schemas/vision_msgs/msg/LabelInfo.msg": "96cf2fa183f8f20a7356fd18163d2a8e875306c799f3fadec08169e5e487f3aa", - "schemas/vision_msgs/msg/ObjectHypothesis.msg": "6224cb18c032fe062d18859089444f4e1f311ab478e45d937fdfac18a980695b", - "schemas/vision_msgs/msg/ObjectHypothesisWithPose.msg": "162639c82b24a8fc4f3e93a4dc91704928d5cff9d39d169515bb748eccf4d573", - "schemas/vision_msgs/msg/Point2D.msg": "6b99220dccc3193a603fb40d6a2880b4de67fb2175121c5683d0bde9f71e3733", - "schemas/vision_msgs/msg/Pose2D.msg": "0cdb3bc9872a5c3379a5122c14d03ec13d59b92752d3b444cc41592492258ab2", - "schemas/vision_msgs/msg/VisionClass.msg": "ae82ce087350e3ee1c0f0f8bb8f6e6c2e08f94dea6d984dec579fd72663bdb72", - "schemas/vision_msgs/msg/VisionInfo.msg": "5a47776dfea36e48958dbde43ab55e9cb94fb337b0f68b4fcc444807f333b23d", - "schemas/vision_msgs/package.xml": "b69e5eb38183cbcf2cf0b729a21ea6217eb76a48bd0613c00539a598a5f35872" - }, - "patches": {} - }, { "repository": "ros2/rosidl", "revision": "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", "files": { "_vendor/rosidl_parser.py": "4ca3bc4ecbfca7f48a07f1d9630bfb5d006f55857e75a3d3207380386431572e", - "schemas/licenses/ros2_rosidl/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", - "schemas/rosidl_adapter/package.xml": "653c797d2b4e2f5e6ad7b18812632bf6bf55aa924dfbca0405439389a5273989" + "_vendor/LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "_vendor/rosidl_adapter.package.xml": "653c797d2b4e2f5e6ad7b18812632bf6bf55aa924dfbca0405439389a5273989" }, "patches": { "_vendor/rosidl_parser.py": { @@ -199,14 +13,5 @@ "description": "Equivalent linear-time constant-name validation regex" } } - }, - { - "repository": "foxglove/schemas", - "revision": "e86a94e9d4d259cdde71872f18336a7a055bf9ba", - "files": { - "schemas/foxglove_msgs/msg/CompressedVideo.msg": "83d044efaefc90291cdd56cd36b2ef6b190748c1df860d1eca7df77328174324", - "schemas/licenses/foxglove_schemas/LICENSE": "da11235665c17d4c1634072dae92b8ba1b38d6fdde2ccf19a6bbede33253f58d" - }, - "patches": {} } ] diff --git a/dimos/message_codegen/test_definitions.py b/dimos/message_codegen/test_definitions.py index 135b279e727..7d28b462e0d 100644 --- a/dimos/message_codegen/test_definitions.py +++ b/dimos/message_codegen/test_definitions.py @@ -30,7 +30,7 @@ def write_message(root: Path, name: str, text: str) -> Path: def test_resolves_standard_dependencies_without_ros(tmp_path): write_message(tmp_path, "example_msgs/msg/Telemetry", "sensor_msgs/Image image\nstring label\n") - definitions = Definitions([tmp_path]) + definitions = Definitions([Path(__file__).parents[2] / "examples/message-codegen", tmp_path]) closure = definitions.resolve(["example_msgs/msg/Telemetry"]) assert [message.name for message in closure] == [ @@ -137,15 +137,3 @@ def test_invalid_field_reports_source_line(tmp_path): parse_message(source) assert f"{source}:3:" in str(error.value) - - -def test_all_bundled_schemas_resolve(): - closure = Definitions([]).resolve() - - assert "sensor_msgs/msg/PointCloud2" in {message.name for message in closure} - assert "visualization_msgs/msg/MarkerArray" in {message.name for message in closure} - assert all( - dependency in {item.name for item in closure} - for message in closure - for dependency in message.dependencies - ) diff --git a/dimos/message_codegen/test_native.py b/dimos/message_codegen/test_native.py index 9555c7686a0..0598e91143b 100644 --- a/dimos/message_codegen/test_native.py +++ b/dimos/message_codegen/test_native.py @@ -37,7 +37,11 @@ def test_all_generated_types_match_independent_codec(): for value in vars(package.msg).values() if isinstance(value, type) and hasattr(value, "msg_name") ] - assert len(message_types) >= 142 + assert { + "demo_msgs/msg/Telemetry", + "sensor_msgs/msg/Image", + "std_msgs/msg/UInt32MultiArray", + } <= {item.msg_name for item in message_types} for message_type in message_types: reference.register(get_types_from_msg(message_type.schema, message_type.msg_name)) for little_endian in (True, False): diff --git a/examples/message-codegen/builtin_interfaces/msg/Time.msg b/examples/message-codegen/builtin_interfaces/msg/Time.msg new file mode 100644 index 00000000000..9eb444ccc09 --- /dev/null +++ b/examples/message-codegen/builtin_interfaces/msg/Time.msg @@ -0,0 +1,2 @@ +int32 sec +uint32 nanosec diff --git a/examples/message-codegen/demo_transport.py b/examples/message-codegen/demo_transport.py deleted file mode 100644 index 2d03ecf4708..00000000000 --- a/examples/message-codegen/demo_transport.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2026 Dimensional Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Verify Python/native raw LCM interoperability, including fragmented payloads.""" - -import argparse -from pathlib import Path -import selectors -import socket -import subprocess -import time - -import lcm - - -def main() -> None: - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("--executable", type=Path, required=True) - args = parser.parse_args() - with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as port_socket: - port_socket.bind(("127.0.0.1", 0)) - port = port_socket.getsockname()[1] - transport = lcm.LCM(f"udpm://239.255.76.67:{port}?ttl=0&recv_buf_size=4194304") - received: list[bytes] = [] - subscription = transport.subscribe("REPLY", lambda _channel, data: received.append(data)) - process = subprocess.Popen( - [str(args.executable.resolve()), str(port)], stdout=subprocess.PIPE, text=True - ) - try: - assert process.stdout is not None - with selectors.DefaultSelector() as ready: - ready.register(process.stdout, selectors.EVENT_READ) - assert ready.select(timeout=10), "Native transport did not become ready" - assert process.stdout.readline().strip() == "READY" - for size in (128, 65536, 1048576): - payload = bytes(index % 251 for index in range(size)) - transport.publish("INPUT", payload) - deadline = time.monotonic() + 10 - while not received and time.monotonic() < deadline: - transport.handle_timeout(100) - assert received, f"No reply for {size} bytes" - assert received.pop(0) == payload - print(f"Python -> native Rust -> Python: {size} raw bytes match", flush=True) - assert process.wait(timeout=10) == 0 - finally: - transport.unsubscribe(subscription) - if process.poll() is None: - process.terminate() - process.wait(timeout=10) - if process.stdout is not None: - process.stdout.close() - - -if __name__ == "__main__": - main() diff --git a/examples/message-codegen/geometry_msgs/msg/Point.msg b/examples/message-codegen/geometry_msgs/msg/Point.msg new file mode 100644 index 00000000000..96a6940e4f2 --- /dev/null +++ b/examples/message-codegen/geometry_msgs/msg/Point.msg @@ -0,0 +1,3 @@ +float64 x +float64 y +float64 z diff --git a/examples/message-codegen/sensor_msgs/msg/Image.msg b/examples/message-codegen/sensor_msgs/msg/Image.msg new file mode 100644 index 00000000000..5cf53c92010 --- /dev/null +++ b/examples/message-codegen/sensor_msgs/msg/Image.msg @@ -0,0 +1,7 @@ +std_msgs/Header header +uint32 height +uint32 width +string encoding +uint8 is_bigendian +uint32 step +uint8[] data diff --git a/examples/message-codegen/sensor_msgs/msg/PointCloud2.msg b/examples/message-codegen/sensor_msgs/msg/PointCloud2.msg new file mode 100644 index 00000000000..2b6a94c3cf3 --- /dev/null +++ b/examples/message-codegen/sensor_msgs/msg/PointCloud2.msg @@ -0,0 +1,9 @@ +std_msgs/Header header +uint32 height +uint32 width +PointField[] fields +bool is_bigendian +uint32 point_step +uint32 row_step +uint8[] data +bool is_dense diff --git a/examples/message-codegen/sensor_msgs/msg/PointField.msg b/examples/message-codegen/sensor_msgs/msg/PointField.msg new file mode 100644 index 00000000000..5abcf793e42 --- /dev/null +++ b/examples/message-codegen/sensor_msgs/msg/PointField.msg @@ -0,0 +1,12 @@ +uint8 INT8 = 1 +uint8 UINT8 = 2 +uint8 INT16 = 3 +uint8 UINT16 = 4 +uint8 INT32 = 5 +uint8 UINT32 = 6 +uint8 FLOAT32 = 7 +uint8 FLOAT64 = 8 +string name +uint32 offset +uint8 datatype +uint32 count diff --git a/examples/message-codegen/std_msgs/msg/Bool.msg b/examples/message-codegen/std_msgs/msg/Bool.msg new file mode 100644 index 00000000000..e70908b074b --- /dev/null +++ b/examples/message-codegen/std_msgs/msg/Bool.msg @@ -0,0 +1 @@ +bool data diff --git a/examples/message-codegen/std_msgs/msg/Header.msg b/examples/message-codegen/std_msgs/msg/Header.msg new file mode 100644 index 00000000000..3b25b3933a6 --- /dev/null +++ b/examples/message-codegen/std_msgs/msg/Header.msg @@ -0,0 +1,2 @@ +builtin_interfaces/Time stamp +string frame_id diff --git a/examples/message-codegen/std_msgs/msg/MultiArrayDimension.msg b/examples/message-codegen/std_msgs/msg/MultiArrayDimension.msg new file mode 100644 index 00000000000..6442b08cafb --- /dev/null +++ b/examples/message-codegen/std_msgs/msg/MultiArrayDimension.msg @@ -0,0 +1,3 @@ +string label +uint32 size +uint32 stride diff --git a/examples/message-codegen/std_msgs/msg/MultiArrayLayout.msg b/examples/message-codegen/std_msgs/msg/MultiArrayLayout.msg new file mode 100644 index 00000000000..e8bdc175f92 --- /dev/null +++ b/examples/message-codegen/std_msgs/msg/MultiArrayLayout.msg @@ -0,0 +1,2 @@ +MultiArrayDimension[] dim +uint32 data_offset diff --git a/examples/message-codegen/std_msgs/msg/String.msg b/examples/message-codegen/std_msgs/msg/String.msg new file mode 100644 index 00000000000..ae721739e8f --- /dev/null +++ b/examples/message-codegen/std_msgs/msg/String.msg @@ -0,0 +1 @@ +string data diff --git a/examples/message-codegen/std_msgs/msg/UInt32MultiArray.msg b/examples/message-codegen/std_msgs/msg/UInt32MultiArray.msg new file mode 100644 index 00000000000..ae2694ad2f6 --- /dev/null +++ b/examples/message-codegen/std_msgs/msg/UInt32MultiArray.msg @@ -0,0 +1,2 @@ +MultiArrayLayout layout +uint32[] data diff --git a/native/rust/dimos-lcm-transport/Cargo.toml b/native/rust/dimos-lcm-transport/Cargo.toml deleted file mode 100644 index f83c98802d0..00000000000 --- a/native/rust/dimos-lcm-transport/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "dimos-lcm-transport" -version = "0.1.0" -edition = "2021" -description = "Schema-independent LCM UDP multicast transport for DimOS" -license = "Apache-2.0" - -[dependencies] -byteorder = "1" -socket2 = { version = "0.5", features = ["all"] } -tokio = { version = "1.51.1", features = ["net", "rt-multi-thread", "macros", "time"] } diff --git a/native/rust/dimos-lcm-transport/README.md b/native/rust/dimos-lcm-transport/README.md deleted file mode 100644 index 57907bcbf8e..00000000000 --- a/native/rust/dimos-lcm-transport/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# DimOS raw LCM transport - -This crate publishes and receives opaque bytes over LCM UDP multicast. It has no -message definitions, fingerprints, generated message crate, or CDR dependency. -Typed consumers choose their own codec above this transport. - -The initial implementation was extracted from Dimensional's `dimos-lcm` repository, -`tools/rust/lcm`, commit `04d78e8622500244123ba9cefa4c51b4cb454549`, matching the -existing workspace lockfile. That crate declares Apache-2.0 in its Cargo manifest. -The source is maintained here so adding a message no longer depends on that -repository. Original transport behavior and its unit tests are retained; local -changes are reviewed in the DimOS history. - -Source: https://github.com/dimensionalOS/dimos-lcm/tree/04d78e8622500244123ba9cefa4c51b4cb454549/tools/rust/lcm - -Run the raw transport checks with: - -```bash -cargo test -p dimos-lcm-transport -cargo build -p dimos-lcm-transport --example interop -.venv/bin/python examples/message-codegen/demo_transport.py \ - --executable target/debug/examples/interop -``` - -The demo chooses a local UDP port, starts the native receiver, waits for its ready -signal, and exchanges both short and fragmented binary payloads with Python's LCM -binding. It terminates and reaps the native process even on failure. diff --git a/native/rust/dimos-lcm-transport/examples/interop.rs b/native/rust/dimos-lcm-transport/examples/interop.rs deleted file mode 100644 index efc4c9e9576..00000000000 --- a/native/rust/dimos-lcm-transport/examples/interop.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2026 Dimensional Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use dimos_lcm_transport::{Lcm, LcmOptions}; -use std::io::{self, Write}; -use std::time::Duration; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let port = std::env::args() - .nth(1) - .ok_or("usage: interop ")? - .parse()?; - let transport = Lcm::with_options(LcmOptions { - port, - ttl: 0, - ..Default::default() - }) - .await?; - println!("READY"); - io::stdout().flush()?; - for _ in 0..3 { - let message = tokio::time::timeout(Duration::from_secs(10), async { - loop { - let message = transport.recv().await?; - if message.channel == "INPUT" { - return Ok::<_, io::Error>(message); - } - } - }) - .await??; - transport.publish("REPLY", &message.data).await?; - } - Ok(()) -} diff --git a/native/rust/dimos-lcm-transport/src/lib.rs b/native/rust/dimos-lcm-transport/src/lib.rs deleted file mode 100644 index 1bbaef79375..00000000000 --- a/native/rust/dimos-lcm-transport/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2025-2026 Dimensional Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Pure Rust LCM (Lightweight Communications and Marshalling) transport. -//! -//! Provides UDP multicast publish/subscribe for LCM messages. -//! No system LCM library required. -//! -//! # Example -//! -//! ```no_run -//! use dimos_lcm_transport::Lcm; -//! -//! #[tokio::main] -//! async fn main() { -//! let mut lcm = Lcm::new().await.unwrap(); -//! -//! // Publish -//! let data = vec![1, 2, 3]; -//! lcm.publish("EXAMPLE", &data).await.unwrap(); -//! -//! // Receive -//! let msg = lcm.recv().await.unwrap(); -//! println!("{}: {} bytes", msg.channel, msg.data.len()); -//! } -//! ``` - -mod transport; - -pub use transport::{Lcm, LcmOptions, ReceivedMessage}; diff --git a/native/rust/dimos-lcm-transport/src/transport.rs b/native/rust/dimos-lcm-transport/src/transport.rs deleted file mode 100644 index 5be58aa18b3..00000000000 --- a/native/rust/dimos-lcm-transport/src/transport.rs +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2025-2026 Dimensional Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use byteorder::{BigEndian, ByteOrder}; -use socket2::{Domain, Protocol, Socket, Type}; -use std::collections::HashMap; -use std::io; -use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; -use std::sync::atomic::{AtomicU32, Ordering}; -use std::sync::Mutex; -use tokio::net::UdpSocket; - -const MAGIC_SHORT: u32 = 0x4c433032; // "LC02" -const MAGIC_LONG: u32 = 0x4c433033; // "LC03" -const SHORT_HEADER_SIZE: usize = 8; -const FRAGMENT_HEADER_SIZE: usize = 20; -const MAX_DATAGRAM_SIZE: usize = 65507; - -/// Default LCM multicast group address. -pub const DEFAULT_MULTICAST_GROUP: Ipv4Addr = Ipv4Addr::new(239, 255, 76, 67); -/// Default LCM multicast port. -pub const DEFAULT_PORT: u16 = 7667; - -static SEQ: AtomicU32 = AtomicU32::new(0); - -struct FragmentBuffer { - channel: String, - num_fragments: u16, - received: u16, - data: Vec, -} - -/// Configuration for an LCM transport instance. -#[derive(Debug, Clone)] -pub struct LcmOptions { - /// Multicast group address (default: 239.255.76.67). - pub multicast_group: Ipv4Addr, - /// UDP port (default: 7667). - pub port: u16, - /// Multicast TTL (default: 1). - pub ttl: u32, - /// Network interface to bind to (default: any). - pub interface: Ipv4Addr, -} - -impl Default for LcmOptions { - fn default() -> Self { - Self { - multicast_group: DEFAULT_MULTICAST_GROUP, - port: DEFAULT_PORT, - ttl: 1, - interface: Ipv4Addr::UNSPECIFIED, - } - } -} - -/// A received LCM message. -#[derive(Debug, Clone)] -pub struct ReceivedMessage { - /// Channel name. - pub channel: String, - /// Encoded message payload. - pub data: Vec, -} - -/// Returns the first and subsequent payload sizes, and the number of fragments -fn fragment_params(msg_size: usize, channel_len: usize) -> (usize, usize, usize) { - let first_payload_size = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE - channel_len - 1; - let subsequent_payload_size = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE; - let num_fragments = if msg_size <= first_payload_size { - 1 - } else { - 1 + msg_size - .saturating_sub(first_payload_size) - .div_ceil(subsequent_payload_size) - }; - (first_payload_size, subsequent_payload_size, num_fragments) -} - -/// Pure Rust LCM UDP multicast transport. -pub struct Lcm { - socket: UdpSocket, - multicast_addr: SocketAddrV4, - reassembly: Mutex>, -} - -impl Lcm { - /// Create a new LCM transport with default options. - pub async fn new() -> io::Result { - Self::with_options(LcmOptions::default()).await - } - - /// Create a new LCM transport with custom options. - pub async fn with_options(opts: LcmOptions) -> io::Result { - let s2 = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP))?; - s2.set_reuse_address(true)?; - // Sensor messages arrive as bursts of large fragments. Request enough - // queue space to reassemble an image without relying on kernel defaults. - s2.set_recv_buffer_size(4 * 1024 * 1024)?; - #[cfg(not(target_os = "windows"))] - s2.set_reuse_port(true)?; - - let bind_addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, opts.port); - s2.bind(&bind_addr.into())?; - - let std_socket: std::net::UdpSocket = s2.into(); - std_socket.set_nonblocking(true)?; - let socket = UdpSocket::from_std(std_socket)?; - - socket.join_multicast_v4(opts.multicast_group, opts.interface)?; - socket.set_multicast_ttl_v4(opts.ttl)?; - - Ok(Self { - socket, - multicast_addr: SocketAddrV4::new(opts.multicast_group, opts.port), - reassembly: Mutex::new(HashMap::new()), - }) - } - - /// Publish encoded message data on the given channel. - pub async fn publish(&self, channel: &str, data: &[u8]) -> io::Result<()> { - let channel_bytes = channel.as_bytes(); - let total = SHORT_HEADER_SIZE + channel_bytes.len() + 1 + data.len(); - let seqno = SEQ.fetch_add(1, Ordering::Relaxed); - - if total > MAX_DATAGRAM_SIZE { - self.publish_fragmented(channel_bytes, data, seqno).await - } else { - self.publish_small(channel_bytes, data, seqno).await - } - } - - async fn publish_small(&self, channel_bytes: &[u8], data: &[u8], seqno: u32) -> io::Result<()> { - let total = SHORT_HEADER_SIZE + channel_bytes.len() + 1 + data.len(); - let mut buf = vec![0u8; total]; - - BigEndian::write_u32(&mut buf[0..4], MAGIC_SHORT); - BigEndian::write_u32(&mut buf[4..8], seqno); - - buf[SHORT_HEADER_SIZE..SHORT_HEADER_SIZE + channel_bytes.len()] - .copy_from_slice(channel_bytes); - // null terminator already 0 from vec![0u8; ..] - let payload_start = SHORT_HEADER_SIZE + channel_bytes.len() + 1; - buf[payload_start..].copy_from_slice(data); - - self.socket.send_to(&buf, self.multicast_addr).await?; - Ok(()) - } - - async fn publish_fragmented( - &self, - channel_bytes: &[u8], - data: &[u8], - seqno: u32, - ) -> io::Result<()> { - let msg_size = data.len(); - let (first_payload_size, subsequent_payload_size, num_fragments) = - fragment_params(msg_size, channel_bytes.len()); - - let mut payload_offset = 0; - - for fragment_no in 0..num_fragments { - let is_first = fragment_no == 0; - let channel_size = if is_first { channel_bytes.len() + 1 } else { 0 }; - let max_payload = if is_first { - first_payload_size - } else { - subsequent_payload_size - }; - let payload_len = (msg_size - payload_offset).min(max_payload); - - let datagram_size = FRAGMENT_HEADER_SIZE + channel_size + payload_len; - let mut buf = vec![0u8; datagram_size]; - - BigEndian::write_u32(&mut buf[0..4], MAGIC_LONG); - BigEndian::write_u32(&mut buf[4..8], seqno); - BigEndian::write_u32(&mut buf[8..12], msg_size as u32); - BigEndian::write_u32(&mut buf[12..16], payload_offset as u32); - BigEndian::write_u16(&mut buf[16..18], fragment_no as u16); - BigEndian::write_u16(&mut buf[18..20], num_fragments as u16); - - let mut offset = FRAGMENT_HEADER_SIZE; - - if is_first { - buf[offset..offset + channel_bytes.len()].copy_from_slice(channel_bytes); - // null terminator already 0 - offset += channel_bytes.len() + 1; - } - - buf[offset..offset + payload_len] - .copy_from_slice(&data[payload_offset..payload_offset + payload_len]); - - self.socket.send_to(&buf, self.multicast_addr).await?; - payload_offset += payload_len; - } - - Ok(()) - } - - /// Receive one LCM message asynchronously. - /// - /// Waits until a complete message arrives, reassembling fragments if necessary. - pub async fn recv(&self) -> io::Result { - let mut buf = vec![0u8; MAX_DATAGRAM_SIZE]; - loop { - let (n, sender) = self.socket.recv_from(&mut buf).await?; - let pkt = &buf[..n]; - - if pkt.len() < 4 { - continue; - } - let magic = BigEndian::read_u32(&pkt[0..4]); - - if magic == MAGIC_SHORT { - if let Some(msg) = Self::decode_small(pkt)? { - return Ok(msg); - } - } else if magic == MAGIC_LONG { - if let Some(msg) = self.process_fragment(sender, pkt)? { - return Ok(msg); - } - } - // Unknown magic or incomplete fragment — wait for the next datagram - } - } - - fn process_fragment( - &self, - sender: SocketAddr, - buf: &[u8], - ) -> io::Result> { - if buf.len() < FRAGMENT_HEADER_SIZE { - return Ok(None); - } - - let seqno = BigEndian::read_u32(&buf[4..8]); - let total_size = BigEndian::read_u32(&buf[8..12]) as usize; - let fragment_offset = BigEndian::read_u32(&buf[12..16]) as usize; - let fragment_no = BigEndian::read_u16(&buf[16..18]); - let num_fragments = BigEndian::read_u16(&buf[18..20]); - - let mut offset = FRAGMENT_HEADER_SIZE; - - // First fragment carries the channel name - let channel = if fragment_no == 0 { - let channel_end = match buf[offset..].iter().position(|&b| b == 0) { - Some(pos) => offset + pos, - None => return Ok(None), - }; - let ch = String::from_utf8_lossy(&buf[offset..channel_end]).into_owned(); - offset = channel_end + 1; - Some(ch) - } else { - None - }; - - let payload = &buf[offset..]; - - let key = (sender, seqno); - - let mut reassembly = self.reassembly.lock().unwrap(); - let entry = reassembly.entry(key).or_insert_with(|| FragmentBuffer { - channel: channel.clone().unwrap_or_default(), - num_fragments, - received: 0, - data: vec![0u8; total_size], - }); - - // First fragment also sets the channel name on an existing entry - if let Some(ch) = channel { - entry.channel = ch; - } - - let end = (fragment_offset + payload.len()).min(total_size); - entry.data[fragment_offset..end].copy_from_slice(&payload[..end - fragment_offset]); - entry.received += 1; - - if entry.received == entry.num_fragments { - let complete = reassembly.remove(&key).unwrap(); - return Ok(Some(ReceivedMessage { - channel: complete.channel, - data: complete.data, - })); - } - - Ok(None) - } - - fn decode_small(buf: &[u8]) -> io::Result> { - if buf.len() < SHORT_HEADER_SIZE || BigEndian::read_u32(&buf[0..4]) != MAGIC_SHORT { - return Ok(None); - } - let channel_start = SHORT_HEADER_SIZE; - let channel_end = match buf[channel_start..].iter().position(|&b| b == 0) { - Some(pos) => channel_start + pos, - None => return Ok(None), - }; - let channel = String::from_utf8_lossy(&buf[channel_start..channel_end]).into_owned(); - let data = buf[channel_end + 1..].to_vec(); - Ok(Some(ReceivedMessage { channel, data })) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - const TEST_CHANNEL_LEN: usize = 13; // "/test_channel" - const FIRST_PAYLOAD: usize = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE - TEST_CHANNEL_LEN - 1; - const SUBSEQUENT_PAYLOAD: usize = MAX_DATAGRAM_SIZE - FRAGMENT_HEADER_SIZE; - - #[test] - fn fragment_count_fits_in_one() { - let (_, _, n) = fragment_params(FIRST_PAYLOAD, TEST_CHANNEL_LEN); - assert_eq!(n, 1); - } - - #[test] - fn fragment_count_spills_into_two() { - let (_, _, n) = fragment_params(FIRST_PAYLOAD + 1, TEST_CHANNEL_LEN); - assert_eq!(n, 2); - } - - #[test] - fn fragment_count_spills_into_three() { - let (_, _, n) = fragment_params(FIRST_PAYLOAD + SUBSEQUENT_PAYLOAD + 1, TEST_CHANNEL_LEN); - assert_eq!(n, 3); - } - - #[test] - fn fragment_count_one_mb() { - let (_, _, n) = fragment_params(1024 * 1024, TEST_CHANNEL_LEN); - assert_eq!(n, 17); - } - - fn make_small_packet(channel: &[u8], payload: &[u8]) -> Vec { - let mut buf = vec![0u8; SHORT_HEADER_SIZE + channel.len() + 1 + payload.len()]; - BigEndian::write_u32(&mut buf[0..4], MAGIC_SHORT); - BigEndian::write_u32(&mut buf[4..8], 0); - buf[SHORT_HEADER_SIZE..SHORT_HEADER_SIZE + channel.len()].copy_from_slice(channel); - buf[SHORT_HEADER_SIZE + channel.len() + 1..].copy_from_slice(payload); - buf - } - - #[test] - fn decode_small_known_good() { - let buf = make_small_packet(b"CHAN", &[1, 2, 3]); - let msg = Lcm::decode_small(&buf).unwrap().unwrap(); - assert_eq!(msg.channel, "CHAN"); - assert_eq!(msg.data, [1u8, 2, 3]); - } - - #[test] - fn decode_small_empty_payload() { - let buf = make_small_packet(b"CHAN", &[]); - let msg = Lcm::decode_small(&buf).unwrap().unwrap(); - assert_eq!(msg.channel, "CHAN"); - assert!(msg.data.is_empty()); - } - - #[test] - fn decode_small_wrong_magic() { - let mut buf = make_small_packet(b"CHAN", &[1, 2, 3]); - BigEndian::write_u32(&mut buf[0..4], 0xDEADBEEF); - assert!(Lcm::decode_small(&buf).unwrap().is_none()); - } - - #[test] - fn decode_small_truncated() { - // Shorter than SHORT_HEADER_SIZE - let buf = vec![0x4C, 0x43, 0x30, 0x32, 0x00]; - assert!(Lcm::decode_small(&buf).unwrap().is_none()); - } - - #[test] - fn decode_small_missing_null_terminator() { - // Valid header but channel bytes have no null terminator - let mut buf = vec![0u8; SHORT_HEADER_SIZE + 4]; - BigEndian::write_u32(&mut buf[0..4], MAGIC_SHORT); - BigEndian::write_u32(&mut buf[4..8], 0); - buf[SHORT_HEADER_SIZE..SHORT_HEADER_SIZE + 4].copy_from_slice(b"CHAN"); - assert!(Lcm::decode_small(&buf).unwrap().is_none()); - } -} diff --git a/scripts/test_message_codegen.sh b/scripts/test_message_codegen.sh index f25e2b79836..2951857fcc5 100644 --- a/scripts/test_message_codegen.sh +++ b/scripts/test_message_codegen.sh @@ -20,7 +20,3 @@ export PYTHONPATH="$PWD/build/message-codegen/demo/python${PYTHONPATH:+:$PYTHONP | tee build/message-codegen/demo/evidence/conformance.txt .venv/bin/python examples/message-codegen/demo_buffers.py --functional-only \ | tee build/message-codegen/demo/evidence/buffers.txt -cargo test -p dimos-lcm-transport -cargo build -p dimos-lcm-transport --example interop -.venv/bin/python examples/message-codegen/demo_transport.py --executable target/debug/examples/interop \ - | tee build/message-codegen/demo/evidence/transport.txt diff --git a/scripts/vendor_message_definitions.py b/scripts/vendor_message_definitions.py deleted file mode 100644 index 8326d8d864f..00000000000 --- a/scripts/vendor_message_definitions.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright 2026 Dimensional Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Refresh the pinned, ROS-free schema and parser sources used by message codegen. - -Run with the checkout's development Python environment. This maintenance command -requires network access; generation and downstream applications never run it. -""" - -from __future__ import annotations - -import hashlib -import io -import json -from pathlib import Path -import tarfile - -import requests - -ROOT = Path(__file__).resolve().parents[1] / "dimos" / "message_codegen" -SOURCES = ( - ( - "ros2/common_interfaces", - "a941f14bb318d8d904505ed935ccbb97f24a70a4", - ( - "std_msgs", - "geometry_msgs", - "sensor_msgs", - "nav_msgs", - "trajectory_msgs", - "visualization_msgs", - "shape_msgs", - ), - ), - ("ros2/rcl_interfaces", "7aa3caf43377ea6ad615bc1040832e2c7566bfbe", ("builtin_interfaces",)), - ("ros2/geometry2", "f702874b1c8535d6a038230ab2cda0ba5d521ebd", ("tf2_msgs",)), - ("ros-perception/vision_msgs", "adbf56af9f77e3c8ab2552e25dc99e4a8a77fb27", ("vision_msgs",)), - ("ros2/rosidl", "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", ("rosidl_adapter",)), - ("foxglove/schemas", "e86a94e9d4d259cdde71872f18336a7a055bf9ba", ("foxglove_msgs",)), -) - - -def main() -> None: - provenance: list[dict[str, object]] = [] - for repository, revision, packages in SOURCES: - url = f"https://codeload.github.com/{repository}/tar.gz/{revision}" - response = requests.get(url, timeout=90) - response.raise_for_status() - files: dict[str, str] = {} - patches: dict[str, dict[str, str]] = {} - with tarfile.open(fileobj=io.BytesIO(response.content), mode="r:gz") as archive: - for member in archive: - path = Path(*Path(member.name).parts[1:]) - if ( - repository == "foxglove/schemas" - and path.as_posix() == "schemas/ros2/CompressedVideo.msg" - ): - path = Path("foxglove_msgs/msg/CompressedVideo.msg") - if not member.isfile() or not path.parts: - continue - if len(path.parts) == 1 and path.name in {"LICENSE", "LICENSE.txt", "NOTICE"}: - target = ROOT / "schemas" / "licenses" / repository.replace("/", "_") / path - elif path.parts[0] not in packages: - continue - elif path.as_posix() == "rosidl_adapter/rosidl_adapter/parser.py": - target = ROOT / "_vendor" / "rosidl_parser.py" - elif path.name in {"LICENSE", "LICENSE.txt", "NOTICE", "package.xml"} or ( - len(path.parts) == 3 and path.parts[1] == "msg" and path.suffix == ".msg" - ): - target = ROOT / "schemas" / path - else: - continue - source = archive.extractfile(member) - assert source is not None - content = source.read() - if target == ROOT / "_vendor" / "rosidl_parser.py": - original = ( - b"VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z]([A-Z0-9_]?[A-Z0-9]+)*$')" - ) - replacement = ( - b"# DimOS patch: equivalent linear-time pattern; avoid nested ambiguous repetition.\n" - b"VALID_CONSTANT_NAME_PATTERN = re.compile('^[A-Z](?:[A-Z0-9]|_[A-Z0-9])*$')" - ) - assert content.count(original) == 1, "Recheck parser patch against upstream" - patches[str(target.relative_to(ROOT))] = { - "upstream_sha256": hashlib.sha256(content).hexdigest(), - "description": "Equivalent linear-time constant-name validation regex", - } - content = content.replace(original, replacement) - target.parent.mkdir(parents=True, exist_ok=True) - target.write_bytes(content) - files[str(target.relative_to(ROOT))] = hashlib.sha256(content).hexdigest() - provenance.append( - { - "repository": repository, - "revision": revision, - "files": dict(sorted(files.items())), - "patches": patches, - } - ) - print(f"{repository}@{revision}: {len(files)} files") - (ROOT / "sources.json").write_text(json.dumps(provenance, indent=2) + "\n") - - -if __name__ == "__main__": - main() From 2fbaf009118af2d56d9d550dab8bf0da275fdb0d Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 8 Oct 2026 13:17:34 -0700 Subject: [PATCH 13/55] docs: locate upstream maintenance in package review layer --- dimos/message_codegen/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dimos/message_codegen/README.md b/dimos/message_codegen/README.md index 811efc17367..421b8ca4b70 100644 --- a/dimos/message_codegen/README.md +++ b/dimos/message_codegen/README.md @@ -37,12 +37,12 @@ self-contained test definitions under `examples/message-codegen`. The parser's original copyright header is preserved. `rosidl_parser.pyi` is DimOS's type stub; the upstream implementation has one documented patch replacing an ambiguous constant-name regex with its linear-time equivalent. `sources.json` records both -the original and patched hashes; the maintenance script reapplies the patch. +the original and patched hashes. -To refresh the pinned inputs intentionally, edit the revisions in -`scripts/vendor_message_definitions.py`, then run that maintenance command with -`requests` installed. Review the source diff and update the conformance evidence. -Applications and builds never run the maintenance downloader. +The following message-package layer provides `scripts/vendor_message_definitions.py` +for intentional updates of pinned upstream inputs and reapplication of the parser +patch. It is not part of this standalone generator layer. Applications and builds +never run a maintenance downloader. This work is being delivered through the `replace-lcm-message-encoding` OpenSpec change. The generated pipeline is under development; the old runtime message APIs From 70eec802bc86bc45cdd803e7c74540627a5b01aa Mon Sep 17 00:00:00 2001 From: cc Date: Thu, 8 Oct 2026 18:21:41 -0700 Subject: [PATCH 14/55] refactor: delegate Python and C++ message declarations to upstream generators --- .github/workflows/message-codegen.yml | 2 +- dimos/message_codegen/README.md | 32 + dimos/message_codegen/_vendor/rosidl/LICENSE | 202 +++++ .../rosidl_runtime_c/message_initialization.h | 35 + .../rosidl_runtime_cpp/bounded_vector.hpp | 806 ++++++++++++++++++ .../message_initialization.hpp | 37 + .../rosidl/notices/rosidl_adapter/package.xml | 36 + .../notices/rosidl_generator_cpp/package.xml | 43 + .../rosidl/notices/rosidl_parser/package.xml | 32 + .../notices/rosidl_pycommon/package.xml | 28 + .../notices/rosidl_runtime_c/package.xml | 40 + .../notices/rosidl_runtime_cpp/package.xml | 35 + .../_vendor/rosidl/rosidl_adapter/__init__.py | 32 + .../rosidl/rosidl_adapter/__init__.pyi | 17 + .../rosidl/rosidl_adapter/msg/__init__.py | 115 +++ .../rosidl_adapter/resource/__init__.py | 110 +++ .../rosidl/rosidl_adapter/resource/msg.idl.em | 26 + .../rosidl_adapter/resource/struct.idl.em | 103 +++ .../rosidl/rosidl_generator_cpp/__init__.py | 344 ++++++++ .../resource/idl__struct.hpp.em | 86 ++ .../resource/msg__struct.hpp.em | 403 +++++++++ .../_vendor/rosidl/rosidl_parser/__init__.py | 0 .../rosidl/rosidl_parser/definition.py | 789 +++++++++++++++++ .../_vendor/rosidl/rosidl_parser/grammar.lark | 524 ++++++++++++ .../_vendor/rosidl/rosidl_parser/parser.py | 672 +++++++++++++++ .../rosidl/rosidl_pycommon/__init__.py | 250 ++++++ .../rosidl/rosidl_pycommon/__init__.pyi | 17 + .../_vendor/rosidl/sources.json | 117 +++ dimos/message_codegen/cpp.py | 131 ++- dimos/message_codegen/python.py | 51 +- dimos/message_codegen/templates/runtime.py | 12 - dimos/message_codegen/test_definitions.py | 10 + uv.lock | 23 + 33 files changed, 5078 insertions(+), 82 deletions(-) create mode 100644 dimos/message_codegen/_vendor/rosidl/LICENSE create mode 100644 dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_c/message_initialization.h create mode 100644 dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/bounded_vector.hpp create mode 100644 dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/message_initialization.hpp create mode 100644 dimos/message_codegen/_vendor/rosidl/notices/rosidl_adapter/package.xml create mode 100644 dimos/message_codegen/_vendor/rosidl/notices/rosidl_generator_cpp/package.xml create mode 100644 dimos/message_codegen/_vendor/rosidl/notices/rosidl_parser/package.xml create mode 100644 dimos/message_codegen/_vendor/rosidl/notices/rosidl_pycommon/package.xml create mode 100644 dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_c/package.xml create mode 100644 dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_cpp/package.xml create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.pyi create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_adapter/msg/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/msg.idl.em create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/struct.idl.em create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/idl__struct.hpp.em create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/msg__struct.hpp.em create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_parser/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_parser/definition.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_parser/grammar.lark create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_parser/parser.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.py create mode 100644 dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.pyi create mode 100644 dimos/message_codegen/_vendor/rosidl/sources.json diff --git a/.github/workflows/message-codegen.yml b/.github/workflows/message-codegen.yml index 8f08bcfd85b..57848158ef9 100644 --- a/.github/workflows/message-codegen.yml +++ b/.github/workflows/message-codegen.yml @@ -26,7 +26,7 @@ jobs: run: | test ! -d /opt/ros uv venv .venv --python 3.12 - uv pip install --python .venv/bin/python rosbags==0.11.0 numpy pytest pytest-asyncio pytest-env mypy==1.19.0 + uv pip install --python .venv/bin/python rosbags==0.11.0 empy==4.2 lark==1.2.2 numpy pytest pytest-asyncio pytest-env mypy==1.19.0 .venv/bin/python -c "import importlib.util; assert importlib.util.find_spec('rclpy') is None" - name: Build the pinned standalone CDR library run: bash scripts/setup_message_codegen.sh diff --git a/dimos/message_codegen/README.md b/dimos/message_codegen/README.md index 421b8ca4b70..fbbebb76ef0 100644 --- a/dimos/message_codegen/README.md +++ b/dimos/message_codegen/README.md @@ -52,3 +52,35 @@ Generation resolves only explicitly supplied roots by default in this layer. The following package layer provides bundled standard definitions. Raw LCM bus interop belongs to the runtime layer; this layer tests CDR bytes independently of transport. + +## Upstream generation and remaining adapters + +Python class declarations, annotations and constants come from pinned rosbags +0.11.0 `generate_python_code`, not a DimOS field-to-Python type emitter. A small +AST adapter attaches the existing Message base and maps array annotations to the +owned Sequence API. Standard dataclasses supply equality and representation. +The adapter preserves upstream generated-code attribution. + +Rosbags does not preserve declared field defaults in its emitted dataclasses. +The Message/Sequence runtime still supplies those defaults, constructor and +assignment validation, dependency-owned nested values, read-only borrowed views +and resize guards. Its malformed-input precheck still traverses CDR layout; it +must not be described as entirely library-owned serialization validation. + +C++ struct declarations, constructors, default values, constants, equality and +field types now come from the pinned upstream Jazzy `rosidl_generator_cpp`, using +`rosidl_adapter` for MSG-to-IDL conversion. Vendored upstream resources have a +separate revision/hash manifest under `_vendor/rosidl`; namespace relocation is +recorded. EmPy 4.2 and Lark 1.2.2 are build-time Python dependencies. Generated +headers include the minimal upstream runtime declarations, so consumers need no +ROS installation. DimOS still supplies metadata, validation and Fast CDR field +visitation. Bounded-vector adaptation currently copies through a standard vector; +this is not claimed as zero-copy. + +The Rust emitter has not yet been replaced. Actual compatibility probes +found that Fast-DDS-Gen 4.3.0 rejects array `@default({...})`, while ros2msg 0.5.3 +emits uncompilable string and floating-array defaults for the existing Telemetry +fixture. ROS Jazzy's C++ generator does preserve these defaults and public fields; +its types compile using only packaged runtime headers, without a ROS installation. +The bounded-vector codec adapter passes the same conformance checks. These are isolated +integration gaps, not evidence that an entire custom generator is necessary. diff --git a/dimos/message_codegen/_vendor/rosidl/LICENSE b/dimos/message_codegen/_vendor/rosidl/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_c/message_initialization.h b/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_c/message_initialization.h new file mode 100644 index 00000000000..8778594a39d --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_c/message_initialization.h @@ -0,0 +1,35 @@ +// Copyright 2017 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ROSIDL_RUNTIME_C__MESSAGE_INITIALIZATION_H_ +#define ROSIDL_RUNTIME_C__MESSAGE_INITIALIZATION_H_ + +enum rosidl_runtime_c__message_initialization +{ + // Initialize all fields of the message, either with the default value + // (if the field has one), or with an empty value (generally 0 or an + // empty string). + ROSIDL_RUNTIME_C_MSG_INIT_ALL, + // Skip initialization of all fields of the message. It is up to the user to + // ensure that all fields are initialized before use. + ROSIDL_RUNTIME_C_MSG_INIT_SKIP, + // Initialize all fields of the message to an empty value (generally 0 or an + // empty string). + ROSIDL_RUNTIME_C_MSG_INIT_ZERO, + // Initialize all fields of the message that have defaults; all other fields + // are left untouched. + ROSIDL_RUNTIME_C_MSG_INIT_DEFAULTS_ONLY, +}; + +#endif // ROSIDL_RUNTIME_C__MESSAGE_INITIALIZATION_H_ diff --git a/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/bounded_vector.hpp b/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/bounded_vector.hpp new file mode 100644 index 00000000000..2adc767d1c2 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/bounded_vector.hpp @@ -0,0 +1,806 @@ +// Copyright 2016 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ROSIDL_RUNTIME_CPP__BOUNDED_VECTOR_HPP_ +#define ROSIDL_RUNTIME_CPP__BOUNDED_VECTOR_HPP_ + +#include +#include +#include +#include +#include + +// GCC 13 has false positive warnings around stringop-overflow and array-bounds. +// The layout of a BoundedVector triggers these warnings. Suppress them +// until this is fixed in upstream gcc. See +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114758 for more details. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + +namespace rosidl_runtime_cpp +{ + +/// A container based on std::vector but with an upper bound. +/** + * Meets the same requirements as std::vector. + * + * \param Tp Type of element + * \param UpperBound The upper bound for the number of elements + * \param Alloc Allocator type, defaults to std::allocator + */ +template> +class BoundedVector + : protected std::vector +{ + using Base = std::vector; + +public: + using typename Base::value_type; + using typename Base::pointer; + using typename Base::const_pointer; + using typename Base::reference; + using typename Base::const_reference; + using typename Base::iterator; + using typename Base::const_iterator; + using typename Base::const_reverse_iterator; + using typename Base::reverse_iterator; + using typename Base::size_type; + using typename Base::difference_type; + using typename Base::allocator_type; + + /// Create a %BoundedVector with no elements. + BoundedVector() + noexcept (std::is_nothrow_default_constructible::value) + : Base() + {} + + /// Creates a %BoundedVector with no elements. + /** + * \param a An allocator object + */ + explicit + BoundedVector( + const typename Base::allocator_type & a) + noexcept + : Base(a) + {} + + /// Create a %BoundedVector with default constructed elements. + /** + * This constructor fills the %BoundedVector with @a n default + * constructed elements. + * + * \param n The number of elements to initially create + * \param a An allocator + */ + explicit + BoundedVector( + typename Base::size_type n, + const typename Base::allocator_type & a = allocator_type()) + : Base(n, a) + { + if (n > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + } + + /// Create a %BoundedVector with copies of an exemplar element. + /** + * This constructor fills the %BoundedVector with @a n copies of @a value. + * + * \param n The number of elements to initially create + * \param value An element to copy + * \param a An allocator + */ + BoundedVector( + typename Base::size_type n, + const typename Base::value_type & value, + const typename Base::allocator_type & a = allocator_type()) + : Base(n, value, a) + { + if (n > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + } + + /// %BoundedVector copy constructor. + /** + * The newly-created %BoundedVector uses a copy of the allocation + * object used by @a x. + * All the elements of @a x are copied, but any extra memory in + * @a x (for fast expansion) will not be copied. + * + * \param x A %BoundedVector of identical element and allocator types + */ + BoundedVector( + const BoundedVector & x) + : Base(x) + {} + + /// %BoundedVector move constructor. + /** + * The newly-created %BoundedVector contains the exact contents of @a x. + * The contents of @a x are a valid, but unspecified %BoundedVector. + * + * \param x A %BoundedVector of identical element and allocator types + */ + BoundedVector(BoundedVector && x) noexcept + : Base(std::move(x)) + {} + + /// Copy constructor with alternative allocator + BoundedVector(const BoundedVector & x, const typename Base::allocator_type & a) + : Base(x, a) + {} + + /// Build a %BoundedVector from an initializer list. + /** + * Create a %BoundedVector consisting of copies of the elements in the + * initializer_list @a l. + * + * This will call the element type's copy constructor N times + * (where N is @a l.size()) and do no memory reallocation. + * + * \param l An initializer_list + * \param a An allocator + */ + BoundedVector( + std::initializer_list l, + const typename Base::allocator_type & a = typename Base::allocator_type()) + : Base(l, a) + { + if (l.size() > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + } + + /// Build a %BoundedVector from a range. + /** + * Create a %BoundedVector consisting of copies of the elements from + * [first,last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. + * But if only input iterators are used, then this will do at most 2N + * calls to the copy constructor, and logN memory reallocations. + * + * \param first An input iterator + * \param last An input iterator + * \param a An allocator + */ + template< + typename InputIterator + > + BoundedVector( + InputIterator first, + InputIterator last, + const typename Base::allocator_type & a = allocator_type()) + : Base(first, last, a) + { + if (size() > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + } + + /// The dtor only erases the elements. + /** + * Note that if the elements themselves are pointers, the pointed-to + * memory is not touched in any way. + * Managing the pointer is the user's responsibility. + */ + ~BoundedVector() noexcept + {} + + /// %BoundedVector assignment operator. + /** + * All the elements of @a x are copied, but any extra memory in + * @a x (for fast expansion) will not be copied. + * Unlike the copy constructor, the allocator object is not copied. + * + * \param x A %BoundedVector of identical element and allocator types + */ + BoundedVector & + operator=(const BoundedVector & x) + { + (void)Base::operator=(x); + return *this; + } + + /// %BoundedVector move assignment operator + /** + * \param x A %BoundedVector of identical element and allocator types. + */ + BoundedVector & + operator=(BoundedVector && x) + { + (void)Base::operator=(std::move(x)); + return *this; + } + + /// %BoundedVector list assignment operator. + /** + * This function fills a %BoundedVector with copies of the elements in + * the initializer list @a l. + * + * Note that the assignment completely changes the %BoundedVector and + * that the resulting %BoundedVector's size is the same as the number + * of elements assigned. + * Old data may be lost. + * + * \param l An initializer_list + */ + BoundedVector & + operator=(std::initializer_list l) + { + if (l.size() > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::operator=(l); + return *this; + } + + /// Assign a given value to a %BoundedVector. + /** + * This function fills a %BoundedVector with @a n copies of the + * given value. + * Note that the assignment completely changes the %BoundedVector and + * that the resulting %BoundedVector's size is the same as the number + * of elements assigned. + * Old data may be lost. + * + * \param n Number of elements to be assigned + * \param val Value to be assigned + */ + void + assign( + typename Base::size_type n, + const typename Base::value_type & val) + { + if (n > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::assign(n, val); + } + + /// Assign a range to a %BoundedVector. + /** + * This function fills a %BoundedVector with copies of the elements in + * the range [first,last). + * + * Note that the assignment completely changes the %BoundedVector and + * that the resulting %BoundedVector's size is the same as the number + * of elements assigned. + * Old data may be lost. + * + * \param first An input iterator + * \param last An input iterator + */ + template< + typename InputIterator + > + void + assign(InputIterator first, InputIterator last) + { + using cat = typename std::iterator_traits::iterator_category; + do_assign(first, last, cat()); + } + + /// Assign an initializer list to a %BoundedVector. + /** + * This function fills a %BoundedVector with copies of the elements in + * the initializer list @a l. + * + * Note that the assignment completely changes the %BoundedVector and + * that the resulting %BoundedVector's size is the same as the number + * of elements assigned. + * Old data may be lost. + * + * \param l An initializer_list + */ + void + assign(std::initializer_list l) + { + if (l.size() > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::assign(l); + } + + using Base::begin; + using Base::end; + using Base::rbegin; + using Base::rend; + using Base::cbegin; + using Base::cend; + using Base::crbegin; + using Base::crend; + using Base::size; + + /** Returns the size() of the largest possible %BoundedVector. */ + typename Base::size_type + max_size() const noexcept + { + return std::min(UpperBound, Base::max_size()); + } + + /// Resize the %BoundedVector to the specified number of elements. + /** + * This function will %resize the %BoundedVector to the specified + * number of elements. + * If the number is smaller than the %BoundedVector's current size the + * %BoundedVector is truncated, otherwise default constructed elements + * are appended. + * + * \param new_size Number of elements the %BoundedVector should contain + */ + void + resize(typename Base::size_type new_size) + { + if (new_size > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::resize(new_size); + } + + /// Resize the %BoundedVector to the specified number of elements. + /** + * This function will %resize the %BoundedVector to the specified + * number of elements. + * If the number is smaller than the %BoundedVector's current size the + * %BoundedVector is truncated, otherwise the %BoundedVector is + * extended and new elements are populated with given data. + * + * \param new_size Number of elements the %BoundedVector should contain + * \param x Data with which new elements should be populated + */ + void + resize( + typename Base::size_type new_size, + const typename Base::value_type & x) + { + if (new_size > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::resize(new_size, x); + } + + using Base::shrink_to_fit; + using Base::capacity; + using Base::empty; + + /// Attempt to preallocate enough memory for specified number of elements. + /** + * This function attempts to reserve enough memory for the + * %BoundedVector to hold the specified number of elements. + * If the number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the number of elements that + * will be required, the user can reserve the memory in %advance, and + * thus prevent a possible reallocation of memory and copying of + * %BoundedVector data. + * + * \param n Number of elements required + * @throw std::length_error If @a n exceeds @c max_size() + */ + void + reserve(typename Base::size_type n) + { + if (n > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::reserve(n); + } + + using Base::operator[]; + using Base::at; + using Base::front; + using Base::back; + + /// Return a pointer such that [data(), data() + size()) is a valid range. + /** + * For a non-empty %BoundedVector, data() == &front(). + */ + template< + typename T, + typename std::enable_if< + !std::is_same::value && + !std::is_same::value + >::type * = nullptr + > + T * + data() noexcept + { + return Base::data(); + } + + template< + typename T, + typename std::enable_if< + !std::is_same::value && + !std::is_same::value + >::type * = nullptr + > + const T * + data() const noexcept + { + return Base::data(); + } + + /// Add data to the end of the %BoundedVector. + /** + * This is a typical stack operation. + * The function creates an element at the end of the %BoundedVector + * and assigns the given data to it. + * Due to the nature of a %BoundedVector this operation can be done in + * constant time if the %BoundedVector has preallocated space + * available. + * + * \param x Data to be added + */ + void + push_back(const typename Base::value_type & x) + { + if (size() >= UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::push_back(x); + } + + void + push_back(typename Base::value_type && x) + { + if (size() >= UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::push_back(x); + } + + /// Add data to the end of the %BoundedVector. + /** + * This is a typical stack operation. + * The function creates an element at the end of the %BoundedVector + * and assigns the given data to it. + * Due to the nature of a %BoundedVector this operation can be done in + * constant time if the %BoundedVector has preallocated space + * available. + * + * \param args Arguments to be forwarded to the constructor of Tp + */ + template + typename Base::reference + emplace_back(Args && ... args) + { + if (size() >= UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + return Base::emplace_back(std::forward(args)...); + } + + /// Insert an object in %BoundedVector before specified iterator. + /** + * This function will insert an object of type T constructed with + * T(std::forward(args)...) before the specified location. + * Note that this kind of operation could be expensive for a + * %BoundedVector and if it is frequently used the user should + * consider using std::list. + * + * \param position A const_iterator into the %BoundedVector + * \param args Arguments + * \return An iterator that points to the inserted data + */ + template + typename Base::iterator + emplace( + typename Base::const_iterator position, + Args && ... args) + { + if (size() >= UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + return Base::emplace(position, std::forward(args) ...); + } + + /// Insert given value into %BoundedVector before specified iterator. + /** + * This function will insert a copy of the given value before the + * specified location. + * Note that this kind of operation could be expensive for a + * %BoundedVector and if it is frequently used the user should + * consider using std::list. + * + * \param position A const_iterator into the %BoundedVector + * \param x Data to be inserted + * \return An iterator that points to the inserted data + */ + typename Base::iterator + insert( + typename Base::const_iterator position, + const typename Base::value_type & x) + { + if (size() >= UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + return Base::insert(position, x); + } + + /// Insert given rvalue into %BoundedVector before specified iterator. + /** + * This function will insert a copy of the given rvalue before the + * specified location. + * Note that this kind of operation could be expensive for a + * %BoundedVector and if it is frequently used the user should + * consider using std::list. + * + * \param position A const_iterator into the %BoundedVector + * \param x Data to be inserted + * \return An iterator that points to the inserted data + */ + typename Base::iterator + insert( + typename Base::const_iterator position, + typename Base::value_type && x) + { + if (size() >= UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + return Base::insert(position, x); + } + + /// Insert an initializer_list into the %BoundedVector. + /** + * This function will insert copies of the data in the + * initializer_list @a l into the %BoundedVector before the location + * specified by @a position. + * + * Note that this kind of operation could be expensive for a + * %BoundedVector and if it is frequently used the user should + * consider using std::list. + * + * \param position An iterator into the %BoundedVector + * \param l An initializer_list + */ + typename Base::iterator + insert( + typename Base::const_iterator position, + std::initializer_list l) + { + if (size() + l.size() > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + return Base::insert(position, l); + } + + /// Insert a number of copies of given data into the %BoundedVector. + /** + * This function will insert a specified number of copies of the given + * data before the location specified by @a position. + * + * Note that this kind of operation could be expensive for a + * %BoundedVector and if it is frequently used the user should + * consider using std::list. + * + * \param position A const_iterator into the %BoundedVector + * \param n Number of elements to be inserted + * \param x Data to be inserted + * \return An iterator that points to the inserted data + */ + typename Base::iterator + insert( + typename Base::const_iterator position, + typename Base::size_type n, + const typename Base::value_type & x) + { + if (size() + n > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + return Base::insert(position, n, x); + } + + /// Insert a range into the %BoundedVector. + /** + * This function will insert copies of the data in the range + * [first,last) into the %BoundedVector before the location + * specified by @a pos. + * + * Note that this kind of operation could be expensive for a + * %BoundedVector and if it is frequently used the user should + * consider using std::list. + * + * \param position A const_iterator into the %BoundedVector + * \param first An input iterator + * \param last An input iterator + * \return An iterator that points to the inserted data + */ + template< + typename InputIterator + > + typename Base::iterator + insert( + typename Base::const_iterator position, + InputIterator first, + InputIterator last) + { + using cat = typename std::iterator_traits::iterator_category; + return do_insert(position, first, last, cat()); + } + + using Base::erase; + using Base::pop_back; + using Base::clear; + +private: + /// Assign elements from an input range. + template< + typename InputIterator + > + void + do_assign(InputIterator first, InputIterator last, std::input_iterator_tag) + { + BoundedVector(first, last).swap(*this); + } + + /// Assign elements from a forward range. + template< + typename FwdIterator + > + void + do_assign(FwdIterator first, FwdIterator last, std::forward_iterator_tag) + { + if (static_cast(std::distance(first, last)) > UpperBound) { + throw std::length_error("Exceeded upper bound"); + } + Base::assign(first, last); + } + + // Insert each value at the end and then rotate them to the desired position. + // If the bound is exceeded, the inserted elements are removed again. + template< + typename InputIterator + > + typename Base::iterator + do_insert( + typename Base::const_iterator position, + InputIterator first, + InputIterator last, + std::input_iterator_tag) + { + const auto orig_size = size(); + const auto idx = position - cbegin(); + try { + while (first != last) { + push_back(*first++); + } + } catch (const std::length_error &) { + Base::resize(orig_size); + throw; + } + auto pos = begin() + idx; + std::rotate(pos, begin() + orig_size, end()); + return begin() + idx; + } + + template< + typename FwdIterator + > + typename Base::iterator + do_insert( + typename Base::const_iterator position, + FwdIterator first, + FwdIterator last, + std::forward_iterator_tag) + { + auto dist = std::distance(first, last); + if ((dist < 0) || (size() + static_cast(dist) > UpperBound)) { + throw std::length_error("Exceeded upper bound"); + } + return Base::insert(position, first, last); + } + + /// Vector equality comparison. + /** + * This is an equivalence relation. + * It is linear in the size of the vectors. + * Vectors are considered equivalent if their sizes are equal, and if + * corresponding elements compare equal. + * + * \param x A %BoundedVector + * \param y A %BoundedVector of the same type as @a x + * \return True if the size and elements of the vectors are equal + */ + friend bool + operator==( + const BoundedVector & x, + const BoundedVector & y) + { + return static_cast(x) == static_cast(y); + } + + /// Vector ordering relation. + /** + * This is a total ordering relation. + * It is linear in the size of the vectors. + * The elements must be comparable with @c <. + * + * See std::lexicographical_compare() for how the determination is made. + * + * \param x A %BoundedVector + * \param y A %BoundedVector of the same type as @a x + * @return True if @a x is lexicographically less than @a y + */ + friend bool + operator<( + const BoundedVector & x, + const BoundedVector & y) + { + return static_cast(x) < static_cast(y); + } + + /// Based on operator== + friend bool + operator!=( + const BoundedVector & x, + const BoundedVector & y) + { + return static_cast(x) != static_cast(y); + } + + /// Based on operator< + friend bool + operator>( + const BoundedVector & x, + const BoundedVector & y) + { + return static_cast(x) > static_cast(y); + } + + /// Based on operator< + friend bool + operator<=( + const BoundedVector & x, + const BoundedVector & y) + { + return static_cast(x) <= static_cast(y); + } + + /// Based on operator< + friend bool + operator>=( + const BoundedVector & x, + const BoundedVector & y) + { + return static_cast(x) >= static_cast(y); + } +}; + +/// See rosidl_runtime_cpp::BoundedVector::swap(). +template +inline void +swap(BoundedVector & x, BoundedVector & y) +{ + x.swap(y); +} + +} // namespace rosidl_runtime_cpp + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +#endif // ROSIDL_RUNTIME_CPP__BOUNDED_VECTOR_HPP_ diff --git a/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/message_initialization.hpp b/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/message_initialization.hpp new file mode 100644 index 00000000000..52d0167d430 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/include/rosidl_runtime_cpp/message_initialization.hpp @@ -0,0 +1,37 @@ +// Copyright 2017 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ROSIDL_RUNTIME_CPP__MESSAGE_INITIALIZATION_HPP_ +#define ROSIDL_RUNTIME_CPP__MESSAGE_INITIALIZATION_HPP_ + +#include + +namespace rosidl_runtime_cpp +{ + +/// Enum utilized in rosidl generated sources for describing how members are initialized. +/** + * See the documentation for the `rosidl_runtime_c__message_initialization` enum for more information. + */ +enum class MessageInitialization +{ + ALL = ROSIDL_RUNTIME_C_MSG_INIT_ALL, + SKIP = ROSIDL_RUNTIME_C_MSG_INIT_SKIP, + ZERO = ROSIDL_RUNTIME_C_MSG_INIT_ZERO, + DEFAULTS_ONLY = ROSIDL_RUNTIME_C_MSG_INIT_DEFAULTS_ONLY, +}; + +} // namespace rosidl_runtime_cpp + +#endif // ROSIDL_RUNTIME_CPP__MESSAGE_INITIALIZATION_HPP_ diff --git a/dimos/message_codegen/_vendor/rosidl/notices/rosidl_adapter/package.xml b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_adapter/package.xml new file mode 100644 index 00000000000..49ac663bf15 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_adapter/package.xml @@ -0,0 +1,36 @@ + + + + rosidl_adapter + 4.6.9 + + API and scripts to parse .msg/.srv/.action files and convert them to .idl. + + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + + ament_cmake_core + python3 + + ament_cmake + + python3-empy + rosidl_cli + + ament_cmake_pytest + ament_lint_common + ament_lint_auto + + + ament_cmake + + diff --git a/dimos/message_codegen/_vendor/rosidl/notices/rosidl_generator_cpp/package.xml b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_generator_cpp/package.xml new file mode 100644 index 00000000000..eb32188adfd --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_generator_cpp/package.xml @@ -0,0 +1,43 @@ + + + + rosidl_generator_cpp + 4.6.9 + Generate the ROS interfaces in C++. + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + + ament_cmake + + ament_cmake_core + python3 + rosidl_pycommon + + rosidl_cmake + + rosidl_generator_c + rosidl_runtime_cpp + + ament_index_python + rosidl_cli + rosidl_generator_type_description + rosidl_parser + + ament_lint_auto + ament_lint_common + + rosidl_generator_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/_vendor/rosidl/notices/rosidl_parser/package.xml b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_parser/package.xml new file mode 100644 index 00000000000..9bac59b2438 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_parser/package.xml @@ -0,0 +1,32 @@ + + + + rosidl_parser + 4.6.9 + The parser for `.idl` ROS interface files. + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + + ament_cmake + + python3-lark-parser + rosidl_adapter + + ament_cmake_pytest + ament_lint_auto + ament_lint_common + python3-pytest + + + ament_cmake + + diff --git a/dimos/message_codegen/_vendor/rosidl/notices/rosidl_pycommon/package.xml b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_pycommon/package.xml new file mode 100644 index 00000000000..b731e30e415 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_pycommon/package.xml @@ -0,0 +1,28 @@ + + + + rosidl_pycommon + 4.6.9 + Common Python functions used by rosidl packages. + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Jacob Perron + Michel Hidalgo + + rosidl_parser + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_c/package.xml b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_c/package.xml new file mode 100644 index 00000000000..ea52726c235 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_c/package.xml @@ -0,0 +1,40 @@ + + + + rosidl_runtime_c + 4.6.9 + Provides definitions, initialization and finalization functions, and macros for getting and working with rosidl typesupport types in C. + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + William Woodall + + ament_cmake_ros + + rosidl_typesupport_interface + + ament_cmake + + rosidl_typesupport_interface + + rcutils + + ament_cmake_gtest + ament_lint_auto + ament_lint_common + performance_test_fixture + + rosidl_runtime_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_cpp/package.xml b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_cpp/package.xml new file mode 100644 index 00000000000..66e148555ce --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/notices/rosidl_runtime_cpp/package.xml @@ -0,0 +1,35 @@ + + + + rosidl_runtime_cpp + 4.6.9 + Provides definitions and templated functions for getting and working with rosidl typesupport types in C++. + + Aditya Pande + Brandon Ong + Dharini Dutia + Shane Loretz + + Apache License 2.0 + + Chris Lalancette + Dirk Thomas + Michel Hidalgo + + ament_cmake + + ament_cmake + + rosidl_runtime_c + + ament_cmake_gtest + ament_lint_auto + ament_lint_common + performance_test_fixture + + rosidl_runtime_packages + + + ament_cmake + + diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.py b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.py new file mode 100644 index 00000000000..39f9161e28f --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.py @@ -0,0 +1,32 @@ +# Copyright 2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def convert_to_idl(package_dir, package_name, interface_file, output_dir): + if interface_file.suffix == '.msg': + from dimos.message_codegen._vendor.rosidl.rosidl_adapter.msg import convert_msg_to_idl + return convert_msg_to_idl( + package_dir, package_name, interface_file, output_dir / 'msg') + + if interface_file.suffix == '.srv': + from dimos.message_codegen._vendor.rosidl.rosidl_adapter.srv import convert_srv_to_idl + return convert_srv_to_idl( + package_dir, package_name, interface_file, output_dir / 'srv') + + if interface_file.suffix == '.action': + from dimos.message_codegen._vendor.rosidl.rosidl_adapter.action import convert_action_to_idl + return convert_action_to_idl( + package_dir, package_name, interface_file, output_dir / 'action') + + assert False, f"Unsupported interface type '{interface_file.suffix}'" diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.pyi b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.pyi new file mode 100644 index 00000000000..14724a92c16 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/__init__.pyi @@ -0,0 +1,17 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pathlib import Path + +def convert_to_idl(package_dir: Path, package_name: str, interface_file: Path, output_dir: Path) -> Path: ... diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/msg/__init__.py b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/msg/__init__.py new file mode 100644 index 00000000000..68ec6742267 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/msg/__init__.py @@ -0,0 +1,115 @@ +# Copyright 2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from dimos.message_codegen._vendor.rosidl_parser import parse_message_string +from dimos.message_codegen._vendor.rosidl.rosidl_adapter.resource import expand_template + + +def convert_msg_to_idl(package_dir, package_name, input_file, output_dir): + assert package_dir.is_absolute() + assert not input_file.is_absolute() + assert input_file.suffix == '.msg' + + abs_input_file = package_dir / input_file + print(f'Reading input file: {abs_input_file}') + abs_input_file = package_dir / input_file + content = abs_input_file.read_text(encoding='utf-8') + msg = parse_message_string(package_name, input_file.stem, content) + + output_file = output_dir / input_file.with_suffix('.idl').name + abs_output_file = output_file.absolute() + print(f'Writing output file: {abs_output_file}') + data = { + 'pkg_name': package_name, + 'relative_input_file': input_file.as_posix(), + 'msg': msg, + } + + expand_template('msg.idl.em', data, output_file, encoding='iso-8859-1') + return output_file + + +MSG_TYPE_TO_IDL = { + 'bool': 'boolean', + 'byte': 'octet', + 'char': 'uint8', + 'int8': 'int8', + 'uint8': 'uint8', + 'int16': 'int16', + 'uint16': 'uint16', + 'int32': 'int32', + 'uint32': 'uint32', + 'int64': 'int64', + 'uint64': 'uint64', + 'float32': 'float', + 'float64': 'double', + 'string': 'string', + 'wstring': 'wstring', +} + + +def to_idl_literal(idl_type, value): + if idl_type[-1] == ']' or idl_type.startswith('sequence<'): + content = repr(tuple(value)).replace('\\', r'\\').replace('"', r'\"') + return f'"{content}"' + + if 'boolean' == idl_type: + return 'TRUE' if value else 'FALSE' + if idl_type.startswith('string'): + return string_to_idl_string_literal(value) + if idl_type.startswith('wstring'): + return string_to_idl_wstring_literal(value) + return value + + +def string_to_idl_string_literal(string): + """Convert string to character literal as described in IDL 4.2 section 7.2.6.3 .""" + estr = string.encode().decode('unicode_escape') + estr = estr.replace('"', r'\"') + return '"{0}"'.format(estr) + + +def string_to_idl_wstring_literal(string): + return string_to_idl_string_literal(string) + + +def get_include_file(base_type): + if base_type.is_primitive_type(): + return None + return f'{base_type.pkg_name}/msg/{base_type.type}.idl' + + +def get_idl_type(type_): + if isinstance(type_, str): + identifier = MSG_TYPE_TO_IDL[type_] + elif type_.is_primitive_type(): + identifier = MSG_TYPE_TO_IDL[type_.type] + if ( + identifier in ('string', 'wstring') and + type_.string_upper_bound is not None + ): + identifier += f'<{type_.string_upper_bound}>' + else: + identifier = f'{type_.pkg_name}::msg::{type_.type}' + + if isinstance(type_, str) or not type_.is_array: + return identifier + + if type_.is_fixed_size_array(): + return f'{identifier}[{type_.array_size}]' + + if not type_.is_upper_bound: + return f'sequence<{identifier}>' + + return f'sequence<{identifier}, {type_.array_size}>' diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/__init__.py b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/__init__.py new file mode 100644 index 00000000000..b629021a105 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/__init__.py @@ -0,0 +1,110 @@ +# Copyright 2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from io import StringIO +import os +import sys + +import em + +try: + from em import Configuration + em_has_configuration = True +except ImportError: + em_has_configuration = False + + +def expand_template(template_name, data, output_file, encoding='utf-8'): + content = evaluate_template(template_name, data) + + if output_file.exists(): + existing_content = output_file.read_text(encoding=encoding) + if existing_content == content: + return + elif output_file.parent: + os.makedirs(str(output_file.parent), exist_ok=True) + + output_file.write_text(content, encoding=encoding) + + +_interpreter = None + + +def evaluate_template(template_name, data): + global _interpreter + # create copy before manipulating + data = dict(data) + data['TEMPLATE'] = _evaluate_template + + template_path = os.path.join(os.path.dirname(__file__), template_name) + + output = StringIO() + try: + if em_has_configuration: + config = Configuration( + defaultRoot=template_path, + defaultStdout=output, + deleteOnError=True, + rawErrors=True, + useProxy=True) + _interpreter = em.Interpreter( + config=config, + dispatcher=False) + else: + _interpreter = em.Interpreter( + output=output, + options={ + em.BUFFERED_OPT: True, + em.RAW_OPT: True, + }) + with open(template_path, 'r') as h: + content = h.read() + _interpreter.invoke( + 'beforeFile', name=template_name, file=h, locals=data) + if em_has_configuration: + _interpreter.string(content, locals=data) + else: + _interpreter.string(content, template_path, locals=data) + _interpreter.invoke('afterFile') + + return output.getvalue() + except Exception as e: # noqa: F841 + print( + f"{e.__class__.__name__} processing template '{template_name}'", + file=sys.stderr) + raise + finally: + if _interpreter is not None: + _interpreter.shutdown() + _interpreter = None + + +def _evaluate_template(template_name, **kwargs): + global _interpreter + template_path = os.path.join(os.path.dirname(__file__), template_name) + with open(template_path, 'r') as h: + _interpreter.invoke( + 'beforeInclude', name=template_path, file=h, locals=kwargs) + content = h.read() + try: + if em_has_configuration: + _interpreter.string(content, locals=kwargs) + else: + _interpreter.string(content, template_path, kwargs) + except Exception as e: # noqa: F841 + print( + f"{e.__class__.__name__} processing template '{template_name}': " + f'{e}', file=sys.stderr) + sys.exit(1) + _interpreter.invoke('afterInclude') diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/msg.idl.em b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/msg.idl.em new file mode 100644 index 00000000000..26897a3dff4 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/msg.idl.em @@ -0,0 +1,26 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from @(pkg_name)/@(relative_input_file) +// generated code does not contain a copyright notice + +@{ +from dimos.message_codegen._vendor.rosidl.rosidl_adapter.msg import get_include_file +include_files = set() +for field in msg.fields: + include_file = get_include_file(field.type) + if include_file is not None: + include_files.add(include_file) +}@ +@[for include_file in sorted(include_files)]@ +#include "@(include_file)" +@[end for]@ + +module @(pkg_name) { + module msg { +@{ +TEMPLATE( + 'struct.idl.em', + msg=msg, +) +}@ + }; +}; diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/struct.idl.em b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/struct.idl.em new file mode 100644 index 00000000000..761e19966c8 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_adapter/resource/struct.idl.em @@ -0,0 +1,103 @@ +@#typedefs for arrays need to be defined outside of the struct +@{ +from collections import OrderedDict + +from dimos.message_codegen._vendor.rosidl.rosidl_adapter.msg import get_idl_type +from dimos.message_codegen._vendor.rosidl.rosidl_adapter.msg import to_idl_literal +from dimos.message_codegen._vendor.rosidl.rosidl_adapter.msg import string_to_idl_string_literal + +typedefs = OrderedDict() +def get_idl_type_identifier(idl_type): + return idl_type.replace('::', '__') \ + .replace('<', '__').replace('>', '') \ + .replace('[', '__').replace(']', '') +}@ +@[for field in msg.fields]@ +@{ +idl_type = get_idl_type(field.type) +}@ +@[ if field.type.is_fixed_size_array()]@ +@{ +idl_base_type = idl_type.split('[', 1)[0] +idl_base_type_identifier = idl_base_type.replace('::', '__') +# only necessary for complex types +if idl_base_type_identifier != idl_base_type: + if idl_base_type_identifier not in typedefs: + typedefs[idl_base_type_identifier] = idl_base_type + else: + assert typedefs[idl_base_type_identifier] == idl_base_type +idl_type_identifier = get_idl_type_identifier(idl_type) + '[' + str(field.type.array_size) + ']' +if idl_type_identifier not in typedefs: + typedefs[idl_type_identifier] = idl_base_type_identifier +else: + assert typedefs[idl_type_identifier] == idl_base_type_identifier +}@ +@[ end if]@ +@[end for]@ +@[for k, v in typedefs.items()]@ + typedef @(v) @(k); +@[end for]@ +@[if msg.constants]@ + module @(msg.msg_name)_Constants { +@[ for constant in msg.constants]@ +@[ if constant.annotations.get('comment', [])]@ + @@verbatim (language="comment", text= +@[ for i, line in enumerate(constant.annotations['comment'])]@ + @(string_to_idl_string_literal(line))@ +@[ if i < len(constant.annotations.get('comment')) - 1]@ + "\n"@ +@[ end if]@ +@[ end for]@ +) +@[ end if]@ + const @(get_idl_type(constant.type)) @(constant.name) = @(to_idl_literal(get_idl_type(constant.type), constant.value)); +@[ end for]@ + }; +@[end if]@ +@# +@[if msg.annotations.get('comment', [])]@ + @@verbatim (language="comment", text=@ +@[ for i, line in enumerate(msg.annotations['comment'])] + @(string_to_idl_string_literal(line))@ +@[ if i < len(msg.annotations.get('comment')) - 1]@ + "\n"@ +@[ end if]@ +@[ end for]@ +) +@[end if]@ + struct @(msg.msg_name) { +@[if msg.fields]@ +@[ for i, field in enumerate(msg.fields)]@ +@[ if i > 0]@ + +@[ end if]@ +@[ if field.annotations.get('comment', [])]@ + @@verbatim (language="comment", text=@ +@[ for j, line in enumerate(field.annotations['comment'])] + @(string_to_idl_string_literal(line))@ +@[ if j < len(field.annotations.get('comment')) - 1]@ + "\n"@ +@[ end if]@ +@[ end for]@ +) +@[ end if]@ +@[ if field.default_value is not None]@ + @@default (value=@(to_idl_literal(get_idl_type(field.type), field.default_value))) +@[ end if]@ +@[ if 'unit' in field.annotations]@ + @@unit (value=@(string_to_idl_string_literal(field.annotations['unit']))) +@[ end if]@ +@{ +idl_type = get_idl_type(field.type) +}@ +@[ if field.type.is_fixed_size_array()]@ +@{ +idl_type = get_idl_type_identifier(idl_type) +}@ +@[ end if]@ + @(idl_type) @(field.name); +@[ end for]@ +@[else]@ + uint8 structure_needs_at_least_one_member; +@[end if]@ + }; diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/__init__.py b/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/__init__.py new file mode 100644 index 00000000000..25dbde62b00 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/__init__.py @@ -0,0 +1,344 @@ +# Copyright 2014-2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ast import literal_eval + +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractGenericString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractNestedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractSequence +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractWString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Array +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BasicType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BoundedSequence +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import FLOATING_POINT_TYPES +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import NamespacedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import UnboundedSequence +from dimos.message_codegen._vendor.rosidl.rosidl_pycommon import generate_files + + +def generate_cpp(generator_arguments_file): + mapping = { + 'idl.hpp.em': '%s.hpp', + 'idl__builder.hpp.em': 'detail/%s__builder.hpp', + 'idl__struct.hpp.em': 'detail/%s__struct.hpp', + 'idl__traits.hpp.em': 'detail/%s__traits.hpp', + 'idl__type_support.hpp.em': 'detail/%s__type_support.hpp', + } + return generate_files( + generator_arguments_file, mapping, + post_process_callback=prefix_with_bom_if_necessary) + + +def prefix_with_bom_if_necessary(content): + try: + content.encode('ASCII') + except UnicodeError: + prefix = '\ufeff' + \ + '// NOLINT: This file starts with a BOM ' + \ + 'since it contain non-ASCII characters\n' + content = prefix + content + return content + + +MSG_TYPE_TO_CPP = { + 'boolean': 'bool', + 'octet': 'unsigned char', # TODO change to std::byte with C++17 + 'char': 'unsigned char', + 'wchar': 'char16_t', + 'float': 'float', + 'double': 'double', + 'long double': 'long double', + 'uint8': 'uint8_t', + 'int8': 'int8_t', + 'uint16': 'uint16_t', + 'int16': 'int16_t', + 'uint32': 'uint32_t', + 'int32': 'int32_t', + 'uint64': 'uint64_t', + 'int64': 'int64_t', + 'string': 'std::basic_string, ' + + 'typename std::allocator_traits::template rebind_alloc>', + 'wstring': 'std::basic_string, typename ' + + 'std::allocator_traits::template rebind_alloc>', +} + + +def msg_type_only_to_cpp(type_): + """ + Convert a message type into the C++ declaration, ignoring array types. + + Example input: uint32, std_msgs/String + Example output: uint32_t, std_msgs::String_ + + @param type_: The message type + @type type_: rosidl_parser.Type + """ + if isinstance(type_, AbstractNestedType): + type_ = type_.value_type + if isinstance(type_, BasicType): + cpp_type = MSG_TYPE_TO_CPP[type_.typename] + elif isinstance(type_, AbstractString): + cpp_type = MSG_TYPE_TO_CPP['string'] + elif isinstance(type_, AbstractWString): + cpp_type = MSG_TYPE_TO_CPP['wstring'] + elif isinstance(type_, NamespacedType): + typename = '::'.join(type_.namespaced_name()) + cpp_type = typename + '_' + else: + assert False, type_ + + return cpp_type + + +def msg_type_to_cpp(type_): + """ + Convert a message type into the C++ declaration, along with the array type. + + Example input: uint32, std_msgs/String, std_msgs/String[3] + Example output: uint32_t, std_msgs::String_, + std::array, 3> + + @param type_: The message type + @type type_: rosidl_parser.Type + """ + cpp_type = msg_type_only_to_cpp(type_) + + if isinstance(type_, AbstractNestedType): + if isinstance(type_, UnboundedSequence): + return \ + ('std::vector<%s, typename std::allocator_traits::template ' + + 'rebind_alloc<%s>>') % (cpp_type, cpp_type) + elif isinstance(type_, BoundedSequence): + return \ + ('rosidl_runtime_cpp::BoundedVector<%s, %u, typename std::allocator_traits' + + '::template rebind_alloc<%s>>') % (cpp_type, + type_.maximum_size, + cpp_type) + else: + assert isinstance(type_, Array) + return 'std::array<%s, %u>' % (cpp_type, type_.size) + else: + return cpp_type + + +def value_to_cpp(type_, value): + """ + Convert a python value into a string representing that value in C++. + + This is equivalent to primitive_value_to_cpp but can process arrays values as well + + Warning this still processes only primitive types + @param type_: a ROS IDL type + @type type_: builtin.str + @param value: the value to convert + @type value: python builtin (bool, int, float, str or list) + @returns: a string containing the C++ representation of the value + """ + assert not isinstance(type_, NamespacedType), \ + "Could not convert non-primitive type '%s' to CPP" % (type_) + assert value is not None, "Value for type '%s' must not be None" % (type_) + + if not isinstance(type_, AbstractNestedType): + return primitive_value_to_cpp(type_, value) + + cpp_values = [] + is_string_array = isinstance(type_.value_type, AbstractGenericString) + for single_value in value: + cpp_value = primitive_value_to_cpp(type_.value_type, single_value) + if is_string_array: + tmp_cpp_value = '{%s}' % cpp_value + else: + tmp_cpp_value = cpp_value + cpp_values.append(tmp_cpp_value) + cpp_value = '{%s}' % ', '.join(cpp_values) + if len(cpp_values) > 1 and not is_string_array: + # Only wrap in a second set of {} if the array length is > 1. + # This avoids "warning: braces around scalar initializer" + cpp_value = '{%s}' % cpp_value + return cpp_value + + +def primitive_value_to_cpp(type_, value): + """ + Convert a python value into a string representing that value in C++. + + Warning: The value has to be a primitive and not a list + (aka this function doesn't work for arrays) + @param type_: a ROS IDL type + @type type_: builtin.str + @param value: the value to convert + @type value: python builtin (bool, int, float or str) + @returns: a string containing the C++ representation of the value + """ + assert isinstance(type_, (BasicType, AbstractGenericString)), \ + "Could not convert non-primitive type '%s' to CPP" % (type_) + assert value is not None, "Value for type '%s' must not be None" % (type_) + + if isinstance(type_, AbstractString): + return '"%s"' % escape_string(value) + + if isinstance(type_, AbstractWString): + return 'u"%s"' % escape_wstring(value) + + if type_.typename == 'boolean': + return 'true' if value else 'false' + + if type_.typename in [ + 'short', 'unsigned short', + 'char', 'wchar', + 'double', 'long double', + 'octet', + 'int8', 'uint8', + 'int16', 'uint16', + ]: + return str(value) + + if type_.typename == 'int32': + # Handle edge case for INT32_MIN + # Specifically, MSVC is not happy in this case + if -2147483648 == value: + return '({0}l - 1)'.format(value + 1) + return '%sl' % value + + if type_.typename == 'uint32': + return '%sul' % value + + if type_.typename == 'int64': + # Handle edge case for INT64_MIN + # See https://en.cppreference.com/w/cpp/language/integer_literal + if -9223372036854775808 == value: + return '(%sll - 1)' % (value + 1) + return '%sll' % value + + if type_.typename == 'uint64': + return '%sull' % value + + if type_.typename == 'float': + return '%sf' % value + + assert False, "unknown primitive type '%s'" % type_.typename + + +def default_value_from_type(type_): + if isinstance(type_, AbstractGenericString): + return '' + elif isinstance(type_, BasicType) and type_.typename in FLOATING_POINT_TYPES: + return 0.0 + elif isinstance(type_, BasicType) and type_.typename == 'boolean': + return False + return 0 + + +def escape_string(s): + s = s.replace('\\', '\\\\') + s = s.replace('"', '\\"') + return s + + +def escape_wstring(s): + return escape_string(s) + + +def create_init_alloc_and_member_lists(message): + # A Member object represents the information we need to know to initialize + # a single member of the class. + class Member: + + def __init__(self, name): + self.name = name + self.default_value = None + self.zero_value = None + self.zero_need_array_override = False + self.type = None + self.num_prealloc = 0 + + def same_default_and_zero_value(self, other): + return self.default_value == other.default_value and \ + self.zero_value == other.zero_value + + # A CommonMemberSet is a set of adjacent members that share the same set of + # initialization semantics. Here, initialization semantics mean that all + # members of the set have a default value (or do not have a default value), + # and all members of the set have a zero value (or do not have a zero + # value). + class CommonMemberSet: + + def __init__(self): + self.members = [] + + def add_member(self, member): + if not self.members or self.members[-1].same_default_and_zero_value(member): + self.members.append(member) + return True + return False + + # The loop below is used to generate three different lists: + # init_list - The list of member variables that we will initialize using member + # initialization in the default constructor + # alloc_list - The list of member variables that we will initialize using member + # initializion in the allocator constructor + # member_list - The list of members that we will generate initialization code + # for in the body of the constructors + init_list = [] + alloc_list = [] + member_list = [] + for field in message.structure.members: + member = Member(field.name) + member.type = field.type + if isinstance(field.type, Array): + alloc_list.append(field.name + '(_alloc)') + if isinstance(field.type.value_type, BasicType) or \ + isinstance(field.type.value_type, AbstractGenericString): + default = default_value_from_type(field.type.value_type) + single = primitive_value_to_cpp(field.type.value_type, default) + member.zero_value = [single] * field.type.size + if field.has_annotation('default'): + default_value = literal_eval( + field.get_annotation_value('default')['value']) + member.default_value = [] + for val in default_value: + member.default_value.append( + primitive_value_to_cpp(field.type.value_type, val)) + else: + member.zero_value = [] + member.zero_need_array_override = True + elif isinstance(field.type, AbstractSequence): + if field.has_annotation('default'): + default_value = literal_eval( + field.get_annotation_value('default')['value']) + member.default_value = value_to_cpp(field.type, default_value) + member.num_prealloc = len(default_value) + else: + if isinstance(field.type, BasicType) or \ + isinstance(field.type, AbstractGenericString): + if isinstance(field.type, AbstractGenericString): + alloc_list.append(field.name + '(_alloc)') + default = default_value_from_type(field.type) + member.zero_value = primitive_value_to_cpp(field.type, default) + if field.has_annotation('default'): + member.default_value = primitive_value_to_cpp( + field.type, + field.get_annotation_value('default')['value']) + else: + init_list.append(field.name + '(_init)') + alloc_list.append(field.name + '(_alloc, _init)') + + if field.has_annotation('default') or member.zero_value is not None: + if not member_list or not member_list[-1].add_member(member): + commonset = CommonMemberSet() + commonset.add_member(member) + member_list.append(commonset) + + return init_list, alloc_list, member_list diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/idl__struct.hpp.em b/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/idl__struct.hpp.em new file mode 100644 index 00000000000..10657453dee --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/idl__struct.hpp.em @@ -0,0 +1,86 @@ +// generated from rosidl_generator_cpp/resource/idl__struct.hpp.em +// with input from @(package_name):@(interface_path) +// generated code does not contain a copyright notice +@{from dimos.message_codegen._vendor.rosidl.rosidl_pycommon import convert_camel_case_to_lower_case_underscore} +// IWYU pragma: private, include "@(package_name)/@(interface_path.parent)/@(convert_camel_case_to_lower_case_underscore(interface_path.stem)).hpp" + +@ +@####################################################################### +@# EmPy template for generating __struct.hpp files +@# +@# Context: +@# - package_name (string) +@# - interface_path (Path relative to the directory named after the package) +@# - content (IdlContent, list of elements, e.g. Messages or Services) +@####################################################################### +@{ +from dimos.message_codegen._vendor.rosidl.rosidl_pycommon import convert_camel_case_to_lower_case_underscore +include_parts = [package_name] + list(interface_path.parents[0].parts) + [ + 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] +header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \ + '__STRUCT_HPP_' + +include_directives = set() +}@ + +#ifndef @(header_guard_variable) +#define @(header_guard_variable) + +#include +#include +#include +#include +#include +#include + +#include "rosidl_runtime_cpp/bounded_vector.hpp" +#include "rosidl_runtime_cpp/message_initialization.hpp" + +@####################################################################### +@# Handle message +@####################################################################### +@{ +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Message +}@ +@[for message in content.get_elements_of_type(Message)]@ +@{ +TEMPLATE( + 'msg__struct.hpp.em', + package_name=package_name, interface_path=interface_path, + message=message, include_directives=include_directives) +}@ + +@[end for]@ +@ +@####################################################################### +@# Handle service +@####################################################################### +@{ +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Service +}@ +@[for service in content.get_elements_of_type(Service)]@ +@{ +TEMPLATE( + 'srv__struct.hpp.em', + package_name=package_name, interface_path=interface_path, service=service, + include_directives=include_directives) +}@ + +@[end for]@ +@ +@####################################################################### +@# Handle action +@####################################################################### +@{ +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Action +}@ +@[for action in content.get_elements_of_type(Action)]@ +@{ +TEMPLATE( + 'action__struct.hpp.em', + package_name=package_name, interface_path=interface_path, action=action, + include_directives=include_directives) +}@ + +@[end for]@ +#endif // @(header_guard_variable) diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/msg__struct.hpp.em b/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/msg__struct.hpp.em new file mode 100644 index 00000000000..1e28ee0dd51 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_generator_cpp/resource/msg__struct.hpp.em @@ -0,0 +1,403 @@ +@# Included from rosidl_generator_cpp/resource/idl__struct.hpp.em +@{ +from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import create_init_alloc_and_member_lists +from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import escape_string +from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import escape_wstring +from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import msg_type_to_cpp +from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import MSG_TYPE_TO_CPP +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractNestedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractWString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import ACTION_FEEDBACK_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import ACTION_GOAL_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import ACTION_RESULT_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import SERVICE_REQUEST_MESSAGE_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import SERVICE_RESPONSE_MESSAGE_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BasicType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BOOLEAN_TYPE +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import CHARACTER_TYPES +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import INTEGER_TYPES +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import NamespacedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import OCTET_TYPE +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import UNSIGNED_INTEGER_TYPES + +message_typename = '::'.join(message.structure.namespaced_type.namespaced_name()) + +# Common Windows macros that may interfere with user defined constants +msvc_common_macros = ('DELETE', 'ERROR', 'NO_ERROR') +}@ +@ +@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +@# Collect necessary include directives for all members +@{ +from collections import OrderedDict +from dimos.message_codegen._vendor.rosidl.rosidl_pycommon import convert_camel_case_to_lower_case_underscore +includes = OrderedDict() +for member in message.structure.members: + type_ = member.type + if isinstance(type_, AbstractNestedType): + type_ = type_.value_type + if isinstance(type_, NamespacedType): + if ( + message.structure.namespaced_type.namespaces[-1] in ['action', 'srv'] and ( + type_.name.endswith(SERVICE_REQUEST_MESSAGE_SUFFIX) or + type_.name.endswith(SERVICE_RESPONSE_MESSAGE_SUFFIX)) + ): + typename = type_.name.rsplit('_', 1)[0] + if typename == message.structure.namespaced_type.name.rsplit('_', 1)[0]: + continue + if ( + type_.name.endswith(ACTION_GOAL_SUFFIX) or + type_.name.endswith(ACTION_RESULT_SUFFIX) or + type_.name.endswith(ACTION_FEEDBACK_SUFFIX) + ): + typename = type_.name.rsplit('_', 1)[0] + else: + typename = type_.name + member_names = includes.setdefault( + '/'.join((type_.namespaces + ['detail', convert_camel_case_to_lower_case_underscore(typename)])) + '__struct.hpp', []) + member_names.append(member.name) +}@ +@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +@ +@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +@[if includes]@ + +// Include directives for member types +@[ for header_file, member_names in includes.items()]@ +@[ for member_name in member_names]@ +// Member '@(member_name)' +@[ end for]@ +@[ if header_file in include_directives]@ +// already included above +// @ +@[ else]@ +@{include_directives.add(header_file)}@ +@[ end if]@ +#include "@(header_file)" +@[ end for]@ +@[end if]@ +@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +@{ +deprecated_macro_name = \ + '__'.join(['DEPRECATED', package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name]) +}@ +#ifndef _WIN32 +# define @(deprecated_macro_name) __attribute__((deprecated)) +#else +# define @(deprecated_macro_name) __declspec(deprecated) +#endif + +@[for ns in message.structure.namespaced_type.namespaces]@ +namespace @(ns) +{ + +@[end for]@ +// message struct +template +struct @(message.structure.namespaced_type.name)_ +{ + using Type = @(message.structure.namespaced_type.name)_; + +@{ +# The creation of the constructors for messages is a bit complicated. The goal +# is to have a constructor where the user can control how the fields of the +# message get initialized via the _init parameter to the constructor. See +# http://design.ros2.org/articles/generated_interfaces_cpp.html#constructors +# for a detailed explanation of the different _init parameters. +init_list, alloc_list, member_list = create_init_alloc_and_member_lists(message) + +def generate_default_string(membset): + from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import msg_type_only_to_cpp + from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import msg_type_to_cpp + strlist = [] + for member in membset.members: + if member.default_value is not None: + if member.num_prealloc > 0: + strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc)) + if isinstance(member.default_value, list): + if all(v == member.default_value[0] for v in member.default_value): + # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244) + # For more info, see https://github.com/ros2/rosidl/issues/309 + # TODO(jacobperron): Investigate reason for build warnings on Windows + # TODO(jacobperron): Write test case for this path of execution + strlist.append('std::fill(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.default_value[0])) + else: + for index, val in enumerate(member.default_value): + strlist.append('this->%s[%d] = %s;' % (member.name, index, val)) + else: + strlist.append('this->%s = %s;' % (member.name, member.default_value)) + + return strlist + +def generate_zero_string(membset, fill_args): + from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import msg_type_only_to_cpp + from dimos.message_codegen._vendor.rosidl.rosidl_generator_cpp import msg_type_to_cpp + strlist = [] + for member in membset.members: + if isinstance(member.zero_value, list): + if member.num_prealloc > 0: + strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc)) + if member.zero_need_array_override: + strlist.append('this->%s.fill(%s{%s});' % (member.name, msg_type_only_to_cpp(member.type), fill_args)) + else: + # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244) + # For more info, see https://github.com/ros2/rosidl/issues/309 + # TODO(jacobperron): Investigate reason for build warnings on Windows + strlist.append('std::fill(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.zero_value[0])) + else: + strlist.append('this->%s = %s;' % (member.name, member.zero_value)) + return strlist +}@ + explicit @(message.structure.namespaced_type.name)_(rosidl_runtime_cpp::MessageInitialization _init = rosidl_runtime_cpp::MessageInitialization::ALL) +@[if init_list]@ + : @(',\n '.join(init_list)) +@[end if]@ + { +@[if not member_list]@ + (void)_init; +@[end if]@ +@{ +default_value_members = [m for m in member_list if m.members[0].default_value] +zero_value_members = [m for m in member_list if m.members[0].zero_value] +non_defaulted_zero_initialized_members = [ + m for m in member_list + if (m.members[0].zero_value or m.members[0].zero_need_array_override) and not m.members[0].default_value +] +}@ +@[if default_value_members]@ + if (rosidl_runtime_cpp::MessageInitialization::ALL == _init || + rosidl_runtime_cpp::MessageInitialization::DEFAULTS_ONLY == _init) + { +@[ for membset in default_value_members]@ +@[ for line in generate_default_string(membset)]@ + @(line) +@[ end for]@ +@[ end for]@ +@[ if zero_value_members]@ + } else if (rosidl_runtime_cpp::MessageInitialization::ZERO == _init) { +@[ for membset in zero_value_members]@ +@[ for line in generate_zero_string(membset, '_init')]@ + @(line) +@[ end for]@ +@[ end for]@ +@[ end if]@ + } +@[ end if]@ +@[ if non_defaulted_zero_initialized_members]@ + if (rosidl_runtime_cpp::MessageInitialization::ALL == _init || + rosidl_runtime_cpp::MessageInitialization::ZERO == _init) + { +@[ for membset in non_defaulted_zero_initialized_members]@ +@[ for line in generate_zero_string(membset, '_init')]@ +@[ if line]@ + @(line) +@[ end if]@ +@[ end for]@ +@[ end for]@ + } +@[end if]@ + } + + explicit @(message.structure.namespaced_type.name)_(const ContainerAllocator & _alloc, rosidl_runtime_cpp::MessageInitialization _init = rosidl_runtime_cpp::MessageInitialization::ALL) +@[if alloc_list]@ + : @(',\n '.join(alloc_list)) +@[end if]@ + { +@[if not member_list]@ + (void)_init; +@[end if]@ +@[if not alloc_list]@ + (void)_alloc; +@[end if]@ +@[if default_value_members]@ + if (rosidl_runtime_cpp::MessageInitialization::ALL == _init || + rosidl_runtime_cpp::MessageInitialization::DEFAULTS_ONLY == _init) + { +@[ for membset in default_value_members]@ +@[ for line in generate_default_string(membset)]@ + @(line) +@[ end for]@ +@[ end for]@ +@[ if zero_value_members]@ + } else if (rosidl_runtime_cpp::MessageInitialization::ZERO == _init) { +@[ for membset in zero_value_members]@ +@[ for line in generate_zero_string(membset, '_alloc, _init')]@ + @(line) +@[ end for]@ +@[ end for]@ +@[ end if]@ + } +@[end if]@ +@[if non_defaulted_zero_initialized_members]@ + if (rosidl_runtime_cpp::MessageInitialization::ALL == _init || + rosidl_runtime_cpp::MessageInitialization::ZERO == _init) + { +@[ for membset in non_defaulted_zero_initialized_members]@ +@[ for line in generate_zero_string(membset, '_alloc, _init')]@ + @(line) +@[ end for]@ +@[ end for]@ + } +@[end if]@ + } + + // field types and members +@[for member in message.structure.members]@ + using _@(member.name)_type = + @(msg_type_to_cpp(member.type)); + _@(member.name)_type @(member.name); +@[end for]@ + +@[if len(message.structure.members) != 1 or message.structure.members[0].name != EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME]@ + // setters for named parameter idiom +@[ for member in message.structure.members]@ + Type & set__@(member.name)( + const @(msg_type_to_cpp(member.type)) & _arg) + { + this->@(member.name) = _arg; + return *this; + } +@[ end for]@ +@[end if]@ + + // constant declarations +@[for constant in message.constants]@ +@[ if constant.name in msvc_common_macros]@ + // guard against '@(constant.name)' being predefined by MSVC by temporarily undefining it +#if defined(_WIN32) +# if defined(@(constant.name)) +# pragma push_macro("@(constant.name)") +# undef @(constant.name) +# endif +#endif +@[ end if]@ +@[ if isinstance(constant.type, AbstractString)]@ + static const @(MSG_TYPE_TO_CPP['string']) @(constant.name); +@[ elif isinstance(constant.type, AbstractWString)]@ + static const @(MSG_TYPE_TO_CPP['wstring']) @(constant.name); +@[ else]@ + static constexpr @(MSG_TYPE_TO_CPP[constant.type.typename]) @(constant.name) = +@[ if isinstance(constant.type, BasicType)]@ +@[ if constant.type.typename in (*INTEGER_TYPES, *CHARACTER_TYPES, BOOLEAN_TYPE, OCTET_TYPE)]@ + @(int(constant.value))@ +@[ if constant.type.typename in UNSIGNED_INTEGER_TYPES]@ +u@ +@[ end if]@ +@[ elif constant.type.typename == 'float']@ + @(constant.value)f@ +@[ else]@ + @(constant.value)@ +@[ end if]; +@[ else]@ + @(constant.value); +@[ end if]@ +@[ end if]@ +@[ if constant.name in msvc_common_macros]@ +#if defined(_WIN32) +# pragma warning(suppress : 4602) +# pragma pop_macro("@(constant.name)") +#endif +@[ end if]@ +@[end for]@ + + // pointer types + using RawPtr = + @(message_typename)_ *; + using ConstRawPtr = + const @(message_typename)_ *; + using SharedPtr = + std::shared_ptr<@(message_typename)_>; + using ConstSharedPtr = + std::shared_ptr<@(message_typename)_ const>; + + template>> + using UniquePtrWithDeleter = + std::unique_ptr<@(message_typename)_, Deleter>; + + using UniquePtr = UniquePtrWithDeleter<>; + + template>> + using ConstUniquePtrWithDeleter = + std::unique_ptr<@(message_typename)_ const, Deleter>; + using ConstUniquePtr = ConstUniquePtrWithDeleter<>; + + using WeakPtr = + std::weak_ptr<@(message_typename)_>; + using ConstWeakPtr = + std::weak_ptr<@(message_typename)_ const>; + + // pointer types similar to ROS 1, use SharedPtr / ConstSharedPtr instead + // NOTE: Can't use 'using' here because GNU C++ can't parse attributes properly + typedef @(deprecated_macro_name) + std::shared_ptr<@(message_typename)_> + Ptr; + typedef @(deprecated_macro_name) + std::shared_ptr<@(message_typename)_ const> + ConstPtr; + + // comparison operators + bool operator==(const @(message.structure.namespaced_type.name)_ & other) const + { +@[if not message.structure.members]@ + (void)other; +@[end if]@ +@[for member in message.structure.members]@ + if (this->@(member.name) != other.@(member.name)) { + return false; + } +@[end for]@ + return true; + } + bool operator!=(const @(message.structure.namespaced_type.name)_ & other) const + { + return !this->operator==(other); + } +}; // struct @(message.structure.namespaced_type.name)_ + +// alias to use template instance with default allocator +using @(message.structure.namespaced_type.name) = + @(message_typename)_>; + +// constant definitions +@[for c in message.constants]@ +@[ if c.name in msvc_common_macros]@ +// guard against '@(c.name)' being predefined by MSVC by temporarily undefining it +#if defined(_WIN32) +# if defined(@(c.name)) +# pragma push_macro("@(c.name)") +# undef @(c.name) +# endif +#endif +@[ end if]@ +@[ if isinstance(c.type, AbstractString)]@ +template +const @(MSG_TYPE_TO_CPP['string']) +@(message.structure.namespaced_type.name)_::@(c.name) = "@(escape_string(c.value))"; +@[ elif isinstance(c.type, AbstractWString)]@ +template +const @(MSG_TYPE_TO_CPP['wstring']) +@(message.structure.namespaced_type.name)_::@(c.name) = u"@(escape_wstring(c.value))"; +@[ else ]@ +#if __cplusplus < 201703L +// static constexpr member variable definitions are only needed in C++14 and below, deprecated in C++17 +template +constexpr @(MSG_TYPE_TO_CPP[c.type.typename]) @(message.structure.namespaced_type.name)_::@(c.name); +#endif // __cplusplus < 201703L +@[ end if]@ +@[ if c.name in msvc_common_macros]@ +#if defined(_WIN32) +# pragma warning(suppress : 4602) +# pragma pop_macro("@(c.name)") +#endif +@[ end if]@ +@[end for]@ +@ +@[for ns in reversed(message.structure.namespaced_type.namespaces)]@ + +} // namespace @(ns) +@[end for]@ diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_parser/__init__.py b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_parser/definition.py b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/definition.py new file mode 100644 index 00000000000..273c306b9d5 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/definition.py @@ -0,0 +1,789 @@ +# Copyright 2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pathlib +from typing import Iterable +from typing import Tuple + +# Basic types as defined by the IDL specification + +# 7.4.1.4.4.2 Basic Types +SIGNED_NONEXPLICIT_INTEGER_TYPES = ( # rules (26) + 'short', # rule (27) + 'long', # rule (28) + 'long long', # rule (29) +) +UNSIGNED_NONEXPLICIT_INTEGER_TYPES = ( # rules (30) + 'unsigned short', # rule (31) + 'unsigned long', # rule (32) + 'unsigned long long', # rule (33) +) +NONEXPLICIT_INTEGER_TYPES = ( + *SIGNED_NONEXPLICIT_INTEGER_TYPES, + *UNSIGNED_NONEXPLICIT_INTEGER_TYPES, +) +FLOATING_POINT_TYPES = ( # rule (24) + 'float', + 'double', + 'long double', +) +CHARACTER_TYPES = ( + 'char', # rule (34) + 'wchar', # rule (35) +) +BOOLEAN_TYPE = 'boolean' # rule (36) +OCTET_TYPE = 'octet' # rule (37) + +# 7.4.13.4.4 Integers restricted to holding 8-bits of information +# 7.4.13.4.5 Explicitly-named Integer Types +SIGNED_EXPLICIT_INTEGER_TYPES = ( + 'int8', # rule (208) + 'int16', # rule (210) + 'int32', # rule (211) + 'int64', # rule (212) +) +UNSIGNED_EXPLICIT_INTEGER_TYPES = ( + 'uint8', # rule (209) + 'uint16', # rule (213) + 'uint32', # rule (214) + 'uint64', # rule (215) +) +EXPLICIT_INTEGER_TYPES = ( + *SIGNED_EXPLICIT_INTEGER_TYPES, + *UNSIGNED_EXPLICIT_INTEGER_TYPES, +) +SIGNED_INTEGER_TYPES = ( # rules (26) + (208) + (210-212) + *SIGNED_NONEXPLICIT_INTEGER_TYPES, + *SIGNED_EXPLICIT_INTEGER_TYPES, +) +UNSIGNED_INTEGER_TYPES = ( # rules (30) + (209) + (213-215) + *UNSIGNED_NONEXPLICIT_INTEGER_TYPES, + *UNSIGNED_EXPLICIT_INTEGER_TYPES, +) +INTEGER_TYPES = ( # rules (25) + (206-207) + (210-215) + *SIGNED_INTEGER_TYPES, + *UNSIGNED_INTEGER_TYPES, +) + +"""All basic types as defined by the IDL specification.""" +BASIC_TYPES = ( + *INTEGER_TYPES, + *FLOATING_POINT_TYPES, + *CHARACTER_TYPES, + BOOLEAN_TYPE, + OCTET_TYPE, +) + +EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME = 'structure_needs_at_least_one_member' + +CONSTANT_MODULE_SUFFIX = '_Constants' + +SERVICE_REQUEST_MESSAGE_SUFFIX = '_Request' +SERVICE_RESPONSE_MESSAGE_SUFFIX = '_Response' +SERVICE_EVENT_MESSAGE_SUFFIX = '_Event' + +ACTION_GOAL_SUFFIX = '_Goal' +ACTION_RESULT_SUFFIX = '_Result' +ACTION_FEEDBACK_SUFFIX = '_Feedback' + +ACTION_GOAL_SERVICE_SUFFIX = '_SendGoal' +ACTION_RESULT_SERVICE_SUFFIX = '_GetResult' +ACTION_FEEDBACK_MESSAGE_SUFFIX = '_FeedbackMessage' + + +class AbstractType: + """The abstract base class for all types.""" + + __slots__ = () + + def __eq__(self, other): + return type(self) is type(other) + + +class AbstractNestableType(AbstractType): + """ + The abstract base class for types which can be used inside nested types. + + Arrays and sequences are nested types which contain elements of nestable + types. + Nestable types are: + - BasicType like numerics, character types, boolean and octet + - NamedType identified by a name which hasn't been resolved yet + - NamespacedType which describes another Structure + - Strings with any kind of character types, bounded as well as unbounded + """ + + __slots__ = () + + +class BasicType(AbstractNestableType): + """ + A basic type according to the IDL specification. + + Its `typename` attribute defines the specific numeric, character, boolean + or octet type. + """ + + __slots__ = ('typename', ) + + def __init__(self, typename: str): + """ + Create a BasicType. + + :param typename: the name of the basic type + """ + super().__init__() + assert typename in BASIC_TYPES + self.typename = typename + + def __eq__(self, other): + return super().__eq__(other) and self.typename == other.typename + + +class NamedType(AbstractNestableType): + """A type identified by the name.""" + + __slots__ = ('name') + + def __init__(self, name: str): + """ + Create a NamedType. + + :param name: the name + """ + super().__init__() + self.name = name + + def __eq__(self, other): + return super().__eq__(other) and self.name == other.name + + +class NamespacedType(AbstractNestableType): + """A type identified by a name in a namespaced scope.""" + + __slots__ = ('namespaces', 'name') + + def __init__(self, namespaces: Iterable[str], name: str): + """ + Create a NamespacedType. + + :param namespaces: the names of nested namespaces identifying a + specific scope + :param name: the name of the type within that scope + """ + super().__init__() + self.namespaces = namespaces + self.name = name + + def namespaced_name(self) -> Tuple[str, ...]: + return (*self.namespaces, self.name) + + def __eq__(self, other): + return super().__eq__(other) and \ + self.namespaces == other.namespaces and self.name == other.name + + +class AbstractGenericString(AbstractNestableType): + """The abstract base class of all string types.""" + + __slots__ = () + + def has_maximum_size(self): + raise NotImplementedError('Only implemented in subclasses') + + +class AbstractString(AbstractGenericString): + """The abstract base class of 8-bit string types.""" + + __slots__ = () + + +class BoundedString(AbstractString): + """A 8-bit string type with a limited number of characters.""" + + __slots__ = ('maximum_size', ) + + def __init__(self, maximum_size: int): + """ + Create a BoundedString. + + :param maximum_size: the maximum length of the string in characters + """ + super().__init__() + assert maximum_size >= 0 + self.maximum_size = maximum_size + + def has_maximum_size(self): + return True + + def __eq__(self, other): + return super().__eq__(other) and \ + self.maximum_size == other.maximum_size + + +class UnboundedString(AbstractString): + """A 8-bit string type with an unlimited number of characters.""" + + __slots__ = () + + def has_maximum_size(self): + return False + + +class AbstractWString(AbstractGenericString): + """The abstract base class of 16-bit string types.""" + + __slots__ = () + + +class BoundedWString(AbstractWString): + """A 16-bit string type.""" + + __slots__ = ('maximum_size', ) + + def __init__(self, maximum_size: int): + """ + Create a BoundedWString. + + :param maximum_size: the maximum length of the string in characters + (must be greater than zero) + """ + super().__init__() + # TODO(dirk-thomas) can't be enforced yet since the parser might pass a + # constant name + # assert maximum_size > 0 + self.maximum_size = maximum_size + + def has_maximum_size(self): + return True + + def __eq__(self, other): + return super().__eq__(other) and \ + self.maximum_size == other.maximum_size + + +class UnboundedWString(AbstractWString): + """A 16-bit string type.""" + + __slots__ = () + + def has_maximum_size(self): + return False + + +# the following types are templated on a base type + +class AbstractNestedType(AbstractType): + """ + The abstract base class of nested types. + + Arrays and sequences are nested types which contain elements of nestable + types. + """ + + __slots__ = ('value_type', ) + + def __init__(self, value_type: AbstractNestableType): + """ + Create an AbstractNestedType. + + :param value_type: the type of the nested elements + """ + super().__init__() + assert isinstance(value_type, AbstractNestableType) + self.value_type = value_type + + def has_maximum_size(self): + raise NotImplementedError('Only implemented in subclasses') + + def __eq__(self, other): + return super().__eq__(other) and self.value_type == other.value_type + + +class Array(AbstractNestedType): + """An array type with a static size.""" + + __slots__ = ('size') + + def __init__(self, value_type: AbstractNestableType, size: int): + """ + Create an Array. + + :param value_type: the type of each element in the array + :param size: the number of elements in the array (must be greater than + zero) + """ + super().__init__(value_type) + assert size > 0 + self.size = size + + def has_maximum_size(self): + return True + + def __eq__(self, other): + return super().__eq__(other) and self.size == other.size + + +class AbstractSequence(AbstractNestedType): + """The abstract base class of sequence types.""" + + __slots__ = set() + + def __init__(self, value_type: AbstractNestableType): + super().__init__(value_type) + + +class BoundedSequence(AbstractSequence): + """A sequence type with a maximum number of elements.""" + + __slots__ = ('maximum_size', ) + + def __init__(self, value_type: AbstractNestableType, maximum_size: int): + """ + Create a BoundedSequence. + + :param basetype: the type of each element in the sequence + :param maximum_size: the maximum number of elements in the sequence + """ + super().__init__(value_type) + assert maximum_size > 0 + self.maximum_size = maximum_size + + def has_maximum_size(self): + return True + + def __eq__(self, other): + return super().__eq__(other) and \ + self.maximum_size == other.maximum_size + + +class UnboundedSequence(AbstractSequence): + """A sequence type with an unlimited number of elements.""" + + __slots__ = () + + def __init__(self, value_type: AbstractNestableType): + """ + Create an UnboundedSequence. + + :param value_type: the type of each element in the sequence + """ + super().__init__(value_type) + + def has_maximum_size(self): + return False + + +class Annotation: + """An annotation identified by a name with an arbitrary value.""" + + __slots__ = ('name', 'value') + + def __init__(self, name: str, value): + """ + Create an Annotation. + + :param name: the type of the annotation as defined in the IDL spec + :param value: the type of the value is defined by the annotation, it + can be a primitive type like int or str or a dictionary containing + multiple key-value pairs + """ + assert isinstance(name, str) + self.name = name + self.value = value + + +class Annotatable: + """The base class for types which can have annotations.""" + + __slots__ = ('annotations', ) + + def __init__(self): + self.annotations = [] + + def get_annotation_value(self, name): + """ + Get the unique value of an annotation of a specific type. + + :param str name: the name of the annotation type + :returns: the annotation value + :raises: ValueError if there is no or multiple annotations with the + given name + """ + values = self.get_annotation_values(name) + if not values: + raise ValueError(f"No '{name}' annotation") + if len(values) > 1: + raise ValueError(f"Multiple '{name}' annotations") + return values[0] + + def get_annotation_values(self, name): + """ + Get the values of annotations of a specific type. + + :param str name: the name of the annotation type + :returns: a list of annotation values + """ + return [a.value for a in self.annotations if a.name == name] + + def get_comment_lines(self): + """ + Get the comment lines of the annotatable. + + :returns: a list of comment lines + """ + comments = [ + x['text'] for x in self.get_annotation_values('verbatim') if + 'language' in x and 'text' in x and x['language'] == 'comment' + ] + lines = [] + for comment in comments: + lines.extend(comment.splitlines()) + return lines + + def has_annotation(self, name): + """ + Check if there is exactly one annotation of a specific type. + + :param str name: the name of the annotation type + :returns: True if there is exactly one annotation, False otherwise + """ + values = self.get_annotation_values(name) + return len(values) == 1 + + def has_annotations(self, name): + """ + Check if there are any annotations of a specific type. + + :param str name: the name of the annotation type + :returns: True if there are any annotations, False otherwise + """ + annotations = self.get_annotation_values(name) + return bool(annotations) + + +class Member(Annotatable): + """A member of a structure.""" + + __slots__ = ('type', 'name') + + def __init__(self, type_: AbstractType, name: str): + """ + Create a Member. + + :param type_: the type of the member + :param name: the name of the member + """ + super().__init__() + assert isinstance(type_, AbstractType) + self.type = type_ + self.name = name + + +class Structure(Annotatable): + """A namespaced type containing of a list of members.""" + + __slots__ = ('namespaced_type', 'members') + + def __init__(self, namespaced_type: NamespacedType, members=None): + """ + Create a Structure. + + :param namespaced_type: the namespaced type identifying the structure + :param list members: the members of the structure + """ + super().__init__() + assert isinstance(namespaced_type, NamespacedType) + self.namespaced_type = namespaced_type + self.members = members or [] + + def has_any_member_with_annotation(self, name: str): + """ + Check whether any member has a particular annotation. + + :param str name: the name of the annotation + :returns: True if there is at least one member with the annotation, False otherwise + """ + has_any = [member.name for member in self.members if member.has_annotation(name)] + return bool(has_any) + + +class Include: + """An include statement.""" + + __slots__ = ('locator', ) + + def __init__(self, locator): + """ + Create an Include. + + :param str locator: a URI identifying the included file + """ + self.locator = locator + + +class Constant(Annotatable): + """A constant definition.""" + + __slots__ = ('name', 'type', 'value') + + def __init__(self, name: str, type_: AbstractType, value): + """ + Create a Constant. + + :param name: the name of the constant + :param type_: the type of the constant + :param value: the value of the constant + """ + super().__init__() + assert isinstance(type_, AbstractType) + self.name = name + self.type = type_ + self.value = value + + +class Message: + """A structure containing constants.""" + + __slots__ = ('structure', 'constants') + + def __init__(self, structure: Structure): + """ + Create a Message. + + :param structure: the structure of the message + """ + super().__init__() + assert isinstance(structure, Structure) + self.structure = structure + self.constants = [] + + +class Service: + """A namespaced type containing a request and response message.""" + + __slots__ = ('namespaced_type', 'request_message', 'response_message', 'event_message') + + def __init__( + self, namespaced_type: NamespacedType, request: Message, + response: Message + ): + """ + Create a Service. + + :param namespaced_type: the namespaced type identifying the + service + :param request: the request message + :param response: the response message + """ + super().__init__() + + assert isinstance(namespaced_type, NamespacedType) + self.namespaced_type = namespaced_type + + assert isinstance(request, Message) + assert request.structure.namespaced_type.namespaces == \ + namespaced_type.namespaces + assert request.structure.namespaced_type.name == \ + namespaced_type.name + SERVICE_REQUEST_MESSAGE_SUFFIX + self.request_message = request + + assert isinstance(response, Message) + assert response.structure.namespaced_type.namespaces == \ + namespaced_type.namespaces + assert response.structure.namespaced_type.name == \ + namespaced_type.name + SERVICE_RESPONSE_MESSAGE_SUFFIX + self.response_message = response + + self.event_message = Message( + Structure( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=f'{namespaced_type.name}{SERVICE_EVENT_MESSAGE_SUFFIX}' + ), + members=[ + Member(NamespacedType(['service_msgs', 'msg'], 'ServiceEventInfo'), 'info'), + Member(BoundedSequence(request.structure.namespaced_type, 1), 'request'), + Member(BoundedSequence(response.structure.namespaced_type, 1), 'response'), + ] + ) + ) + + +class Action: + """A namespaced type of an action including the derived types.""" + + __slots__ = ( + 'namespaced_type', 'goal', 'result', 'feedback', + 'send_goal_service', 'get_result_service', 'feedback_message', + 'implicit_includes') + + def __init__( + self, namespaced_type: NamespacedType, goal: Message, result: Message, + feedback: Message + ): + """ + Create an Action. + + From the provided types the actually used services and messages are + derived. + + :param namespaced_type: the namespaced type identifying the action + :param goal: the goal message + :param result: the result message + :param feedback: the feedback message + """ + super().__init__() + + assert isinstance(namespaced_type, NamespacedType) + self.namespaced_type = namespaced_type + + # explicitly defined types + assert isinstance(goal, Message) + assert goal.structure.namespaced_type.namespaces == \ + namespaced_type.namespaces + assert goal.structure.namespaced_type.name == namespaced_type.name + \ + ACTION_GOAL_SUFFIX + self.goal = goal + + assert isinstance(result, Message) + assert result.structure.namespaced_type.namespaces == \ + namespaced_type.namespaces + assert result.structure.namespaced_type.name == \ + namespaced_type.name + ACTION_RESULT_SUFFIX + self.result = result + + assert isinstance(feedback, Message) + assert feedback.structure.namespaced_type.namespaces == \ + namespaced_type.namespaces + assert feedback.structure.namespaced_type.name == \ + namespaced_type.name + ACTION_FEEDBACK_SUFFIX + self.feedback = feedback + + # necessary include for injected timestamp member + self.implicit_includes = [ + Include('builtin_interfaces/msg/Time.idl'), + Include('unique_identifier_msgs/msg/UUID.idl'), + ] + + # derived types + goal_id_type = NamespacedType( + namespaces=['unique_identifier_msgs', 'msg'], name='UUID') + + goal_service_name = namespaced_type.name + ACTION_GOAL_SERVICE_SUFFIX + self.send_goal_service = Service( + NamespacedType( + namespaces=namespaced_type.namespaces, name=goal_service_name), + request=Message(Structure( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=goal_service_name + SERVICE_REQUEST_MESSAGE_SUFFIX), + members=[ + Member(goal_id_type, 'goal_id'), + Member(goal.structure.namespaced_type, 'goal')] + )), + response=Message(Structure( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=goal_service_name + SERVICE_RESPONSE_MESSAGE_SUFFIX), + members=[ + Member(BasicType('boolean'), 'accepted'), + Member( + NamespacedType(['builtin_interfaces', 'msg'], 'Time'), + 'stamp')] + )), + ) + + result_service_name = namespaced_type.name + \ + ACTION_RESULT_SERVICE_SUFFIX + self.get_result_service = Service( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=result_service_name), + request=Message(Structure( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=result_service_name + SERVICE_REQUEST_MESSAGE_SUFFIX), + members=[Member(goal_id_type, 'goal_id')] + )), + response=Message(Structure( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=result_service_name + SERVICE_RESPONSE_MESSAGE_SUFFIX), + members=[ + Member(BasicType('int8'), 'status'), + Member(result.structure.namespaced_type, 'result')] + )), + ) + + self.feedback_message = Message(Structure( + NamespacedType( + namespaces=namespaced_type.namespaces, + name=namespaced_type.name + ACTION_FEEDBACK_MESSAGE_SUFFIX), + members=[ + Member(goal_id_type, 'goal_id'), + Member(feedback.structure.namespaced_type, 'feedback')] + )) + + +class IdlLocator: + """A URL of an IDL file.""" + + __slots__ = ('basepath', 'relative_path') + + def __init__(self, basepath, relative_path): + """ + Create an IdlLocator. + + :param str basepath: the basepath of file + :param str relative_path: the path relative to the basepath of the file + """ + super().__init__() + self.basepath = pathlib.Path(basepath) + self.relative_path = pathlib.Path(relative_path) + + def get_absolute_path(self): + return self.basepath / self.relative_path + + +class IdlContent: + """The content of an IDL file consisting of a list of elements.""" + + __slots__ = ('elements', ) + + def __init__(self): + super().__init__() + self.elements = [] + + def get_elements_of_type(self, type_): + return [e for e in self.elements if isinstance(e, type_)] + + +class IdlFile: + """Descriptor for a parsed IDL file.""" + + __slots__ = ('locator', 'content') + + def __init__(self, locator, content): + """ + Create an IdlFile. + + :param IdlLocator locator: the locator of the IDL file + :param IdlContent content: the content of the IDL file + """ + super().__init__() + assert isinstance(locator, IdlLocator) + self.locator = locator + assert isinstance(content, IdlContent) + self.content = content diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_parser/grammar.lark b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/grammar.lark new file mode 100644 index 00000000000..bb7f7890f2d --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/grammar.lark @@ -0,0 +1,524 @@ +// Only implements the following parts of the spec: +// 7.2.2 Comments +// 7.2.3 Identifiers +// 7.2.6 Literals +// 7.3 Preprocessing +// only #include is supported +// 7.4.1 Building Block Core Data Types +// 7.4.15.4.2 Applying Annotations +// Only supported on modules, structs, members, enums and enum identifiers + +%import common.DECIMAL +%import common.DIGIT +%import common.FLOAT +%import common.HEXDIGIT +%import common.INT +%import common.LETTER +%import common.WS +%ignore WS + +// Copied from lark-parser instead of imported so wide string doesn't match: `L "white space between L and quote"` +// https://github.com/lark-parser/lark/blob/953171821ed307f700fddf27f3fcb9483346bd46/lark/grammars/common.lark#L26-L29 +_STRING_INNER: /.*?/ +_STRING_ESC_INNER: _STRING_INNER /(?" | "?" | "@" | "[" | "\\" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~" +| "¡" | "¢" | "£" | "¤" | "¥" | "¦" | "§" | " ̈ " | "©" | "a" | "«" | "¬" | "®" | " ̄" | "°" | "±" | "2" | "3" | " ́ " | "μ" | "¶" | "•" | " ̧ "| "1" | "o" | "»" | "¿" | "×" | "÷" + +// Table 7-5: Formatting characters, missing some uncommon ones +_FORMATTING_CHARACTERS: "\t" | "\n" | "\r" + +// Table 7-9: Escape sequences +_ESCAPE_SEQUENCES: "\\n" | "\\t" | "\\v" | "\\b" | "\\r" | "\\f" | "\\a" | "\\\\" | "\\?" | "\\'" | "\\\"" | "\\" "0".."7" "0".."7" | "\\x" HEXDIGIT HEXDIGIT | "\\" HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT + +// 7.2.6.3 String Literals +// adjacent string literals are concatenated +string_literals: string_literal+ +wide_string_literals: wide_string_literal+ +string_literal: ESCAPED_STRING +wide_string_literal: ESCAPED_WIDE_STRING + +// 7.2.6.4 Floating-point Literals +floating_pt_literal: FLOAT + +// 7.2.6.5 Fixed-Point Literals +fixed_pt_literal: DECIMAL "d"i + | INT "d"i + + +// 7.3 Preprocessing +include_directive: "#include" ("<" h_char_sequence ">" | "\"" q_char_sequence "\"") +// Preprocessor spec - 5.8 Header names +h_char_sequence: /[^>]+/ +q_char_sequence: /[^"]+/ + + +// 7.4.1 Building Block Core Data Types + +// (1) +specification: definition+ + +// (2) +definition: module_dcl ";" + | const_dcl ";" + | type_dcl ";" + | include_directive + +// (3), 7.4.15.2 +module_dcl: annotation_appl* "module" IDENTIFIER "{" definition+ "}" + +// (4) +scoped_name.1: IDENTIFIER + | scoped_name_separator IDENTIFIER + | scoped_name scoped_name_separator IDENTIFIER +// separate rule to identify the separator +scoped_name_separator: "::" + +// (5), 7.4.15.2 +const_dcl: annotation_appl* "const" const_type IDENTIFIER "=" const_expr + +// (6) +const_type: integer_type + | floating_pt_type + | fixed_pt_const_type + | char_type + | wide_char_type + | boolean_type + | octet_type + | string_type + | wide_string_type + | scoped_name + +// (7) +const_expr: or_expr + +// (8) +or_expr: xor_expr + | or_expr "|" xor_expr + +// (9) +xor_expr: and_expr + | xor_expr "^" and_expr + +// (10) +and_expr: shift_expr + | and_expr "&" shift_expr + +// (11) +shift_expr: add_expr + | shift_expr ">>" add_expr + | shift_expr "<<" add_expr + +// (12) +add_expr: mult_expr + | add_expr "+" mult_expr + | add_expr "-" mult_expr + +// (13) +mult_expr: unary_expr + | mult_expr "*" unary_expr + | mult_expr "/" unary_expr + | mult_expr "%" unary_expr + +// (14) +unary_expr: unary_operator primary_expr + | primary_expr + +// (15) +unary_operator: unary_operator_minus + | unary_operator_plus + | unary_operator_tilde +// separate rules to identify the unary operator +unary_operator_minus: "-" +unary_operator_plus: "+" +unary_operator_tilde: "~" + +// (16) +primary_expr: scoped_name + | literal + | "(" const_expr ")" + +// (17) +literal.2: integer_literal + | floating_pt_literal + | fixed_pt_literal + | character_literal + | wide_character_literal + | boolean_literal + | string_literals + | wide_string_literals + +// (18) +boolean_literal: boolean_literal_true + | boolean_literal_false +// separate rules to identify the boolean literal +boolean_literal_true: "TRUE" +boolean_literal_false: "FALSE" + +// (19) +positive_int_const: const_expr + +// (20) +type_dcl: constr_type_dcl + | typedef_dcl +// | native_dcl + +// (21), (216) +type_spec: simple_type_spec + | template_type_spec + +// (22) +simple_type_spec: base_type_spec + | scoped_name + +// (23) +base_type_spec.2: integer_type + | floating_pt_type + | char_type + | wide_char_type + | boolean_type + | octet_type + +// (24) +floating_pt_type.2: floating_pt_type_float + | floating_pt_type_double + | floating_pt_type_long_double +// separate rules to identify the floating point type +floating_pt_type_float: "float" +floating_pt_type_double: "double" +floating_pt_type_long_double: "long" "double" + +// (25) +integer_type.2: signed_int + | unsigned_int + +// (26), (206) +signed_int: signed_short_int + | signed_long_int + | signed_longlong_int + | signed_tiny_int + +// (27), (210) +signed_short_int: "short" + | "int16" + +// (28), (211) +signed_long_int: "long" + | "int32" + +// (29), (212) +signed_longlong_int: "long" "long" + | "int64" + +// (30), (207) +unsigned_int: unsigned_short_int + | unsigned_long_int + | unsigned_longlong_int + | unsigned_tiny_int + +// (31), (213) +unsigned_short_int: "unsigned" "short" + | "uint16" + +// (32), (214) +unsigned_long_int: "unsigned" "long" + | "uint32" + +// (33), (215) +unsigned_longlong_int: "unsigned" "long" "long" + | "uint64" + +// (34) +char_type.2: "char" + +// (35) +wide_char_type.2: "wchar" + +// (36) +boolean_type.2: "boolean" + +// (37) +octet_type.2: "octet" + +// (38) +template_type_spec.2: sequence_type + | string_type + | wide_string_type + | fixed_pt_type + +// (39) +sequence_type: "sequence" "<" type_spec "," positive_int_const ">" + | "sequence" "<" type_spec ">" + +// (40) +string_type.2: "string" "<" positive_int_const ">" + | "string" + +// (41) +wide_string_type.2: "wstring" "<" positive_int_const ">" + | "wstring" + +// (42) +fixed_pt_type: "fixed" "<" positive_int_const "," positive_int_const ">" + +// (43) +fixed_pt_const_type.2: "fixed" + +// (44) +constr_type_dcl: struct_dcl + | enum_dcl +// | union_dcl + +// (45) +struct_dcl: struct_def + | struct_forward_dcl + +// (46), 7.4.15.2 +struct_def: annotation_appl* "struct" IDENTIFIER "{" member+ "}" + +// (47), 7.4.15.2 +member: annotation_appl* type_spec declarators ";" + +// (48) +struct_forward_dcl: "struct" IDENTIFIER + +// (49) +//union_dcl: union_def +// | union_forward_dcl + +// (50) +//union_def: "union" IDENTIFIER "switch" "(" switch_type_spec ")" "{" switch_body "}" + +// (51) +switch_type_spec: integer_type + | char_type + | boolean_type + | scoped_name + +// (52) +switch_body: case+ + +// (53) +case: case_label+ element_spec ";" + +// (54) +case_label: "case" const_expr ":" + | "default" ":" + +// (55) +element_spec: type_spec declarator + +// (56) +//union_forward_dcl: "union" IDENTIFIER + +// (57) +enum_dcl: annotation_appl* "enum" IDENTIFIER "{" enumerator ("," enumerator)* "}" + +// (58) +enumerator: annotation_appl* IDENTIFIER + +// (59) +array_declarator: IDENTIFIER fixed_array_size+ + +// (60) +fixed_array_size: "[" positive_int_const "]" + +// (61) +//native_dcl: "native" simple_declarator + +// (62) +simple_declarator: IDENTIFIER + +// (63) +typedef_dcl: "typedef" type_declarator + +// (64) +type_declarator: (simple_type_spec | template_type_spec | constr_type_dcl) any_declarators + +// (65) +any_declarators: any_declarator ("," any_declarator)* + +// (66) +any_declarator: simple_declarator + | array_declarator + +// (67) +declarators: declarator ("," declarator)* + +// (68), (217) +declarator: simple_declarator + | array_declarator + + +// 7.4.2 Building Block Any + +// (69) +//‎ base_type_spec:+ any_type +// (70) +// ‎any_type: "any" + + +// 7.4.3 Building Block Interfaces – Basic +// ... + + +// 7.4.4 Building Block Interfaces – Full +// ... + +// 7.4.5 Building Block Value Types +// ... + +// 7.4.6 Building Block CORBA-Specific – Interfaces +// ... + +// 7.4.7 Building Block CORBA-Specific – Value Types +// ... + +// 7.4.8 Building Block Components – Basic +// ... + +// 7.4.9 Building Block Components – Homes +// ... + +// 7.4.10 Building Block CCM-Specific +// ... + +// 7.4.11 Building Block Components – Ports and Connectors +// ... + +// 7.4.12 Building Block Template Modules +// ... + + +// 7.4.13 Building Block Extended Data-Types + +// (195) +//struct_def:+ "struct" IDENTIFIER ":" scoped_name "{" member* "}" | "struct" identifier "{" "}" +// (196) +//switch_type_spec:+ wide_char_type | octet_type +// (197) +//template_type_spec:+ map_type +// (198) +//constr_type_dcl:+ bitset_dcl | bitmask_dcl +// (199) +//map_type: "map" "" type_spec "," type_spec "," positive_int_const "" | "map" "" type_spec "," type_spec "" +// (200) +//bitset_dcl: "bitset" identifier [":" scoped_name] "{" bitfield* "}" +// (201) +//bitfield: bitfield_spec identifier* ";" +// (202) +//bitfield_spec: "bitfield" "" positive_int_const "" | "bitfield" "" positive_int_const "," destination_type "" +// (203) +//destination_type: boolean_type | octet_type | integer_type +// (204) +//bitmask_dcl: "bitmask" identifier "{" bit_value { "," bit_value }* "}" +// (205) +//bit_value: identifier +// (206) appended to (26) +//signed_int:+ signed_tiny_int +// (207) appended to (30) +//unsigned_int:+ unsigned_tiny_int +// (208) +signed_tiny_int: "int8" +// (209) +unsigned_tiny_int: "uint8" +// (210) appended to (27) +//signed_short_int:+ "int16" +// (211) appended to (28) +//signed_long_int:+ "int32" +// (212) appended to (29) +//signed_longlong_int:+ "int64" +// (213) appended to (31) +//unsigned_short_int:+ "uint16" +// (214) appended to (32) +//unsigned_long_int:+ "uint32" +// (215) appended to (33) +//unsigned_longlong_int:+ "uint64" + + +// 7.4.14 Building Block Anonymous Types +// ... + + +// 7.4.15 Building Block Annotations + +// 7.4.15.4.1 Defining Annotations + +// (218) should be appended to (2) +//definition: annotation_dcl ";" + +// (219) +//annotation_dcl: annotation_header "{" annotation_body "}" + +// (220) +//annotation_header: "@annotation" IDENTIFIER + +// (221) +//annotation_body: (annotation_member | enum_dcl ";" | const_dcl ";" | typedef_dcl ";")* + +// (222) +//annotation_member: annotation_member_type simple_declarator [ "default" const_expr ] ";" + +// (223) +//annotation_member_type: const_type +// | any_const_type +// | scoped_name + +// (224) +//any_const_type: "any" + +// 7.4.15.4.2 Applying Annotations + +// (225) +annotation_appl: "@" scoped_name [ "(" annotation_appl_params ")" ] + +// (226) +annotation_appl_params: const_expr + | annotation_appl_param ("," annotation_appl_param)* + +// (227) +annotation_appl_param: IDENTIFIER "=" const_expr diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_parser/parser.py b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/parser.py new file mode 100644 index 00000000000..5713489071e --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_parser/parser.py @@ -0,0 +1,672 @@ +# Copyright 2018 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import codecs +import os +import re +import sys + +from lark import Lark +from lark.lexer import Token +from lark.tree import pydot__tree_to_png +from lark.tree import Tree + +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractNestedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import AbstractType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Action +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import ACTION_FEEDBACK_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import ACTION_GOAL_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import ACTION_RESULT_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Annotation +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Array +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BasicType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BoundedSequence +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BoundedString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import BoundedWString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Constant +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import CONSTANT_MODULE_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import IdlContent +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import IdlFile +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Include +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Member +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Message +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import NamedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import NamespacedType +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Service +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import SERVICE_REQUEST_MESSAGE_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import SERVICE_RESPONSE_MESSAGE_SUFFIX +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import Structure +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import UnboundedSequence +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import UnboundedString +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import UnboundedWString + +grammar_file = os.path.join(os.path.dirname(__file__), 'grammar.lark') +with open(grammar_file, mode='r', encoding='utf-8') as h: + grammar = h.read() + +_parser = None + + +def parse_idl_file(locator, png_file=None): + string = locator.get_absolute_path().read_text(encoding='utf-8') + try: + content = parse_idl_string(string, png_file=png_file) + except Exception as e: + print(str(e), str(locator.get_absolute_path()), file=sys.stderr) + raise + return IdlFile(locator, content) + + +def parse_idl_string(idl_string, png_file=None): + tree = get_ast_from_idl_string(idl_string) + content = extract_content_from_ast(tree) + + if png_file: + os.makedirs(os.path.dirname(png_file), exist_ok=True) + try: + pydot__tree_to_png(tree, png_file) + except ImportError: + pass + + return content + + +def get_ast_from_idl_string(idl_string): + global _parser + if _parser is None: + _parser = Lark(grammar, start='specification', maybe_placeholders=False) + return _parser.parse(idl_string) + + +def extract_content_from_ast(tree): + content = IdlContent() + + include_directives = tree.find_data('include_directive') + for include_directive in include_directives: + assert len(include_directive.children) == 1 + child = include_directive.children[0] + assert child.data in ('h_char_sequence', 'q_char_sequence') + include_token = next(child.scan_values(_find_tokens(None))) + content.elements.append(Include(include_token.value)) + + constants = {} + const_dcls = tree.find_data('const_dcl') + for const_dcl in const_dcls: + annotations = get_annotations(const_dcl) + const_type = next(const_dcl.find_data('const_type')) + module_identifiers = get_module_identifier_values(tree, const_dcl) + module_comments = constants.setdefault( + module_identifiers[-1], []) + value = get_const_expr_value(const_dcl.children[-1]) + constant = Constant( + get_child_identifier_value(const_dcl), + get_abstract_type_from_const_expr(const_type, value), + value) + constant.annotations = annotations + module_comments.append(constant) + + typedefs = {} + typedef_dcls = tree.find_data('typedef_dcl') + for typedef_dcl in typedef_dcls: + assert len(typedef_dcl.children) == 1 + child = typedef_dcl.children[0] + assert 'type_declarator' == child.data + assert len(child.children) == 2 + abstract_type = get_abstract_type(child.children[0]) + child = child.children[1] + assert 'any_declarators' == child.data + assert len(child.children) == 1, 'Only support single typedefs atm' + child = child.children[0] + identifier = get_first_identifier_value(child) + abstract_type = get_abstract_type_optionally_as_array( + abstract_type, child) + if identifier in typedefs: + assert typedefs[identifier] == abstract_type + else: + typedefs[identifier] = abstract_type + + struct_defs = list(tree.find_data('struct_def')) + if len(struct_defs) == 1: + msg = Message(Structure(NamespacedType( + namespaces=get_module_identifier_values(tree, struct_defs[0]), + name=get_child_identifier_value(struct_defs[0])))) + annotations = get_annotations(struct_defs[0]) + msg.structure.annotations += annotations + add_message_members(msg, struct_defs[0]) + resolve_typedefed_names(msg.structure, typedefs) + constant_module_name = msg.structure.namespaced_type.name + \ + CONSTANT_MODULE_SUFFIX + if constant_module_name in constants: + msg.constants += constants[constant_module_name] + content.elements.append(msg) + + elif len(struct_defs) == 2: + request = Message(Structure(NamespacedType( + namespaces=get_module_identifier_values(tree, struct_defs[0]), + name=get_child_identifier_value(struct_defs[0])))) + assert request.structure.namespaced_type.name.endswith( + SERVICE_REQUEST_MESSAGE_SUFFIX) + add_message_members(request, struct_defs[0]) + resolve_typedefed_names(request.structure, typedefs) + constant_module_name = \ + request.structure.namespaced_type.name + CONSTANT_MODULE_SUFFIX + if constant_module_name in constants: + request.constants += constants[constant_module_name] + + response = Message(Structure(NamespacedType( + namespaces=get_module_identifier_values(tree, struct_defs[1]), + name=get_child_identifier_value(struct_defs[1])))) + assert response.structure.namespaced_type.name.endswith( + SERVICE_RESPONSE_MESSAGE_SUFFIX) + add_message_members(response, struct_defs[1]) + resolve_typedefed_names(response.structure, typedefs) + constant_module_name = \ + response.structure.namespaced_type.name + CONSTANT_MODULE_SUFFIX + if constant_module_name in constants: + response.constants += constants[constant_module_name] + + assert request.structure.namespaced_type.namespaces == \ + response.structure.namespaced_type.namespaces + request_basename = request.structure.namespaced_type.name[ + :-len(SERVICE_REQUEST_MESSAGE_SUFFIX)] + response_basename = response.structure.namespaced_type.name[ + :-len(SERVICE_RESPONSE_MESSAGE_SUFFIX)] + assert request_basename == response_basename + + srv = Service( + NamespacedType( + namespaces=request.structure.namespaced_type.namespaces, + name=request_basename), + request, response) + content.elements.append(srv) + + elif len(struct_defs) == 3: + goal = Message(Structure(NamespacedType( + namespaces=get_module_identifier_values(tree, struct_defs[0]), + name=get_child_identifier_value(struct_defs[0])))) + assert goal.structure.namespaced_type.name.endswith(ACTION_GOAL_SUFFIX) + add_message_members(goal, struct_defs[0]) + resolve_typedefed_names(goal.structure, typedefs) + constant_module_name = \ + goal.structure.namespaced_type.name + CONSTANT_MODULE_SUFFIX + if constant_module_name in constants: + goal.constants += constants[constant_module_name] + + result = Message(Structure(NamespacedType( + namespaces=get_module_identifier_values(tree, struct_defs[1]), + name=get_child_identifier_value(struct_defs[1])))) + assert result.structure.namespaced_type.name.endswith( + ACTION_RESULT_SUFFIX) + add_message_members(result, struct_defs[1]) + resolve_typedefed_names(result.structure, typedefs) + constant_module_name = \ + result.structure.namespaced_type.name + CONSTANT_MODULE_SUFFIX + if constant_module_name in constants: + result.constants += constants[constant_module_name] + + assert goal.structure.namespaced_type.namespaces == \ + result.structure.namespaced_type.namespaces + goal_basename = goal.structure.namespaced_type.name[ + :-len(ACTION_GOAL_SUFFIX)] + result_basename = result.structure.namespaced_type.name[ + :-len(ACTION_RESULT_SUFFIX)] + assert goal_basename == result_basename + + feedback_message = Message(Structure(NamespacedType( + namespaces=get_module_identifier_values(tree, struct_defs[2]), + name=get_child_identifier_value(struct_defs[2])))) + assert feedback_message.structure.namespaced_type.name.endswith( + ACTION_FEEDBACK_SUFFIX) + add_message_members(feedback_message, struct_defs[2]) + resolve_typedefed_names(feedback_message.structure, typedefs) + constant_module_name = \ + feedback_message.structure.namespaced_type.name + \ + CONSTANT_MODULE_SUFFIX + if constant_module_name in constants: + feedback_message.constants += constants[constant_module_name] + + action = Action( + NamespacedType( + namespaces=goal.structure.namespaced_type.namespaces, + name=goal_basename), + goal, result, feedback_message) + + all_includes = content.get_elements_of_type(Include) + unique_include_locators = { + include.locator for include in all_includes} + content.elements += [ + include for include in action.implicit_includes + if include.locator not in unique_include_locators] + + content.elements.append(action) + + else: + assert False, \ + 'Currently only .idl files with 1 (a message), 2 (a service) ' \ + 'and 3 (an action) structures are supported' + + return content + + +def resolve_typedefed_names(structure, typedefs): + for member in structure.members: + type_ = member.type + if isinstance(type_, AbstractNestedType): + type_ = type_.value_type + assert isinstance(type_, AbstractType) + if isinstance(type_, NamedType): + assert type_.name in typedefs, 'Unknown named type: ' + type_.name + typedefed_type = typedefs[type_.name] + + # second level of indirection for arrays of structures + if isinstance(typedefed_type, AbstractNestedType): + if isinstance(typedefed_type.value_type, NamedType): + assert typedefed_type.value_type.name in typedefs, \ + 'Unknown named type: ' + typedefed_type.value_type.name + typedefed_type.value_type = \ + typedefs[typedefed_type.value_type.name] + + if isinstance(member.type, AbstractNestedType): + member.type.value_type = typedefed_type + else: + member.type = typedefed_type + + +def get_first_identifier_value(tree): + """Get the value of the first identifier token for a node.""" + identifier_token = next(tree.scan_values(_find_tokens('IDENTIFIER'))) + return identifier_token.value + + +def get_child_identifier_value(tree): + """Get the value of the first child identifier token for a node.""" + for c in tree.children: + if not isinstance(c, Token): + continue + if c.type == 'IDENTIFIER': + return c.value + return None + + +def _find_tokens(token_type): + def find(t): + if isinstance(t, Token): + if token_type is None or t.type == token_type: + return t + return find + + +def get_module_identifier_values(tree, target): + """Get all module names between a tree node and a specific target node.""" + path = _find_path(tree, target) + modules = [n for n in path if n.data == 'module_dcl'] + return [ + get_first_identifier_value(n) for n in modules] + + +def _find_path(node, target): + if node == target: + return [node] + for c in node.children: + if not isinstance(c, Tree): + continue + tail = _find_path(c, target) + if tail is not None: + return [node] + tail + return None + + +def get_abstract_type_from_const_expr(const_expr, value): + assert len(const_expr.children) == 1 + child = const_expr.children[0] + + if child.data in ('string_type', 'wide_string_type'): + if 'string_type' == child.data: + return BoundedString(len(value)) + if 'wide_string_type' == child.data: + return BoundedWString(len(value)) + assert False + + while len(child.children) == 1: + child = child.children[0] + return BasicType(BASE_TYPE_SPEC_TO_IDL_TYPE[child.data]) + + +def get_abstract_type_optionally_as_array(abstract_type, declarator): + assert len(declarator.children) == 1 + child = declarator.children[0] + if child.data == 'array_declarator': + fixed_array_sizes = list(child.find_data('fixed_array_size')) + assert len(fixed_array_sizes) == 1, \ + 'Unsupported multidimensional array: ' + str(declarator) + positive_int_const = next( + fixed_array_sizes[0].find_data('positive_int_const')) + size = get_positive_int_const(positive_int_const) + abstract_type = Array(abstract_type, size) + return abstract_type + + +def add_message_members(msg, tree): + members = tree.find_data('member') + for member in members: + # the find_data methods seems to traverse the tree in post order + # the highest type_spec in the subtree is therefore the last item + type_specs = list(member.find_data('type_spec')) + type_spec = type_specs[-1] + abstract_type = get_abstract_type_from_type_spec(type_spec) + declarators = member.find_data('declarator') + annotations = get_annotations(member) + for declarator in declarators: + assert len(declarator.children) == 1 + child = declarator.children[0] + if child.data == 'array_declarator': + fixed_array_sizes = list(child.find_data('fixed_array_size')) + assert len(fixed_array_sizes) == 1, \ + 'Unsupported multidimensional array: ' + str(member) + positive_int_const = next( + fixed_array_sizes[0].find_data('positive_int_const')) + size = get_positive_int_const(positive_int_const) + abstract_type = Array(abstract_type, size) + m = Member(abstract_type, get_first_identifier_value(declarator)) + m.annotations += annotations + msg.structure.members.append(m) + + +BASE_TYPE_SPEC_TO_IDL_TYPE = { + 'floating_pt_type_float': 'float', + 'floating_pt_type_double': 'double', + 'floating_pt_type_long_double': 'long double', + 'char_type': 'char', + 'wide_char_type': 'wchar', + 'boolean_type': 'boolean', + 'octet_type': 'octet', + 'signed_tiny_int': 'int8', + 'unsigned_tiny_int': 'uint8', + 'signed_short_int': 'int16', + 'unsigned_short_int': 'uint16', + 'signed_long_int': 'int32', + 'unsigned_long_int': 'uint32', + 'signed_longlong_int': 'int64', + 'unsigned_longlong_int': 'uint64', +} + + +def get_abstract_type_from_type_spec(type_spec): + assert len(type_spec.children) == 1 + child = type_spec.children[0] + return get_abstract_type(child) + + +def get_abstract_type(tree): + if 'simple_type_spec' == tree.data: + assert len(tree.children) == 1 + child = tree.children[0] + + if 'base_type_spec' == child.data: + while len(child.children) == 1: + child = child.children[0] + return BasicType(BASE_TYPE_SPEC_TO_IDL_TYPE[child.data]) + + if 'scoped_name' == child.data: + scoped_name_separators = list( + child.find_data('scoped_name_separator')) + if not scoped_name_separators: + return NamedType(get_first_identifier_value(child)) + identifiers = list(child.scan_values(_find_tokens('IDENTIFIER'))) + assert len(identifiers) > 1 + return NamespacedType(identifiers[:-1], identifiers[-1]) + + assert False, 'Unsupported tree: ' + str(child) + + if 'template_type_spec' == tree.data: + assert len(tree.children) == 1 + child = tree.children[0] + + if 'sequence_type' == child.data: + # the find_data methods seems to traverse the tree in post order + # the highest type_spec in the subtree is therefore the last item + type_specs = list(child.find_data('type_spec')) + type_spec = type_specs[-1] + basetype = get_abstract_type_from_type_spec(type_spec) + positive_int_consts = list(child.find_data('positive_int_const')) + if positive_int_consts: + path = _find_path(child, positive_int_consts[0]) + if len(path) > 2 and path[-2].data == 'string_type': + positive_int_consts.pop(0) + if positive_int_consts: + maximum_size = get_positive_int_const(positive_int_consts[-1]) + return BoundedSequence(basetype, maximum_size) + else: + return UnboundedSequence(basetype) + + if child.data in ('string_type', 'wide_string_type'): + if len(child.children) == 1: + assert child.children[0].data == 'positive_int_const' + maximum_size = get_positive_int_const(child.children[0]) + if 'string_type' == child.data: + assert maximum_size > 0 + return BoundedString(maximum_size=maximum_size) + if 'wide_string_type' == child.data: + return BoundedWString(maximum_size=maximum_size) + else: + if 'string_type' == child.data: + return UnboundedString() + if 'wide_string_type' == child.data: + return UnboundedWString() + + if 'fixed_pt_type' == child.data: + assert False, 'TODO' + + assert False, 'Unsupported tree: ' + str(child) + + assert False, 'Unsupported tree: ' + str(tree) + + +def get_positive_int_const(positive_int_const): + assert positive_int_const.data == 'positive_int_const' + # TODO support arbitrary expressions + try: + decimal_literal = next(positive_int_const.find_data('decimal_literal')) + except StopIteration: + pass + else: + digits = '' + for child in decimal_literal.children: + digits += child.value + return int(digits) + + try: + identifier_token = next( + positive_int_const.scan_values(_find_tokens('IDENTIFIER'))) + except StopIteration: + pass + else: + # TODO ensure that identifier resolves to a positive integer + return identifier_token.value + + assert False, 'Unsupported tree: ' + str(positive_int_const) + + +def get_annotations(tree): + annotations = [] + for c in tree.children: + if not isinstance(c, Tree): + continue + if c.data != 'annotation_appl': + continue + annotation_appl = c + params = list(annotation_appl.find_data('annotation_appl_param')) + if params: + value = {} + for param in params: + const_expr = next(param.find_data('const_expr')) + value[get_first_identifier_value(param)] = \ + get_const_expr_value(const_expr) + elif len(annotation_appl.children) == 1: + value = None + else: + const_expr = next(annotation_appl.find_data('const_expr')) + value = get_const_expr_value(const_expr) + annotations.append( + Annotation(get_first_identifier_value(annotation_appl), value)) + + return annotations + + +def get_const_expr_value(const_expr): + # TODO support arbitrary expressions + expr = list(const_expr.find_data('primary_expr')) + assert len(expr) == 1, str(expr) + primary_expr = expr[0] + assert len(primary_expr.children) == 1 + child = primary_expr.children[0] + if 'scoped_name' == child.data: + return str(child.children[0]) + elif 'literal' == child.data: + literal = child + unary_operator_minuses = list(const_expr.find_data('unary_operator_minus')) + negate_value = len(unary_operator_minuses) % 2 + + assert len(literal.children) == 1 + child = literal.children[0] + + if child.data == 'integer_literal': + assert len(child.children) == 1 + child = child.children[0] + + if child.data == 'decimal_literal': + value = get_decimal_literal_value(child) + if negate_value: + value = -value + return value + + assert False, 'Unsupported tree: ' + str(child) + + if child.data == 'floating_pt_literal': + value = get_floating_pt_literal_value(child) + if negate_value: + value = -value + return value + + if child.data == 'fixed_pt_literal': + value = get_fixed_pt_literal_value(child) + if negate_value: + value = -value + return value + + if child.data == 'boolean_literal': + assert len(child.children) == 1 + child = child.children[0] + assert child.data in ('boolean_literal_true', 'boolean_literal_false') + return child.data == 'boolean_literal_true' + + if child.data == 'string_literals': + assert not negate_value + return get_string_literals_value(child, allow_unicode=False) + + if child.data == 'wide_string_literals': + assert not negate_value + return get_string_literals_value(child, allow_unicode=True) + + assert False, 'Unsupported tree: ' + str(const_expr) + else: + assert False, 'Unsupported tree: ' + str(const_expr) + + +def get_decimal_literal_value(decimal_literal): + value = '' + for child in decimal_literal.children: + value += child.value + return int(value) + + +def get_floating_pt_literal_value(floating_pt_literal): + value = '' + for child in floating_pt_literal.children: + if isinstance(child, Token): + value += child.value + else: + assert False, 'Unsupported tree: ' + str(floating_pt_literal) + return float(value) + + +def get_fixed_pt_literal_value(fixed_pt_literal): + value = '' + for child in fixed_pt_literal.children: + if isinstance(child, Token): + value += child.value + else: + assert False, 'Unsupported tree: ' + str(fixed_pt_literal) + return float(value) + + +def get_string_literals_value(string_literals, *, allow_unicode=False): + assert len(string_literals.children) > 0 + value = '' + for string_literal in string_literals.children: + value += get_string_literal_value( + string_literal, allow_unicode=allow_unicode) + return value + + +def get_string_literal_value(string_literal, *, allow_unicode=False): + if len(string_literal.children) == 0: + return '' + assert len(string_literal.children) == 1 + child = string_literal.children[0] + assert isinstance(child, Token) + value = child.value + + assert child.type in ('ESCAPED_STRING', 'ESCAPED_WIDE_STRING') + if 'ESCAPED_WIDE_STRING' == child.type: + assert len(value) >= 3 + # Get rid of leading L" and trailing " + value = value[2:-1] + else: + assert len(value) >= 2 + # Get rid of leading " and trailing " + value = value[1:-1] + + regex = _get_escape_sequences_regex(allow_unicode=allow_unicode) + value = regex.sub(_decode_escape_sequence, value) + # unescape double quote and backslash if preceeded by a backslash + i = 0 + while i < len(value): + if value[i] == '\\': + if i + 1 < len(value) and value[i + 1] in ('"', '\\'): + value = value[:i] + value[i + 1:] + i += 1 + return value + + +def _get_escape_sequences_regex(*, allow_unicode): + # IDL Table 7-9: Escape sequences + pattern = '(' + # newline, horizontal tab, vertical tab, backspace, carriage return, + # form feed, alert, backslash, question mark, single quote, double quote + pattern += r'\\[ntvbrfa\\?\'"]' + # octal number + pattern += '|' + r'\\[0-7]{1,3}' + # hexadecimal number + pattern += '|' + r'\\x[0-9a-fA-F]{1,2}' + if allow_unicode: + # unicode character + pattern += '|' + r'\\u[0-9a-fA-F]{1,4}' + pattern += ')' + + return re.compile(pattern) + + +def _decode_escape_sequence(match): + return codecs.decode(match.group(0), 'unicode-escape') diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.py b/dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.py new file mode 100644 index 00000000000..d90be598072 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.py @@ -0,0 +1,250 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from io import StringIO +import json +import os +import pathlib +import re +import sys + +import em + +try: + from em import Configuration + em_has_configuration = True +except ImportError: + em_has_configuration = False + +from dimos.message_codegen._vendor.rosidl.rosidl_parser.definition import IdlLocator +from dimos.message_codegen._vendor.rosidl.rosidl_parser.parser import parse_idl_file + + +def convert_camel_case_to_lower_case_underscore(value): + # insert an underscore before any upper case letter + # which is followed by a lower case letter + value = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', value) + # insert an underscore before any upper case letter + # which is preseded by a lower case letter or number + value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', value) + return value.lower() + + +def read_generator_arguments(input_file): + with open(input_file, mode='r', encoding='utf-8') as h: + return json.load(h) + + +def get_newest_modification_time(target_dependencies): + newest_timestamp = None + for dep in target_dependencies: + ts = os.path.getmtime(dep) + if newest_timestamp is None or ts > newest_timestamp: + newest_timestamp = ts + return newest_timestamp + + +def generate_files( + generator_arguments_file, mapping, additional_context=None, + keep_case=False, post_process_callback=None +): + args = read_generator_arguments(generator_arguments_file) + + template_basepath = pathlib.Path(args['template_dir']) + for template_filename in mapping.keys(): + assert (template_basepath / template_filename).exists(), \ + 'Could not find template: ' + template_filename + + latest_target_timestamp = get_newest_modification_time(args['target_dependencies']) + generated_files = [] + + type_description_files = {} + for description_tuple in args.get('type_description_tuples', []): + tuple_parts = description_tuple.split(':', 1) + assert len(tuple_parts) == 2 + type_description_files[tuple_parts[0]] = tuple_parts[1] + ros_interface_files = {} + for ros_interface_file in args.get('ros_interface_files', []): + p = pathlib.Path(ros_interface_file) + # e.g. ('msg', 'Empty') + key = (p.suffix[1:], p.stem) + ros_interface_files[key] = p + + for idl_tuple in args.get('idl_tuples', []): + idl_parts = idl_tuple.rsplit(':', 1) + assert len(idl_parts) == 2 + locator = IdlLocator(*idl_parts) + idl_rel_path = pathlib.Path(idl_parts[1]) + + type_description_info = None + if type_description_files: + type_hash_file = type_description_files[idl_parts[1]] + with open(type_hash_file, 'r') as f: + type_description_info = json.load(f) + + idl_stem = idl_rel_path.stem + type_source_key = (idl_rel_path.parts[-2], idl_stem) + type_source_file = ros_interface_files.get(type_source_key, locator.get_absolute_path()) + if not keep_case: + idl_stem = convert_camel_case_to_lower_case_underscore(idl_stem) + try: + idl_file = parse_idl_file(locator) + for template_file, generated_filename in mapping.items(): + generated_file = os.path.join( + args['output_dir'], str(idl_rel_path.parent), + generated_filename % idl_stem) + generated_files.append(generated_file) + data = { + 'package_name': args['package_name'], + 'interface_path': idl_rel_path, + 'content': idl_file.content, + 'type_description_info': type_description_info, + 'type_source_file': type_source_file, + } + if additional_context is not None: + data.update(additional_context) + expand_template( + os.path.basename(template_file), data, + generated_file, minimum_timestamp=latest_target_timestamp, + template_basepath=template_basepath, + post_process_callback=post_process_callback) + except Exception as e: + print( + 'Error processing idl file: ' + + str(locator.get_absolute_path()), file=sys.stderr) + raise e + + return generated_files + + +template_prefix_path = [] + + +def get_template_path(template_name): + global template_prefix_path + for basepath in template_prefix_path: + template_path = basepath / template_name + if template_path.exists(): + return template_path + raise RuntimeError(f"Failed to find template '{template_name}'") + + +interpreter = None + + +def expand_template( + template_name, data, output_file, minimum_timestamp=None, + template_basepath=None, post_process_callback=None +): + # in the legacy API the first argument was the path to the template + if template_basepath is None: + template_name = pathlib.Path(template_name) + template_basepath = template_name.parent + template_name = template_name.name + + global template_prefix_path + template_prefix_path.append(template_basepath) + template_path = get_template_path(template_name) + + global interpreter + output = StringIO() + if em_has_configuration: + config = Configuration( + defaultRoot=template_path, + defaultStdout=output, + deleteOnError=True, + rawErrors=True, + useProxy=True) + interpreter = em.Interpreter( + config=config, + dispatcher=False) + else: + interpreter = em.Interpreter( + output=output, + options={ + em.BUFFERED_OPT: True, + em.RAW_OPT: True, + }, + ) + + # create copy before manipulating + data = dict(data) + _add_helper_functions(data) + + try: + with template_path.open('r') as h: + template_content = h.read() + interpreter.invoke( + 'beforeFile', name=template_name, file=h, locals=data) + if em_has_configuration: + interpreter.string(template_content, locals=data) + else: + interpreter.string(template_content, template_path, locals=data) + interpreter.invoke('afterFile') + except Exception as e: # noqa: F841 + if os.path.exists(output_file): + os.remove(output_file) + print(f"{e.__class__.__name__} when expanding '{template_name}' into " + f"'{output_file}': {e}", file=sys.stderr) + raise + finally: + template_prefix_path.pop() + + content = output.getvalue() + interpreter.shutdown() + + if post_process_callback: + content = post_process_callback(content) + + # only overwrite file if necessary + # which is either when the timestamp is too old or when the content is different + if os.path.exists(output_file): + timestamp = os.path.getmtime(output_file) + if minimum_timestamp is None or timestamp > minimum_timestamp: + with open(output_file, 'r', encoding='utf-8') as h: + if h.read() == content: + return + else: + # create folder if necessary + try: + os.makedirs(os.path.dirname(output_file)) + except FileExistsError: + pass + + with open(output_file, 'w', encoding='utf-8') as h: + h.write(content) + + +def _add_helper_functions(data): + data['TEMPLATE'] = _expand_template + + +def _expand_template(template_name, **kwargs): + global interpreter + template_path = get_template_path(template_name) + _add_helper_functions(kwargs) + with template_path.open('r') as h: + interpreter.invoke( + 'beforeInclude', name=str(template_path), file=h, locals=kwargs) + content = h.read() + try: + if em_has_configuration: + interpreter.string(content, locals=kwargs) + else: + interpreter.string(content, template_path, locals=kwargs) + except Exception as e: # noqa: F841 + print(f"{e.__class__.__name__} in template '{template_path}': {e}", + file=sys.stderr) + raise + interpreter.invoke('afterInclude') diff --git a/dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.pyi b/dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.pyi new file mode 100644 index 00000000000..b489d7f9683 --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/rosidl_pycommon/__init__.pyi @@ -0,0 +1,17 @@ +# Copyright 2026 Dimensional Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Mapping + +def generate_files(generator_arguments_file: str, mapping: Mapping[str, str]) -> list[str]: ... diff --git a/dimos/message_codegen/_vendor/rosidl/sources.json b/dimos/message_codegen/_vendor/rosidl/sources.json new file mode 100644 index 00000000000..ade6c77f4fd --- /dev/null +++ b/dimos/message_codegen/_vendor/rosidl/sources.json @@ -0,0 +1,117 @@ +{ + "repository": "https://github.com/ros2/rosidl", + "revision": "85fa592b698b0f665e3120f48fac0d35e2f7d8a4", + "patch": "Relocate Python imports into the vendored namespace; reuse the existing pinned rosidl_adapter parser. No generator templates or type/default rules changed.", + "files": { + "rosidl_adapter/__init__.py": { + "source": "rosidl_adapter/rosidl_adapter/__init__.py", + "upstream_sha256": "fb45e9222e2aec473c3aec8cf986830cc1e8093ddce28773e6012917b3ddc43e", + "sha256": "9bb9855a90b8fe146615d9564eac147fc82c68f818c7ca9ff0927c964b727898" + }, + "rosidl_adapter/msg/__init__.py": { + "source": "rosidl_adapter/rosidl_adapter/msg/__init__.py", + "upstream_sha256": "8c2176b4c06a1f3e9926887abf85bb978d86bd1702f026b8c4591228534fbfd6", + "sha256": "e1b81977d953b8d8b4e131d271b8cb0cf25c830a456e519636e311d1b56c55eb" + }, + "rosidl_adapter/resource/__init__.py": { + "source": "rosidl_adapter/rosidl_adapter/resource/__init__.py", + "upstream_sha256": "95fedb5dde3727364770d7b0f899f90f5faeecbc2e3ad5386061b3252799435a", + "sha256": "95fedb5dde3727364770d7b0f899f90f5faeecbc2e3ad5386061b3252799435a" + }, + "rosidl_adapter/resource/msg.idl.em": { + "source": "rosidl_adapter/rosidl_adapter/resource/msg.idl.em", + "upstream_sha256": "a88137989991e2565b1e24acee0c4df1b0f48d14c2be566c54c28fa6957ed828", + "sha256": "b7ba2612529e499d4473c01c177f96eeeeb3ccbaf2b9e89a2d1ef47374baf3fd" + }, + "rosidl_adapter/resource/struct.idl.em": { + "source": "rosidl_adapter/rosidl_adapter/resource/struct.idl.em", + "upstream_sha256": "cb06fbf7f471d418bc179a79509ef612549c05ca4ffc4a3bed4f6aea452f14ac", + "sha256": "ef4635f84d78b57bed03d1f3dc866854a7b2812c1ecb3a3c82bad3be5aac5c82" + }, + "rosidl_parser/__init__.py": { + "source": "rosidl_parser/rosidl_parser/__init__.py", + "upstream_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "rosidl_parser/definition.py": { + "source": "rosidl_parser/rosidl_parser/definition.py", + "upstream_sha256": "6d882e25ad6f59476839928e36b2ba05ab297ed24593af9654eba5ce9cfa1cd2", + "sha256": "6d882e25ad6f59476839928e36b2ba05ab297ed24593af9654eba5ce9cfa1cd2" + }, + "rosidl_parser/grammar.lark": { + "source": "rosidl_parser/rosidl_parser/grammar.lark", + "upstream_sha256": "74fbcb06037699e88592c6795c066535dad2b40cf06414551c64416867343f65", + "sha256": "74fbcb06037699e88592c6795c066535dad2b40cf06414551c64416867343f65" + }, + "rosidl_parser/parser.py": { + "source": "rosidl_parser/rosidl_parser/parser.py", + "upstream_sha256": "3ae02585b726a5a54038d8f7d1f0730090af320bea52b0935c624423566f298e", + "sha256": "70afaf3184dc1d62e8667fa1db5fc1d77f9f04d41149dd6baeb3e2a3f96ec452" + }, + "rosidl_pycommon/__init__.py": { + "source": "rosidl_pycommon/rosidl_pycommon/__init__.py", + "upstream_sha256": "d0fc43457e82bc442010af4e84f87d9d56390c6faf16cae9313493dd1496de47", + "sha256": "d4b2bc254e348679a2ef9e35b4f844e13d7ff3cf31038f4f467fa1d7185cf189" + }, + "rosidl_generator_cpp/__init__.py": { + "source": "rosidl_generator_cpp/rosidl_generator_cpp/__init__.py", + "upstream_sha256": "8205243d3d377b5b56d30c1a5429386034607e6d2a7b54d4f053439f1d72a316", + "sha256": "006e549d4315f28e2925794212573aa97d83da343e000bed2be7a42757cc188c" + }, + "rosidl_generator_cpp/resource/idl__struct.hpp.em": { + "source": "rosidl_generator_cpp/resource/idl__struct.hpp.em", + "upstream_sha256": "c652928b33243fc1744ba0fd8a8b474e7aa71f3919a79733c206d74fa81224e8", + "sha256": "45ecf5dee725d81e618f0222b01d416d365e62ad2d20a4808b502c704814ede8" + }, + "rosidl_generator_cpp/resource/msg__struct.hpp.em": { + "source": "rosidl_generator_cpp/resource/msg__struct.hpp.em", + "upstream_sha256": "fbcb625ebfafb3313cf9999cbe45b061c2867bff6a45ad84177d063258850488", + "sha256": "f8204e681ea31f52065d60e97a1de7978bdc0240857d66b18d5579f8083d17ba" + }, + "include/rosidl_runtime_cpp/bounded_vector.hpp": { + "source": "rosidl_runtime_cpp/include/rosidl_runtime_cpp/bounded_vector.hpp", + "upstream_sha256": "51bb701b7a8208064ac39b8d7f089c15043d503cda2241b8193b081af9df8808", + "sha256": "51bb701b7a8208064ac39b8d7f089c15043d503cda2241b8193b081af9df8808" + }, + "include/rosidl_runtime_cpp/message_initialization.hpp": { + "source": "rosidl_runtime_cpp/include/rosidl_runtime_cpp/message_initialization.hpp", + "upstream_sha256": "f687d74de409df8c9a41a449416b74d5ab25744926db44eca5328484b37128e5", + "sha256": "f687d74de409df8c9a41a449416b74d5ab25744926db44eca5328484b37128e5" + }, + "include/rosidl_runtime_c/message_initialization.h": { + "source": "rosidl_runtime_c/include/rosidl_runtime_c/message_initialization.h", + "upstream_sha256": "3ff6850b4fc347fc063e198e44075c22169de165706e94b6c7b35c3e938b285b", + "sha256": "3ff6850b4fc347fc063e198e44075c22169de165706e94b6c7b35c3e938b285b" + }, + "notices/rosidl_adapter/package.xml": { + "source": "rosidl_adapter/package.xml", + "upstream_sha256": "653c797d2b4e2f5e6ad7b18812632bf6bf55aa924dfbca0405439389a5273989", + "sha256": "653c797d2b4e2f5e6ad7b18812632bf6bf55aa924dfbca0405439389a5273989" + }, + "notices/rosidl_parser/package.xml": { + "source": "rosidl_parser/package.xml", + "upstream_sha256": "3973858ea09c6fb21b25a670201ab88ed46a998064ceac0e354335f3099fb739", + "sha256": "3973858ea09c6fb21b25a670201ab88ed46a998064ceac0e354335f3099fb739" + }, + "notices/rosidl_pycommon/package.xml": { + "source": "rosidl_pycommon/package.xml", + "upstream_sha256": "5af29a56018307a6d96632a5a94b9798ee4668983a214b21012f81a3e7fb5dd2", + "sha256": "5af29a56018307a6d96632a5a94b9798ee4668983a214b21012f81a3e7fb5dd2" + }, + "notices/rosidl_generator_cpp/package.xml": { + "source": "rosidl_generator_cpp/package.xml", + "upstream_sha256": "437b8959dd48fb8a71521044f563947b9d1f290ea49e2a3ba000c4921921462a", + "sha256": "437b8959dd48fb8a71521044f563947b9d1f290ea49e2a3ba000c4921921462a" + }, + "notices/rosidl_runtime_cpp/package.xml": { + "source": "rosidl_runtime_cpp/package.xml", + "upstream_sha256": "3a255de08073bd9b42e9b2509fe5d0db7e7f448467877715fc277f4144ce5d8f", + "sha256": "3a255de08073bd9b42e9b2509fe5d0db7e7f448467877715fc277f4144ce5d8f" + }, + "notices/rosidl_runtime_c/package.xml": { + "source": "rosidl_runtime_c/package.xml", + "upstream_sha256": "3fa7043a7d337c9dd27aeb976684d84750cb15df01f1606207f3e01b6485fc64", + "sha256": "3fa7043a7d337c9dd27aeb976684d84750cb15df01f1606207f3e01b6485fc64" + } + } +} diff --git a/dimos/message_codegen/cpp.py b/dimos/message_codegen/cpp.py index de665776833..fb7380ff73f 100644 --- a/dimos/message_codegen/cpp.py +++ b/dimos/message_codegen/cpp.py @@ -16,10 +16,16 @@ from __future__ import annotations +from contextlib import redirect_stdout +from dataclasses import asdict +from hashlib import sha256 +from io import StringIO import json -import math -from typing import Any +from pathlib import Path +from tempfile import TemporaryDirectory +from dimos.message_codegen._vendor.rosidl.rosidl_adapter import convert_to_idl +from dimos.message_codegen._vendor.rosidl.rosidl_pycommon import generate_files from dimos.message_codegen.definitions import FieldType, Message PRIMITIVES = { @@ -154,28 +160,6 @@ def type_name(type_: FieldType) -> str: return scalar -def literal(value: Any, type_name_: str) -> str: - if isinstance(value, tuple): - return "{" + ", ".join(literal(item, type_name_) for item in value) + "}" - if isinstance(value, str): - return ("L" if type_name_ == "wstring" else "") + json.dumps(value, ensure_ascii=True) - if isinstance(value, bool): - return "true" if value else "false" - if isinstance(value, float): - native = PRIMITIVES[type_name_] - if math.isnan(value): - return f"std::numeric_limits<{native}>::quiet_NaN()" - if math.isinf(value): - sign = "-" if value < 0 else "" - return f"{sign}std::numeric_limits<{native}>::infinity()" - return repr(value) + ("f" if type_name_ == "float32" else "") - if type_name_ == "uint64": - return f"{value}ULL" - if type_name_ == "int64" and value == -(2**63): - return "(-9223372036854775807LL - 1)" - return str(value) - - def validation(message: Message) -> list[str]: lines = [] for field in message.fields: @@ -214,30 +198,87 @@ def generate(messages: tuple[Message, ...]) -> str: "#include ", '#include "dimos_cdr.hpp"', ] - for message in messages: - namespace = qualified(message.name.rsplit("/", 1)[0]) - name = identifier(message.short_name) - lines.extend([f"namespace {namespace} {{", f"struct {name} {{"]) - for constant in message.constants: - native = PRIMITIVES[constant.type] - if constant.type in {"string", "wstring"}: - native = "const wchar_t*" if constant.type == "wstring" else "const char*" - lines.append( - f"static constexpr {native} {identifier(constant.name)} = {literal(constant.value, constant.type)};" + upstream = Path(__file__).with_name("_vendor") / "rosidl" + for name in [ + "rosidl_runtime_c/message_initialization.h", + "rosidl_runtime_cpp/message_initialization.hpp", + "rosidl_runtime_cpp/bounded_vector.hpp", + ]: + lines.append( + "\n".join( + line + for line in (upstream / "include" / name).read_text().splitlines() + if not line.startswith("#include