Fan-io#2364
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR introduces a fan-I/O platform layer for
Confidence Score: 5/5Safe to merge; the fan-I/O platform and both module migrations are correctly implemented with no functional regressions found. The two-pointer alignment loop, Bundle scatter, normalize_to_bundle bridge, and ingest() seam all behave correctly. The _fuse field-name access in Detection3DModule aligns with stream names derived from In port names. The _nearest_secondary and _interpolated_secondary helpers preserve the old tolerance boundary and tie-breaking. The MarkerTfModule port rename is updated in every consumer and integration test. moduleDB.py is fully removed with no dangling references. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant In_primary as In[primary]
participant In_secondary as In[secondary]
participant NullStore as NullStore
participant ingest as ingest() seam
participant pipeline as pipeline()
participant align as Stream.align()
participant normalize as normalize_to_bundle()
participant scatter as scatter_to_ports()
participant Out_A as Out[port_A]
participant Out_B as Out[port_B]
Note over In_primary,In_secondary: StreamModule.start()
In_primary->>ingest: msg arrives
ingest->>NullStore: "stream.append(msg, ts=...)"
In_secondary->>ingest: msg arrives
ingest->>NullStore: "stream.append(msg, ts=...)"
NullStore->>pipeline: primary.live() stream
pipeline->>align: "primary.transform(...).align(self.streams.secondary, tolerance=T)"
align-->>pipeline: Stream[AlignedPair]
pipeline-->>normalize: Stream[Bundle] (or raw T for 1:1)
normalize-->>scatter: Stream[Bundle] (always bundle-keyed)
scatter->>Out_A: bundle[port_A] publish
scatter->>Out_B: bundle[port_B] publish
Reviews (5): Last reviewed commit: "rename duplicate test class" | Re-trigger Greptile |
| pointcloud_topic.publish(detection.pointcloud) | ||
|
|
||
|
|
||
| def deploy( # type: ignore[no-untyped-def] |
|
@paul-nechifor , when I mark the conversation resolved, it means I am resolving/resolved them in the same very moment I mark them. Once stable, a commit(s) with fixes will land on top. |
Fan-io
Problem
StreamModuleonly supports 1 input and 1 output.Solution
Inregulates all emission times. The pipeline must construct a Bundle which is used to publish messages to multiple outputs.Proof the platform works
memory2/test_module.pyfusion tests (literal N:M)MarkerModulemigration (clearest before/after)Detection3DModulemigration (Rx -> pipeline, compute-once multi-out)Out of scope
module-as-transform in arbitrary outer chains (will be new mem2-native-modules PR).
What this branch is (the core deliverable)
StreamModulememory2/module.pyingest()seam;self.streams.<port>; no 1:1 gatememory2/fanio.pyBundle,scatter_to_ports,normalize_to_bundlememory2/stream.pyStream.align, optionalinterpolator=memory2/interpolators.pylerp_pose,interp_odommemory2/test_module.pyTwoInputFusion,ChainedFusion, multi-out compute-once, interpolationWhy the design
Before fan-I/O:
After fan-I/O:
Summary
Fan-I/O is the wrapper layer: mem2 fusion inside deployed StreamModules. That works today - and an important step toward modules that are just mem2 transforms: the same pipeline() you deploy on a robot should run in any mem2 chain, on a recorded SqliteStore, faster than realtime.
What survives from fan-I/O into that follow-up will be the core - every input as a mem2 stream, .align() / interpolator=, Bundle scatter, ingest() - but not the legacy port/transport wrapper around it.