Skip to content

Roslibrust message generation#11

Merged
YuanYuYuan merged 59 commits intomainfrom
dev/msg-gen
Nov 13, 2025
Merged

Roslibrust message generation#11
YuanYuYuan merged 59 commits intomainfrom
dev/msg-gen

Conversation

@YuanYuYuan
Copy link
Collaborator

@YuanYuYuan YuanYuYuan commented Nov 13, 2025

Closes #10

Introduces a new MessageTypeInfo trait that provides compile-time
message metadata including type name, hash, and package information.
This trait is independent of serialization format and enables proper
ROS2 type compatibility checking.

- Add MessageTypeInfo trait with type_name(), type_hash(), type_info()
- Add package_name() and is_fixed_size() helper methods
- Update all existing message types to implement MessageTypeInfo
- Export MessageTypeInfo from lib.rs for public API
- Maintain backward compatibility via WithTypeInfo trait alias

The trait follows the extensible design pattern to support both
manually-defined and auto-generated message types.
Refactor create_pub and create_sub methods to use shared implementation
functions, reducing code duplication and making the API more maintainable.

- Extract create_pub_impl() for shared publisher creation logic
- Extract create_sub_impl() for shared subscriber creation logic
- Preserve existing create_pub_with_info() and create_sub_with_info() methods
- No API changes, purely internal refactoring
Create a new code generation library that wraps roslibrust_codegen
and generates MessageTypeInfo trait implementations with proper
ROS2 RIHS01 hashes.

- Create ros-z-codegen crate with roslibrust adapter
- Implement MessageGenerator and GeneratorConfig
- Add TypeInfoGenerator for MessageTypeInfo trait generation
- Parse ROS message files and calculate RIHS01 hashes
- Generate Rust code with proper type metadata

Uses local roslibrust dependency for extensibility and to access
ROS2 hash calculation internals.
Create a new crate that auto-generates ROS message types at build time
from system ROS2 packages or bundled definitions.

- Create ros-z-msgs crate with build.rs script
- Auto-discover ROS2 packages from nix-ros installation
- Fall back to roslibrust bundled assets if needed
- Generate MessageTypeInfo implementations with real RIHS01 hashes
- Support feature flags for selective package generation

The crate uses ros-z-codegen to generate Rust types from .msg files
found in the system ROS2 installation, enabling proper type safety
and hash verification for ROS2 interoperability.
Update workspace configuration to include new crates for message
code generation and auto-generated message types.

