Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VirtualCAN-ROS2-Interface

  • ROS2 interface for virtual CAN (vcan0), for developing and testing CAN logic without vehicle hardware
  • Type a signal name and a value in the terminal, and it is encoded into a CAN frame from the .dbc definition
  • The received frame is decoded back into physical values and published as one topic per signal, so the round trip is visible end to end
terminal input          vcan0                     ROS2 topic
Vehicle_speed 80  ──►  711 [8] 00 50 00 ...  ──►  /can/Vehicle_speed  { value: 80.0, unit: kph }

Environment

  • Ubuntu 22.04
  • ROS2 Humble
  • CAN : SocketCAN virtual interface (vcan0)

Package

Package Description
can_interface Bus (raw SocketCAN socket), DbcLoader (.dbc parser), DBC (signal encode/decode)
can_msgs Frame.msg (raw frame), Signal.msg (one decoded signal), ParsedMessage.msg (one message)
socketcan_interface Receives frames from vcan0, publishes raw frames and decoded signals
virtual_can Encodes values typed in the terminal and writes them to vcan0

Virtual CAN Setup

sudo modprobe vcan                                 # Load the vcan kernel module
sudo ip link add dev vcan0 type vcan               # Create the interface
sudo ip link set up vcan0                          # Bring it up
  • The setting is lost on reboot, so it must be re-applied
ip link show vcan0                                 # Check the interface
candump vcan0                                      # Check reception

DBC Pull

DBC files live in a separate private repository (IVSP-DBC), registered as a submodule at dbc/.

git clone --recursive git@github.com:dev-muuu/VirtualCAN-ROS2-Interface.git

git submodule update --init --recursive       # If dbc/ is empty
git submodule update --remote dbc             # Pull the latest DBC
  • Access to the private repository is required — without it the clone succeeds but dbc/ stays empty

Signal Database

DbcLoader parses BO_ (message) and SG_ (signal) lines of a .dbc file directly. Bit layout follows the DBC convention.

Byte order start_bit Extraction
Little endian (@1) LSB position Shift the 8-byte little-endian value
Big endian (@0) MSB position Collect bits in Motorola order

Resolution order for the DBC path:

Priority Source Example
1 Command line argument ros2 run virtual_can virtual_can_sender dbc/Sportage_CAN_ver01.dbc
2 CAN_DBC_PATH environment variable export CAN_DBC_PATH=$PWD/dbc/Sportage_CAN_ver01.dbc
3 Default dbc/Sportage_CAN_ver01.dbc (relative to the working directory)

Frame Generation

Inject arbitrary values into the bus without vehicle hardware, to verify the receive → parse → log path end to end.

  • Values are given in physical units (km/h, deg) — bit packing (start bit, length, byte order, sign, factor/offset) is resolved from the signal database
  • Symmetric with extract_signal, so encode → send → receive → decode can be verified in a single loop
  • Reproduces specific conditions (e.g. speed 80 km/h) on demand, which is hard to trigger in an actual vehicle
Method Input Output
create_frame_by_signal_name One signal name and value One frame, message ID resolved automatically
create_frame Message ID and multiple signal values One frame
create_frames_by_signal_names Multiple signal values across messages Multiple frames, grouped by message ID
#include "can_interface/dbc.h"

can_interface::DBC dbc("dbc/Sportage_CAN_ver01.dbc");

// 1. One signal — message ID is resolved from the signal name
auto frame = dbc.create_frame_by_signal_name("EPS_command", 90.0);
if (frame) bus.send(*frame);

// 2. Multiple signals within one message
auto frame = dbc.create_frame(343, {
    {"EPS_command", 90.0},
    {"SCC_command",  1.5},
});

// 3. Multiple signals across messages — grouped by message ID automatically
auto frames = dbc.create_frames_by_signal_names({
    {"EPS_command",  90.0},
    {"Alive_count",   7.0},
});
for (const auto& f : frames) bus.send(f);
  • Signal names must match the SG_ names in the DBC exactly — check with print_signal_map()
  • create_frame returns std::nullopt if the message ID is unknown, or if a signal does not belong to that message
  • create_frames_by_signal_names silently skips unknown signal names, so verify the returned count

For values entered at runtime, use the sender directly — see Interactive Command. Define a generator in can_frame_generator.h only for fixed patterns that are repeated often.

namespace can_frame_generator
{
    can_frame generate_velocity()
    {
        can_interface::DBC dbc;
        auto frame_opt = dbc.create_frame_by_signal_name("EPS_command", 90.0);
        return frame_opt ? *frame_opt : can_frame{};
    }
}

Build

colcon build --symlink-install
source install/setup.bash

Execute Command

Run from the workspace root — both executables resolve the DBC through a relative path.

  1. ROS2 Interface — reads vcan0, publishes raw frames and decoded signals
source install/setup.bash
ros2 run socketcan_interface socketcan_interface
  1. Frame Sender — encodes the values typed in the terminal
source install/setup.bash
ros2 run virtual_can virtual_can_sender
  1. Monitor — see Monitoring
ros2 topic echo /can/Vehicle_speed

Parameters of the ROS2 interface:

Parameter Default Description
interface vcan0 SocketCAN interface name — set to can0 for a real bus
dbc_path (empty) Falls back to CAN_DBC_PATH, then dbc/Sportage_CAN_ver01.dbc
parsed_prefix /can Namespace of the decoded topics
publish_grouped false Also publish one topic per message, carrying all of its signals
ros2 run socketcan_interface socketcan_interface --ros-args \
  -p interface:=vcan0 \
  -p dbc_path:=$PWD/dbc/Sportage_CAN_ver01.dbc \
  -p publish_grouped:=true

Interactive Command

Type a signal name and a value in the sender terminal, and the frame is encoded and sent at that moment. No rebuild is needed to change a value.

Command Description
<signal> <value> [...] Send once — the default
hold <signal> <value> [...] Repeat at 10 Hz until changed, like a real bus
show Print the values currently being repeated
clear Stop repeating
list Print every message and signal defined in the DBC
test Send the fixed test frame (0x123) once
quit Exit
EPS_command 90                                     # One frame, right now
EPS_command 90 SCC_command 1.5                     # Two signals of one message -> one frame
Alive_count 7                                      # Different message -> separate frame
hold EPS_command 90                                # Start repeating at 10 Hz
hold EPS_command 120                               # Change the value while repeating
clear                                              # Stop repeating
  • Signals are grouped by message ID automatically, so signals from different messages can be given on one line
  • A signal name that is not in the DBC is rejected before sending, with the name printed
  • Nothing is sent until an input arrives — hold is the only command that keeps sending

Topic

Topic Type Description
/frame_can0 can_msgs/Frame Raw CAN frame, every ID including those absent from the DBC
/can/<signal> can_msgs/Signal One topic per signal — header, name, value, unit
/can/<message>/<signal> can_msgs/Signal Used only when the same signal name appears in more than one message
/can/<message> can_msgs/ParsedMessage All signals of one message at once — only with publish_grouped:=true
  • Every topic in the DBC is created at startup, so ros2 topic echo resolves the type before the first frame arrives
  • value is a single scalar, so it can be plotted directly in rqt_plot or Foxglove

Monitoring

ros2 topic list | grep ^/can                       # Every decoded signal
ros2 topic echo /can/Vehicle_speed                  # One signal
ros2 topic echo /frame_can0                         # Raw frame
candump vcan0                                       # Check at the SocketCAN layer
  • Start echo before typing into the sender — a single-shot send is gone by the time it starts
  • Use hold to keep a value on the bus while inspecting it

About

ROS2-CAN interface using Virtual CAN

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages