At a glance (1 minute)
Imagine an ongoing simulation test cycle of an SDV ( Shift-Left ). The cluster looks fine — beams on, no tell-tale — yet the front-lamp computer has failed, or gone mute. The cabin's HMI never says so.
But, a Digital Twin tells the observer, what is not right. It is the trustworthy source of the whole car's state: what the ECUs said on the bus, even when that disagrees with the cluster.
This integration addresses that case.
I attach the Digital Twin I have already built to RemotiveLabs'
Hello World; it stands for a starter virtual vehicle: ECU models on a bus, a notebook to drive them, and a 3D cluster to look at. remotive_bridge taps RemotiveBroker — hazard, turns, lamp status — and maps them onto the Twin. The Gateway still owns the Twin; a Dashboard only watches. Hello World stays the vehicle. The Twin stays the observer.
RemotiveLabs offers a vehicle-simulation platform for automotive software teams: describe the topology as code, mix virtual and physical ECUs, and run the same setup from SIL toward HIL. Hello World is their smallest live car.
Potential: The aim is not “Can we rebuild Remotive in Rust?” The aim is: can the Twin I have already built — an Actor system in Rust — attach to a live vehicle topology, watch what the ECUs actually say, and warn an observer when something is amiss?
📌 More than an HMI mirror.
In Software-Defined Vehicles, a digital twin that only copies the driver display is a mirror, not a twin. The value lies in catching faults the cabin will not show.
That makes this work a candidate SIL (software-in-the-loop) observation component today: the twin, the Remotive bus, and the ECU models already form a virtual testbed which we can drive from Remotive's notebook, watch from the Twin, and replay from disk.
Jupyter / 3D cute car (driver display)
│
v
RemotiveBroker (vehicle bus / signal hub)
│
├──► Remotive ECUs (body and lamp computers)
└──► remotive_bridge ── observed signals + session start/stop
│
v
┌─ Gateway (gateway-ECU role) ──────────┐
│ Digital Twin = the car in software │──── live watch ───> [ Dashboard ]
│ Actor Brain + ECU children (Rust) │
│ │ │
└────────────────────┼──────────────────┘
v
[ Disk: replayable observations ]
The Architecture At a glance
The Digital Twin (link) owns its own CAN world: an emulator drives the session, Gateway holds the twin, and a separate TUI only watches (i.e., works as the dashboard).
This prototypes attaches that same twin to a live Remotive Hello World vehicle — Jupyter, ECU models, and the 3D “cute car” — without moving into Remotive’s containers or rewriting how the webpage paints.
Remotive already has a signal hub (RemotiveBroker). What I add is a small Twin-side process,
remotive_bridge, that sits beside that hub:
Operator / Jupyter / 3D cute car
│
▼
RemotiveBroker (already in Remotive topology)
│
├──► Remotive ECUs (BCM, FLCM, …)
└──► remotive_bridge ──┬── observed ECU signals
│ (hazard, turns, lamp status)
└── Twin session frames
(PowerOn / RPM / PowerOff)
│
▼
Gateway Twin ──► TUI Dashboard
│
▼
Disk: versioned observations
📌 Remotive stays the authoritative vehicle model. The Twin stays the authoritative observer of selected signals and faults. They meet at the broker; they do not swallow each other.
Motivation
-
A Digital Twin that only mirrors the HMI is a mirror, not a twin .
-
The Remotive
Hello Worlddemo is a joy to use: a notebook, a cute car in the browser, lamps that come on when you ask. What it does not do, out of the box, is notice when the front-lamp ECU is lying — or has gone quiet. Command paths can look healthy while a lamp ECU is dead. That gap is where observation earns its keep.
So the question for this exercise has not been “Can we rebuild Remotive in Rust?” It has been: can the Twin I've already built, attach to a live vehicle topology, watch what the ECUs actually say, and warn — without teaching the 3D car to go dark?
The answer has turned out to be a delighted 'Yes'. And the value of the integration is clearly visible: I fail the lamp ECU (or mute it), the webpage stays sunny, and the Twin is already shouting.
Quick snap
📂 Where this sits in the journey
This post builds on the capstone. If you are interested in the Twin’s origin story — actors, Gateway/Dashboard split, observation as a facility — start here:
- The Twin itself: Digital Twin: Designing an Actor-Based SDV Prototype in Rust (Milestone 1)
- Runnable Twin without Remotive:
sdv_simulation_5
This integration effort:
- This repo:
sdv_simulation_remotive— the README is the technical home (what it proves, how the pieces fit, how to run) - Remotive examples:
remotivelabs-topology-examples,
The approach: attach, don't absorb
Hello World is not one process. Jupyter, ECU models, and the 3D car already meet at RemotiveBroker — named signals over gRPC. That hub already exists; I've just used it.
remotive_bridge has a dual role, and both roles matter:
-
Translate Remotive → Twin. Subscribe to a handful of signals — hazard, turn requests, front low-beam status — and map them onto the Twin’s own CAN vocabulary. Remotive keeps speaking Remotive; the Twin keeps speaking Twin's vocabulary.
-
Start the Twin’s brain in the right order. The Twin’s actor tree is lifecycle-sensitive: a brain FSM coordinates child actors and expects PowerOn --> motion -> PowerOff. Remotive does not emit those Twin-specific frames, so the bridge also generates them. Without that, observations never accumulate into the global view the dashboard shows.
The Gateway never sees “broker messages.” It sees two kinds of Twin CAN input from the same interface: observed ECU traffic, and the session frames that used to come from the capstone emulator (kind of backward compatibility in the codebase).
📌 We treat the broker as the shared signal bus Remotive already provides. The Twin attaches beside the vehicle model. It does not replace Remotive’s ECUs, and it does not reach into their containers.
Why that arrangement is the value proposition
There are two paths for the same light stalk:
- Command path. Jupyter → BCM requests → cute car paints low beams ON. This path is unchanged on purpose.
- Status path. FLCM publishes low-beam status Ok | Fail | Silent (this is a change brought in by me; original Remotive sample, doesn't have this). BCM and the webpage do not consume that status. The Twin does — and Warning on its TUI, is that summary speaking.
The Twin holds a global, summated state of the vehicle from what ECUs say on the bus, not from what the 3D manifestation paints. I haven't taught the cute car to go dark. I've taught the Twin to notice.
A small delight along the way: Remotive’s hazard button on the bus is often a momentary pulse. Drivers expect “hazards are on” until they press again. The Twin latches that into a lasting hazard mode, so the TUI matches the expectation while the 3D car still blinks from BCM.
The punchline (you can run this)
Use only Light stalk, FLCM Ok | Fail | Silent, Hazard !, and optionally the Turn stalk. Leave Low Beam on after the first step.
| Step | What you do | Cute car | Twin TUI |
|---|---|---|---|
| 1 | Light stalk → Low Beam | Front beams ON | Low Beam OK / OK; Hazard OFF |
| 2 | FLCM Fail | Beams still ON | Warning; Low Beam FAIL / FAIL |
| 3 | FLCM Ok | Still ON | Warning clears |
| 4 | FLCM Silent | Still ON | Within ~500 ms: Warning (silent); status goes stale |
| 5 | FLCM Ok | Still ON | Healthy again |
| 6 (optional) | Turn stalk → Left, then Off | Left blinker | Front Light ON then OFF (turns, not headlamps) |
| 7 | Hazard ! once | Hazards blink | Hazard: ON and it stays ON |
Steps 2 and 4 are the money shots. The paint can look fine. The bus, watched carefully, is harder to fool.
How to actually spin the topology, Gateway, TUI, and bridge: see the README and the design runbook linked from there. This post is the why; those pages are the how.
What I've not implemented (on purpose)
Scope honesty is part of the story:
- The Twin does not publish commands back into RemotiveBroker.
- BCM, GWM, and the cute car are not taught to consume FLCM status.
- The legacy emulator and headlamp/wiper actuator binaries are not required for this demo.
- Richer ECU stories — rear-lamp reply checks, brake timeouts, Twin-driven stimulus — are deferred.
The integration is valuable because of that boundary. Observation that rewrites the vehicle model is just a second simulator.
What this opens up
Once a Twin can attach to a real (or realistically modelled) vehicle bus and disagree with the HMI, a number of doors swing open:
- Honest consumers next. Teach a Remotive ECU to react to FLCM Fail, and the cute car can go dark because the vehicle learned it — a different thesis, and a natural sequel.
- More of the bus. The five-signal slice is a beachhead. Hazard, turns, and lamp status were enough to prove the seam. The same bridge pattern extends.
- Replay and CI. The Twin already writes a durable observation trail. Broker traces plus those files are how you stop needing a full 3D topology to regression-test “did we notice the silent lamp?”
- Eclipse SDV neighbourhood. The Twin already speaks CAN for the vehicle side and UDS or Zenoh for live observation. Middleware such as uProtocol is still on the horizon from the capstone — this project hasn't waited for it.
Until the 3D car is mapped onto FLCM status, the contrast is the product: bright car, honest Warning. But, this is Remotive's code and I am not an expert in python or javascript.
The paint can lie. A twin that watches the bus is how one catches that — live, next to a vehicle model I don't own.