- Add ros-z-codegen and ros-z-msgs as workspace members
- Update Cargo.lock with new dependencies
- Add lifetime bounds to ZSerializer Input types (T: 'a)
- Fix CdrSerdes to use byteorder::LittleEndian for CDR serialization
- Fix CdrSerdes deserialization to extract tuple result (.0)
- Add blanket ZMessage implementation for all serde-compatible types
- Fix ProtobufSerdes lifetime bounds for feature-gated code
- Remove incorrect #[macro_export] from utils.rs import
- Add 'static bounds to ZPubBuilder/ZSubBuilder generic parameters
- Import impl_with_type_info macro in pubsub.rs and service.rs
- Add feature gate for ProtobufSerdes import in pubsub.rs
- Add byteorder 1.3 for CDR serialization compatibility
- Add ros-z-msgs as dev-dependency for examples
- Fix generate_from_msg_files to pass correct parameters to adapter
- Fix protobuf_adapter string formatting with proper escape sequences
- Remove syntax error (stray 'h' character) in ros_to_proto_type
Enable the 'codegen' feature on roslibrust dependency to make
roslibrust::codegen module available for generated message code.
This resolves compilation errors where generated derives referenced
missing ::roslibrust::codegen::Serialize and similar types.
- Update z_pubsub.rs to use ros-z-msgs::std_msgs::ByteMultiArray
- Update z_pubsub_multi_format.rs to use ros-z-msgs::geometry_msgs::Vector3
- Add vector3_protobuf_demo.rs showing manual protobuf integration
- Use MessageTypeInfo trait for automatic type info population
- Remove manual TypeInfo construction with hardcoded hashes
Update Cargo.lock and workspace configuration to reflect
dependency changes and new crate structure.
Add complete protobuf code generation pipeline:
- Convert ROS2 .msg files to .proto definitions
- Generate Rust code from .proto using prost_build
- Auto-generate MessageTypeInfo implementations for proto types
- Auto-generate ZMessage implementations using ProtobufSerdes

The adapter integrates with roslibrust_codegen to:
1. Parse ROS2 messages and extract field information
2. Map ROS types to protobuf types (int8/int16->int32, arrays->repeated)
3. Generate one .proto file per package
4. Compile .proto files to Rust with prost::Message derives
5. Add ros-z trait implementations for seamless integration

Protobuf types are generated alongside CDR types and exposed in
the proto:: module when the 'protobuf' feature is enabled.
Expose auto-generated protobuf types in the proto:: module when the
'protobuf' feature is enabled. Users can now choose between:

- CDR serialization: geometry_msgs::Vector3 (default, ROS2-compatible)
- Protobuf serialization: proto::geometry_msgs::Vector3 (cross-platform)

Add comprehensive PROTOBUF.md documentation covering:
- Requirements (protoc installation)
- Usage examples for both CDR and protobuf
- Type mapping table
- Architecture overview
- Troubleshooting guide

Simplify build.rs by removing old placeholder protobuf code since
generation is now handled by the unified generate_from_msg_files API.
- Add WithTypeInfo trait implementation to generated types
- Remove unused imports from type_info_generator
- Add feature gates for protobuf in vector3_protobuf_demo
- Fix field name references in examples (remove r# prefix)
- Add documentation for backward compatibility and auto-generated messages
- Remove POST_DESERIALIZATION const generic parameter
- Simplify ZSubBuilder to always pass Sample without deserializing in callback
- Remove post_deserialization() method
- Remove unused serde::Deserialize import
- Subscribers now always perform post-deserialization (defer deserialization)
- Specify RosSerdes explicitly for publisher and subscriber builders
- Update ZPub and ZSub type signatures to include serializer parameter
- Use recv_serialized() instead of recv() for raw Sample access
- Remove post_deserialization() call (no longer exists)
- Use recv() for automatic deserialization (ROS-aligned behavior)
- Remove commented post_deserialization() call
- Fix import paths in battery_state_sub.rs for sensor_msgs types
- Remove unused imports across multiple example files
- Move ByteMultiArray test from ros-z to ros-z-msgs test suite
- Add cdr dev-dependency to ros-z-msgs for testing
- Replace nix-specific paths with standard ROS 2 environment variables
- Check AMENT_PREFIX_PATH and CMAKE_PREFIX_PATH for package discovery
- Add common ROS 2 installation paths as fallback
- Support builtin_interfaces, std_msgs, geometry_msgs, sensor_msgs
- Use cargo features to determine which packages to generate
Add examples/protobuf_demo/ demonstrating two protobuf approaches:
1. ROS messages with protobuf serialization (from ros-z-msgs)
2. Custom .proto file messages (pure protobuf, non-ROS)

This shows ros-z's transport-agnostic design - it can send ANY
protobuf message, not just ROS messages.

Files:
- proto/sensor_data.proto: Custom protobuf message definition
- build.rs: Compiles .proto files at build time
- src/main.rs: Demonstrates both ROS and custom protobuf messages
- README.md: Documentation and usage instructions
Combine laser_scan_pub.rs and laser_scan_sub.rs into single laser_scan.rs
with command-line mode selection (--mode pub|sub).

This provides a cleaner example structure with:
- Unified codebase for both publisher and subscriber
- Command-line argument parsing using clap
- Separate run_publisher() and run_subscriber() functions

Usage:
  cargo run --example laser_scan -- --mode pub
  cargo run --example laser_scan -- --mode sub
These build artifacts should not be tracked in version control.
Remove old example files that have been refactored:
- laser_scan_pub.rs, laser_scan_sub.rs: merged into laser_scan.rs
- vector3_protobuf_demo.rs: replaced by examples/protobuf_demo/
- z_native_ping.rs, z_native_pong.rs, z_ping.rs, z_pong.rs: old ping/pong examples
- z_pub.rs, z_sub.rs, z_pubsub_multi_format.rs: replaced by updated z_pubsub.rs

Update Cargo.lock and related files to reflect these changes.
Update create_service and create_client to require ServiceTypeInfo trait,
enabling automatic type information population. Add timeout variants for
response handling and fix attachment handling in service responses.
Update tests to use the new service API with generated ServiceTypeInfo
types. Tests now properly demonstrate ros-z to ros-z service communication
using the take_request/send_response pattern.
Use ProstMessage::encode() for protobuf serialization instead of
incorrectly using cdr_encoding which requires Serialize trait.
- Remove needless borrows
- Use derive for Default implementation
- Collapse nested if statements
Remove z_client.rs and z_server.rs which used hand-written AddTwoInts
service. The z_srvcli.rs example provides the same functionality using
properly generated messages from ros-z-msgs.
- Use direct struct initialization instead of default + field assignment
- Remove unnecessary let binding for unit value
Replace push_str with single-character strings with more efficient
push calls using character literals.
- Use block expression with vec! initialization for package names
- Collapse nested if statements using if-let chain
- Consolidated all shared dependencies in workspace [workspace.dependencies]
- Updated ros-z, rcl-z, ros-z-codegen, ros-z-msgs, and ros-z-tests to use workspace dependencies
- Moved local roslibrust dependencies to workspace level
- Organized dependencies by category for better maintainability
- Add dependency collection and proper imports to protobuf adapter
- Implement MessageTypeInfo/ServiceTypeInfo for RosMessage/RosService
- Add dynamic type info methods for runtime type discovery
- Fix CDR serialization with proper encapsulation header
- Re-enable ROS2 interoperability tests with serial execution
- Add TypeHash::zero() for placeholder hashes in generic wrappers
- Remove workspace default-members to include all crates in builds
@YuanYuYuan YuanYuYuan merged commit 760d6fe into main Nov 13, 2025
2 checks passed
@YuanYuYuan YuanYuYuan deleted the dev/msg-gen branch November 20, 2025 04:50
YuanYuYuan added a commit that referenced this pull request Dec 9, 2025
* fix: graph

* feat: handcraft more ros messages

* build: bump zenoh to 1.6.2

* feat: add MessageTypeInfo trait for message metadata

Introduces a new MessageTypeInfo trait that provides compile-time
message metadata including type name, hash, and package information.
This trait is independent of serialization format and enables proper
ROS2 type compatibility checking.

- Add MessageTypeInfo trait with type_name(), type_hash(), type_info()
- Add package_name() and is_fixed_size() helper methods
- Update all existing message types to implement MessageTypeInfo
- Export MessageTypeInfo from lib.rs for public API
- Maintain backward compatibility via WithTypeInfo trait alias

The trait follows the extensible design pattern to support both
manually-defined and auto-generated message types.

* refactor: simplify publisher/subscriber creation in node

Refactor create_pub and create_sub methods to use shared implementation
functions, reducing code duplication and making the API more maintainable.

- Extract create_pub_impl() for shared publisher creation logic
- Extract create_sub_impl() for shared subscriber creation logic
- Preserve existing create_pub_with_info() and create_sub_with_info() methods
- No API changes, purely internal refactoring

* feat: add ros-z-codegen crate for message generation

Create a new code generation library that wraps roslibrust_codegen
and generates MessageTypeInfo trait implementations with proper
ROS2 RIHS01 hashes.

- Create ros-z-codegen crate with roslibrust adapter
- Implement MessageGenerator and GeneratorConfig
- Add TypeInfoGenerator for MessageTypeInfo trait generation
- Parse ROS message files and calculate RIHS01 hashes
- Generate Rust code with proper type metadata

Uses local roslibrust dependency for extensibility and to access
ROS2 hash calculation internals.

* feat: add ros-z-msgs crate for auto-generated messages

Create a new crate that auto-generates ROS message types at build time
from system ROS2 packages or bundled definitions.

- Create ros-z-msgs crate with build.rs script
- Auto-discover ROS2 packages from nix-ros installation
- Fall back to roslibrust bundled assets if needed
- Generate MessageTypeInfo implementations with real RIHS01 hashes
- Support feature flags for selective package generation

The crate uses ros-z-codegen to generate Rust types from .msg files
found in the system ROS2 installation, enabling proper type safety
and hash verification for ROS2 interoperability.

* build: add ros-z-codegen and ros-z-msgs to workspace

Update workspace configuration to include new crates for message
code generation and auto-generated message types.

- Add ros-z-codegen and ros-z-msgs as workspace members
- Update Cargo.lock with new dependencies

* fix: resolve compilation errors in message serialization traits

- Add lifetime bounds to ZSerializer Input types (T: 'a)
- Fix CdrSerdes to use byteorder::LittleEndian for CDR serialization
- Fix CdrSerdes deserialization to extract tuple result (.0)
- Add blanket ZMessage implementation for all serde-compatible types
- Fix ProtobufSerdes lifetime bounds for feature-gated code
- Remove incorrect #[macro_export] from utils.rs import

* fix: add proper lifetime bounds and macro imports for builders

- Add 'static bounds to ZPubBuilder/ZSubBuilder generic parameters
- Import impl_with_type_info macro in pubsub.rs and service.rs
- Add feature gate for ProtobufSerdes import in pubsub.rs

* build: add byteorder dependency and ros-z-msgs dev-dependency

- Add byteorder 1.3 for CDR serialization compatibility
- Add ros-z-msgs as dev-dependency for examples

* fix: correct ros-z-codegen API and string formatting

- Fix generate_from_msg_files to pass correct parameters to adapter
- Fix protobuf_adapter string formatting with proper escape sequences
- Remove syntax error (stray 'h' character) in ros_to_proto_type

* fix: enable roslibrust codegen feature for ros-z-msgs

Enable the 'codegen' feature on roslibrust dependency to make
roslibrust::codegen module available for generated message code.
This resolves compilation errors where generated derives referenced
missing ::roslibrust::codegen::Serialize and similar types.

* feat: migrate examples to use auto-generated ros-z-msgs

- Update z_pubsub.rs to use ros-z-msgs::std_msgs::ByteMultiArray
- Update z_pubsub_multi_format.rs to use ros-z-msgs::geometry_msgs::Vector3
- Add vector3_protobuf_demo.rs showing manual protobuf integration
- Use MessageTypeInfo trait for automatic type info population
- Remove manual TypeInfo construction with hardcoded hashes

* chore: update workspace Cargo files

Update Cargo.lock and workspace configuration to reflect
dependency changes and new crate structure.

* feat: implement protobuf adapter for ROS2 message generation

Add complete protobuf code generation pipeline:
- Convert ROS2 .msg files to .proto definitions
- Generate Rust code from .proto using prost_build
- Auto-generate MessageTypeInfo implementations for proto types
- Auto-generate ZMessage implementations using ProtobufSerdes

The adapter integrates with roslibrust_codegen to:
1. Parse ROS2 messages and extract field information
2. Map ROS types to protobuf types (int8/int16->int32, arrays->repeated)
3. Generate one .proto file per package
4. Compile .proto files to Rust with prost::Message derives
5. Add ros-z trait implementations for seamless integration

Protobuf types are generated alongside CDR types and exposed in
the proto:: module when the 'protobuf' feature is enabled.

* feat: add protobuf module to ros-z-msgs

Expose auto-generated protobuf types in the proto:: module when the
'protobuf' feature is enabled. Users can now choose between:

- CDR serialization: geometry_msgs::Vector3 (default, ROS2-compatible)
- Protobuf serialization: proto::geometry_msgs::Vector3 (cross-platform)

Add comprehensive PROTOBUF.md documentation covering:
- Requirements (protoc installation)
- Usage examples for both CDR and protobuf
- Type mapping table
- Architecture overview
- Troubleshooting guide

Simplify build.rs by removing old placeholder protobuf code since
generation is now handled by the unified generate_from_msg_files API.

* refactor: improve message type system and update examples

- Add WithTypeInfo trait implementation to generated types
- Remove unused imports from type_info_generator
- Add feature gates for protobuf in vector3_protobuf_demo
- Fix field name references in examples (remove r# prefix)
- Add documentation for backward compatibility and auto-generated messages

* chore: ignore all target folders

* refactor(ros-z): remove post_deserialization mode from ZSubBuilder

- Remove POST_DESERIALIZATION const generic parameter
- Simplify ZSubBuilder to always pass Sample without deserializing in callback
- Remove post_deserialization() method
- Remove unused serde::Deserialize import
- Subscribers now always perform post-deserialization (defer deserialization)

* fix(rcl-z): update to use explicit RosSerdes and new subscriber API

- Specify RosSerdes explicitly for publisher and subscriber builders
- Update ZPub and ZSub type signatures to include serializer parameter
- Use recv_serialized() instead of recv() for raw Sample access
- Remove post_deserialization() call (no longer exists)

* refactor(ros-z): update z_sub example to use new recv() API

- Use recv() for automatic deserialization (ROS-aligned behavior)
- Remove commented post_deserialization() call

* fix(ros-z): resolve cargo check errors and warnings in examples

- Fix import paths in battery_state_sub.rs for sensor_msgs types
- Remove unused imports across multiple example files
- Move ByteMultiArray test from ros-z to ros-z-msgs test suite
- Add cdr dev-dependency to ros-z-msgs for testing

* feat(ros-z-msgs): make ROS package discovery environment-agnostic

- Replace nix-specific paths with standard ROS 2 environment variables
- Check AMENT_PREFIX_PATH and CMAKE_PREFIX_PATH for package discovery
- Add common ROS 2 installation paths as fallback
- Support builtin_interfaces, std_msgs, geometry_msgs, sensor_msgs
- Use cargo features to determine which packages to generate

* feat(ros-z): add comprehensive protobuf example

Add examples/protobuf_demo/ demonstrating two protobuf approaches:
1. ROS messages with protobuf serialization (from ros-z-msgs)
2. Custom .proto file messages (pure protobuf, non-ROS)

This shows ros-z's transport-agnostic design - it can send ANY
protobuf message, not just ROS messages.

Files:
- proto/sensor_data.proto: Custom protobuf message definition
- build.rs: Compiles .proto files at build time
- src/main.rs: Demonstrates both ROS and custom protobuf messages
- README.md: Documentation and usage instructions

* refactor(ros-z): merge laser_scan pub/sub examples

Combine laser_scan_pub.rs and laser_scan_sub.rs into single laser_scan.rs
with command-line mode selection (--mode pub|sub).

This provides a cleaner example structure with:
- Unified codebase for both publisher and subscriber
- Command-line argument parsing using clap
- Separate run_publisher() and run_subscriber() functions

Usage:
  cargo run --example laser_scan -- --mode pub
  cargo run --example laser_scan -- --mode sub

* chore: remove rust-analyzer flycheck artifacts

These build artifacts should not be tracked in version control.

* chore: remove obsolete example files

Remove old example files that have been refactored:
- laser_scan_pub.rs, laser_scan_sub.rs: merged into laser_scan.rs
- vector3_protobuf_demo.rs: replaced by examples/protobuf_demo/
- z_native_ping.rs, z_native_pong.rs, z_ping.rs, z_pong.rs: old ping/pong examples
- z_pub.rs, z_sub.rs, z_pubsub_multi_format.rs: replaced by updated z_pubsub.rs

Update Cargo.lock and related files to reflect these changes.

* feat(ros-z-codegen): add support for ROS 2 service

* feat(nix): add nix support

* style: cargo fmt

* refactor: integrate interop into cargo test

* fix: cdr-encoding assumes no encapsulation is used

* chore: update build configuration and dependencies

- Add .envrc and .direnv to .gitignore for direnv support
- Update cdr-encoding to use fork with byte buffer support
- Simplify flake.nix configuration

* fix: improve QoS profile encoding to match ROS2 format

Update QoS encoding to only include non-default values and properly
format history depth according to ROS2 conventions. This improves
interoperability with ROS2 nodes.

* feat: generate ServiceTypeInfo trait implementations for services

Add code generation for ServiceTypeInfo and ZService trait implementations
for all generated service types. This enables proper type information and
service discovery in ros-z.

* feat: add ServiceTypeInfo constraint to service creation APIs

Update create_service and create_client to require ServiceTypeInfo trait,
enabling automatic type information population. Add timeout variants for
response handling and fix attachment handling in service responses.

* test: update service interop tests to use new service API

Update tests to use the new service API with generated ServiceTypeInfo
types. Tests now properly demonstrate ros-z to ros-z service communication
using the take_request/send_response pattern.

* fix: use protobuf encode method instead of cdr_encoding

Use ProstMessage::encode() for protobuf serialization instead of
incorrectly using cdr_encoding which requires Serialize trait.

* fix: apply clippy suggestions

- Remove needless borrows
- Use derive for Default implementation
- Collapse nested if statements

* refactor: remove outdated service examples

Remove z_client.rs and z_server.rs which used hand-written AddTwoInts
service. The z_srvcli.rs example provides the same functionality using
properly generated messages from ros-z-msgs.

* style: apply clippy suggestions to examples

- Use direct struct initialization instead of default + field assignment
- Remove unnecessary let binding for unit value

* style: use push(char) instead of push_str for single characters

Replace push_str with single-character strings with more efficient
push calls using character literals.

* style: refactor build.rs to address clippy warnings

- Use block expression with vec! initialization for package names
- Collapse nested if statements using if-let chain

* refactor: use workspace dependencies across all crates

- Consolidated all shared dependencies in workspace [workspace.dependencies]
- Updated ros-z, rcl-z, ros-z-codegen, ros-z-msgs, and ros-z-tests to use workspace dependencies
- Moved local roslibrust dependencies to workspace level
- Organized dependencies by category for better maintainability

* style: fmt

* feat: enhance protobuf generation and type system

- Add dependency collection and proper imports to protobuf adapter
- Implement MessageTypeInfo/ServiceTypeInfo for RosMessage/RosService
- Add dynamic type info methods for runtime type discovery
- Fix CDR serialization with proper encapsulation header
- Re-enable ROS2 interoperability tests with serial execution
- Add TypeHash::zero() for placeholder hashes in generic wrappers
- Remove workspace default-members to include all crates in builds

* chore: add gdb

* style: cargo clippy

* refactor: use the forked roslibrust

* ci: test the new ci

* test: switch to jazzy to use cache

* Revert "test: switch to jazzy to use cache"

This reverts commit cf88c82.

* style: cargo fmt

* test: switch to jazzy to use cache

* ci: skip the test for the time being

* ci: address the duplicated CI

* ci: add interop test

* doc: tidy up
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Serdes Agnostic API

1 participant