Skip to content

feat(transport): share CDR and legacy codecs across existing transports - #4722

Open
TomCC7 wants to merge 3 commits into
cc/feat/cdr-unit-external-messagesfrom
cc/feat/cdr-unit-transports
Open

TomCC7 wants to merge 3 commits into
cc/feat/cdr-unit-external-messagesfrom
cc/feat/cdr-unit-transports

Conversation

@TomCC7

@TomCC7 TomCC7 commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

What this adds

  • Add a shared MessageCodec interface with LCM and CDR implementations.
  • Bind the codec from the declared message type in existing LCM, Zenoh and WebRTC transports.
  • Keep legacy message encoding and explicit pickle/raw channels working during migration.

Base: #4721. CDR serialization and type registration come from cdrgen. Transports retain their existing connection, subscription and QoS behavior.

Validation and limits

Tests cover codec round trips, invalid types and payloads, and existing transport behavior. Business message migration, native SDK integration and schema negotiation remain later work. ROS/DDS need their own type adapters.

Published CDR dependency update

Consume published dimos-cdrgen==0.1.2 throughout this stack, including packaging examples, the Python lock and the Nix generator wheel. PyPI release and successful publisher run. Downloaded wheel/sdist hashes match that run's artifacts exactly.

The external CDR library fix is available as fork release v0.2.4-dimos.1, pinned to its tested commit. Shared SDK API 0.2.0 is isolated in #4774; explicit legacy SDK 0.1.0 pins remain compatible and are respected by autofix. No DimOS PR has been merged.

Final combined-stack verification after installing the published generator: SDK 158, adapters 2, mapper 102, MLS 135, local planner 93, follower 63, V4L2 6 tests; all 12 real native/DimSim exchanges pass. The seven Nix source-staging layouts pass locked Cargo dependency resolution using archive 8101c8db4a50043f1dbd0127fd00220ec9b5a37a. Full Nix builds and hardware/model-dependent tests remain unverified. These are combined-tip results, not independent full test runs of every intermediate PR.

Final native CI passed on the exact stack tip, including SDK/consumer builds, Rust tests and all 12 native/DimSim exchanges: https://github.com/dimensionalOS/dimos/actions/runs/39851662834

@github-actions github-actions Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

go2 replay realtime (arm64)

Details
Benchmark suite Current: deecf9a Previous: ecc2b8f Ratio
peak memory 1602.242 MB 1570.996 MB 1.02
peak threads 357 threads 355 threads 1.01
network (transport) 2722.06 MB 2730.387 MB 1.00
disk write 1.719 MB 1.496 MB 1.15
instructions 115.629 G 115 G 1.01

This comment was automatically generated by workflow using github-action-benchmark.

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
7279 1 7278 61
View the top 1 failed test(s) by shortest run time
dimos.perception.detection.type.test_detection3d::test_guess_projection
Stack Traces | 0.725s run time
get_moment_2d = <functools._lru_cache_wrapper object at 0x7a5813a70040>
publish_moment = <function publish_moment.<locals>.publisher at 0x7a5813ca14e0>

    def test_guess_projection(get_moment_2d, publish_moment) -> None:
        moment = get_moment_2d()
        for key, value in moment.items():
            print(key, "====================================")
            print(value)
    
        moment.get("camera_info")
        detection2d = moment.get("detections2d")[0]
        tf = moment.get("tf")
        tf.get("camera_optical", "world", detection2d.ts, 5.0)
    
        # for stash
        # detection3d = Detection3D.from_2d(detection2d, 1.5, camera_info, transform)
        # print(detection3d)
    
>       publish_moment(moment)

