Is your feature request related to a problem? Please describe.
CARLA currently exposes vehicle I/O only through high-level abstractions: the Python/RPC API (VehicleControl, VehicleAckermannControl, telemetry) and the native ROS2 interface. There is no bus-level vehicle communication. In real vehicles, however, the interface between an autonomy stack and the platform is typically a CAN bus described by a DBC file. This means the vehicle-interface layer of a driving stack — the code that encodes commands into CAN frames and decodes vehicle state from them — cannot be exercised against CARLA at all. Teams must either rewrite that layer for simulation or build and maintain external bridge processes, which adds latency, jitter, and an extra failure point, and breaks the goal of running the same software in simulation (SIL) and on the vehicle. Other UE-based simulators (e.g. SODA.Sim) already provide native virtual CAN buses with pluggable device backends and DBC-driven serialization, which served as inspiration for this proposal.
Describe the solution you'd like
A native, optional CAN interface in the CARLA server, following the same pattern as the existing native ROS2 integration (compile-time option, runtime launch flag, server-embedded):
- CAN sensor — a new
sensor.other.can_bus blueprint attachable to vehicles. Each tick it samples vehicle state (speed, steering, throttle, brake, gear, RPM, lights, doors), encodes it into CAN frames using a user-provided DBC file, and emits the frames through the standard sensor data stream.
- Virtual CAN bus + SocketCAN transport — an in-process virtual bus per vehicle, bridged to a Linux SocketCAN interface (e.g.
vcan0) when the server is launched with a --can flag. External tools then connect exactly as they would to a real vehicle: candump, cansend, python-can, cantools, ROS2 CAN drivers — no CARLA-specific client code.
- Control path — incoming command frames on the bus are decoded via the DBC and mapped to
VehicleControl/VehicleAckermannControl, applied tick-synchronously (deterministic in synchronous mode), with documented arbitration semantics versus RPC control.
- Declarative configuration — a DBC file plus a small YAML mapping (message/signal ↔ vehicle state/control field, direction, rate).
Implementation would use a transport strategy interface (ICanTransport) so additional backends (CAN-over-Ethernet, hardware adapters for HIL) can be added later without touching the core, and an embedded MIT-licensed C++ DBC library (e.g. dbcppp) for encode/decode. Everything is gated behind -DENABLE_CAN=OFF by default, so default builds and existing behavior are unchanged.
The work splits naturally into independently mergeable phases, each within the contribution size limits:
- Phase 1 (LibCarla): frame types, DBC layer, sensor data type + serializer, unit tests.
- Phase 2 (UE plugin):
CANBusSensor actor + blueprint registration + Python exposure.
- Phase 3 (Transport): SocketCAN/vcan backend +
--can launch wiring + docs.
- Phase 4 (Control): frame→control decode path, YAML mapping, closed-loop example.
Phases 1–2 are already useful standalone (CAN telemetry sensor) even if the transport phases are deferred.
Describe alternatives you've considered
- External bridge process (status quo): a separate client that reads CARLA state over the Python API/ROS2 and republishes it on a vcan interface. It works, but adds a serialization hop and an IPC boundary (extra latency and jitter in closed-loop control), requires per-project maintenance, and cannot be tick-synchronous with the simulation. A working bridge of this kind can serve as the latency baseline that a native implementation should beat.
- CAN-frame topics over the native ROS2 interface: publishing raw frames as ROS2 messages. This still requires a ROS2-specific consumer and does not present a real CAN interface to the OS, so standard CAN tooling and unmodified vehicle-interface code cannot connect.
- Sensor-only implementation (no transport): shipping only the
sensor.other.can_bus telemetry sensor. Lower risk and proposed here as Phases 1–2, but on its own it does not enable closed-loop testing of vehicle-interface code; the transport and control phases are what close the gap.
Additional context
- The native ROS2 layer (
LibCarla/source/carla/ros2, --ros2 flag, optional compile flag) is the architectural precedent: an optional, server-embedded transport with publishers and subscribers. This proposal follows the same structure for CAN.
- A virtual SocketCAN interface requires no hardware (
modprobe vcan && ip link add dev vcan0 type vcan), making it suitable for CI and headless setups.
- The frame structure would be sized for CAN FD (up to 64 data bytes) from the start, even if v1 targets classical CAN, so FD support is a later additive change.
- If there is interest, I can follow up with a full design document covering the file-level change map, the arbitration semantics for concurrent RPC/CAN control, and latency benchmarks comparing the external-bridge approach against the native path.
Happy to discuss scope and implementation details, I'd like to align with maintainers before opening any PRs.
Is your feature request related to a problem? Please describe.
CARLA currently exposes vehicle I/O only through high-level abstractions: the Python/RPC API (
VehicleControl,VehicleAckermannControl, telemetry) and the native ROS2 interface. There is no bus-level vehicle communication. In real vehicles, however, the interface between an autonomy stack and the platform is typically a CAN bus described by a DBC file. This means the vehicle-interface layer of a driving stack — the code that encodes commands into CAN frames and decodes vehicle state from them — cannot be exercised against CARLA at all. Teams must either rewrite that layer for simulation or build and maintain external bridge processes, which adds latency, jitter, and an extra failure point, and breaks the goal of running the same software in simulation (SIL) and on the vehicle. Other UE-based simulators (e.g. SODA.Sim) already provide native virtual CAN buses with pluggable device backends and DBC-driven serialization, which served as inspiration for this proposal.Describe the solution you'd like
A native, optional CAN interface in the CARLA server, following the same pattern as the existing native ROS2 integration (compile-time option, runtime launch flag, server-embedded):
sensor.other.can_busblueprint attachable to vehicles. Each tick it samples vehicle state (speed, steering, throttle, brake, gear, RPM, lights, doors), encodes it into CAN frames using a user-provided DBC file, and emits the frames through the standard sensor data stream.vcan0) when the server is launched with a--canflag. External tools then connect exactly as they would to a real vehicle:candump,cansend,python-can,cantools, ROS2 CAN drivers — no CARLA-specific client code.VehicleControl/VehicleAckermannControl, applied tick-synchronously (deterministic in synchronous mode), with documented arbitration semantics versus RPC control.Implementation would use a transport strategy interface (
ICanTransport) so additional backends (CAN-over-Ethernet, hardware adapters for HIL) can be added later without touching the core, and an embedded MIT-licensed C++ DBC library (e.g. dbcppp) for encode/decode. Everything is gated behind-DENABLE_CAN=OFFby default, so default builds and existing behavior are unchanged.The work splits naturally into independently mergeable phases, each within the contribution size limits:
CANBusSensoractor + blueprint registration + Python exposure.--canlaunch wiring + docs.Phases 1–2 are already useful standalone (CAN telemetry sensor) even if the transport phases are deferred.
Describe alternatives you've considered
sensor.other.can_bustelemetry sensor. Lower risk and proposed here as Phases 1–2, but on its own it does not enable closed-loop testing of vehicle-interface code; the transport and control phases are what close the gap.Additional context
LibCarla/source/carla/ros2,--ros2flag, optional compile flag) is the architectural precedent: an optional, server-embedded transport with publishers and subscribers. This proposal follows the same structure for CAN.modprobe vcan && ip link add dev vcan0 type vcan), making it suitable for CI and headless setups.Happy to discuss scope and implementation details, I'd like to align with maintainers before opening any PRs.