Skip to content

feat(equivalences): support per-field ROS type overrides - #23

Open
MerinoSheep wants to merge 1 commit into
rai-opensource:mainfrom
MerinoSheep:feat/field-type-overrides
Open

feat(equivalences): support per-field ROS type overrides#23
MerinoSheep wants to merge 1 commit into
rai-opensource:mainfrom
MerinoSheep:feat/field-type-overrides

Conversation

@MerinoSheep

Copy link
Copy Markdown

Proposed changes

Adds field_type_overrides: a map from fully qualified Protobuf field name to ROS type, overriding one field's ROS type without touching the .proto.

Protobuf has no fixed-size arrays, so a covariance matrix must be repeated double. ROS has float64[36]. Existing message_mapping and package_mapping only remap whole message types.

field_type_overrides:
  proto2ros_tests.FixedSizeVector.values: float64[3]

Changes:

  • Configuration.field_type_overrides + README row.
  • translate_field resolves the override by field FQN, in place of translate_type.
  • New fixed-size array branch in both conversion templates — std::array has no clear()/reserve()/assign().

Protobuf -> ROS, by source length:

Length Behavior
0 zero-fill (field left unset)
N copy
other throw / raise

Partial copies are never produced. ROS -> Protobuf needs no special handling.

Rejected at generation time:

  • repeated field, override not a fixed-size array
  • repeated field, composite element type (no conversion code generated for these)
  • singular field, array override
  • override combined with an any expansion

Checklist

  • Lint and unit tests pass locally
  • I have added tests that prove my changes are effective
  • I have added necessary documentation to communicate the changes

Additional comments

Run in containers from .devcontainer/Dockerfile via the CI chain (colcon build && colcon test && colcon test-result --all --verbose):

Distro Result
humble 45 tests, 0 errors, 0 failures
jazzy 45 tests, 0 errors, 0 failures

Lint clean at pinned .pre-commit-config.yaml versions (ruff 0.14.4, black 25.11.0, mypy 1.18.2, cpplint 1.6.1, clang-format 16.0.2).

The zero-fill literal is type-derived (0.0, False, "", 0) — generated Python type checks each array item, so a bare 0 is rejected for float64[N]. C++ uses .fill({}).

Repeated composite overrides are a possible follow-up: the composite branch of both templates would need the same three cases, using indexed assignment instead of emplace_back.

Add field_type_overrides to Configuration, letting a single Protobuf
field's ROS type be overridden without remapping the whole message.
Repeated fields may only be overridden to a fixed-size array of
primitive types, which is handled in both C++ and Python conversion
templates (zero-fill when the Protobuf field is unset, raise on length
mismatch). Overrides of repeated composite types are rejected at
validation time, since no conversion code is generated for them.

An override short-circuits type translation rather than replacing its
result, and reuses the fully qualified field name already computed for
the any-expansion lookup. Fixed-size array detection uses the existing
rosidl_adapter Type.is_fixed_size_array() rather than a local copy.

Adds regression tests (FixedSizeVector) mirroring the pattern used for
the other config knobs, and documents the new option in the README.
@MerinoSheep
MerinoSheep force-pushed the feat/field-type-overrides branch from 49824fd to 6dd8c88 Compare August 19, 2026 07:53
@mhidalgo-rai
mhidalgo-rai self-requested a review August 31, 2026 14:26

@mhidalgo-rai mhidalgo-rai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MerinoSheep thanks for the contribution, and sorry for delay. This one fell off my radar.

Code itself looks correct, but the functionality does make me wonder. Is it more general than it can be? The set of field type override tuples we can automatically handle is quite narrow when accounting for conversion code. That's why message re-mapping are whole.

So should this be a field_bounds setting instead?

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.

2 participants