detection2d = Detection2DBBox(bbox=(503.43731689453125, 249.89385986328125, 655.9505004882812, 469.82879638671875), track_id=1, clas...70.490248, image=Image(shape=(720, 1280, 3), format=BGR, dtype=uint8, frame_id='camera_optical', ts=1757960670.490248))
get_moment_2d = <functools._lru_cache_wrapper object at 0x7a5813a70040>
key        = 'detections2d'
moment     = {'camera_info': CameraInfo(height=720, width=1280, distortion_model='equidistant', frame_id='camera_optical', ts=17926...optical', ts=1757960670.490248), 'lidar_frame': PointCloud(points=31284, frame_id='world', ts=1757960670.4755309), ...}
publish_moment = <function publish_moment.<locals>.publisher at 0x7a5813ca14e0>
tf         = <dimos.protocol.tf.tf.TF object at 0x7a5813176ed0>
value      = <dimos.perception.detection.type.detection2d.imageDetections2D.ImageDetections2D object at 0x7a5813d089e0>

.../detection/type/test_detection3d.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../perception/detection/conftest.py:126: in publisher
    detections.publish(detections2d_val.to_ros_detection2d_array())
        detections = <dimos.core.transport.LCMTransport object at 0x7a5867a7ebd0>
        detections2d_val = <dimos.perception.detection.type.detection2d.imageDetections2D.ImageDetections2D object at 0x7a5813d089e0>
        moment     = {'camera_info': CameraInfo(height=720, width=1280, distortion_model='equidistant', frame_id='camera_optical', ts=17926...optical', ts=1757960670.490248), 'lidar_frame': PointCloud(points=31284, frame_id='world', ts=1757960670.4755309), ...}
dimos/core/stream.py:107: in publish
    self.broadcast(None, msg)
        msg        = <dimos_lcm.vision_msgs.Detection2DArray.Detection2DArray object at 0x7a589777a500>
        self       = <dimos.core.transport.LCMTransport object at 0x7a5867a7ebd0>
dimos/core/transport.py:164: in broadcast
    self.lcm.publish(self.topic, msg)
        _          = None
        msg        = <dimos_lcm.vision_msgs.Detection2DArray.Detection2DArray object at 0x7a589777a500>
        self       = <dimos.core.transport.LCMTransport object at 0x7a5867a7ebd0>
.../protocol/pubsub/encoders.py:68: in publish
    encoded_message = self.encode(message, topic)
        __class__  = <class 'dimos.protocol.pubsub.encoders.PubSubEncoderMixin'>
        message    = <dimos_lcm.vision_msgs.Detection2DArray.Detection2DArray object at 0x7a589777a500>
        self       = <dimos.protocol.pubsub.impl.lcmpubsub.LCM object at 0x7a5867a7ec30>
        topic      = Topic(topic='/detections', lcm_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>, message_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>)
.../protocol/pubsub/encoders.py:149: in encode
    return descriptor.codec.encode(msg)
        descriptor = MessageDescriptor(message_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>, encoding='lcm', nam...sgs.Detection2DArray', codec=LCMCodec(message_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>))
        msg        = <dimos_lcm.vision_msgs.Detection2DArray.Detection2DArray object at 0x7a589777a500>
        self       = <dimos.protocol.pubsub.impl.lcmpubsub.LCM object at 0x7a5867a7ec30>
        topic      = Topic(topic='/detections', lcm_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>, message_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = LCMCodec(message_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>)
message = <dimos_lcm.vision_msgs.Detection2DArray.Detection2DArray object at 0x7a589777a500>

    def encode(self, message: T) -> bytes:
        if not isinstance(message, self.message_type):
>           raise TypeError("Message does not match the declared type")
E           TypeError: Message does not match the declared type

message    = <dimos_lcm.vision_msgs.Detection2DArray.Detection2DArray object at 0x7a589777a500>
self       = LCMCodec(message_type=<class 'dimos.msgs.vision_msgs.Detection2DArray.Detection2DArray'>)

.../protocol/pubsub/codec.py:41: TypeError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@TomCC7
TomCC7 added this pull request to stack #4743 October 20, 2026 22:26
Comment thread dimos/core/cdr_transport.py Outdated
@TomCC7
TomCC7 force-pushed the cc/feat/cdr-unit-transports branch from 254cb8b to 2b46518 Compare October 21, 2026 01:05
@TomCC7 TomCC7 changed the title feat(transport): support CDR across Python and native SDK transports feat(transport): share CDR and legacy codecs across existing transports Oct 21, 2026
Comment thread dimos/core/transport.py Outdated
Comment thread dimos/core/transport.py Outdated
Comment thread dimos/core/transport.py Outdated
Comment thread dimos/protocol/pubsub/impl/zenohpubsub.py Outdated
Comment thread docs/development/message-codecs.md Outdated
Comment thread examples/message-transport/demo_codec.py Outdated
@TomCC7
TomCC7 marked this pull request as ready for review October 21, 2026 02:03
Comment thread dimos/core/transport.py Outdated
@greptile-apps

greptile-apps Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] No outstanding findings block merging this PR.

Summary

This PR shares message codecs across LCM, Zenoh, and WebRTC. Generated messages use CDR; legacy messages keep their LCM format.

  • Typed LCM and Zenoh topics now choose CDR or legacy LCM encoding.
  • Typed WebRTC streams now encode generated messages with CDR.
  • ROS and DDS transports now require adapters for generated CDR messages.
  • Message setup docs use working links and current import paths.

Reviews (2) · Last reviewed commit: "fix(transport): preserve native DDS type..." · Reviewed by Greptile

Comment thread dimos/core/transport_factory.py Outdated
Comment thread dimos/core/transport.py Outdated
@TomCC7

TomCC7 commented Oct 21, 2026

Copy link
Copy Markdown
Member Author

@greptile review

@TomCC7
TomCC7 force-pushed the cc/feat/cdr-unit-transports branch from 23a3480 to 42b9f1f Compare October 21, 2026 04:39
@TomCC7
TomCC7 force-pushed the cc/feat/cdr-unit-transports branch from 42b9f1f to deecf9a Compare October 21, 2026 18:43
@TomCC7
TomCC7 removed this pull request from stack #4743 October 22, 2026 18:51
@TomCC7
TomCC7 added this pull request to stack #4776 October 22, 2026 18:52

This branch was successfully deployed

1 active (outdated) deployment
cachix — 42b9f1f5 Deployed Oct 21, 2026 by TomCC7 via cachix-build-macos #13733
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.

1 participant