Skip to main content

Instantiating topology

In order to run a topology you need create an instance that describes what parts of the platform you want to run in your virtual environment. The instance also specifies what tests to run, optional ui and jupyter notebooks etc.

tip

To understand how a topology is instantiated you can use

remotive-topology show topology --resolve <filename>

This shows only the parts of the platform that are instantiated and any defaults that have been applied.

See full topology schema for details. Also make sure to setup your editor to use schema validation, see installation instructions.

Platform subset

Given a platform:

schema: remotive-topology-platform:0.6
channels:
DriverCan0:
type: can
database: ../databases/driver_can.dbc

BodyCan0:
type: can
database: ../databases/body_can.dbc

You need to specify both what platform to use and which ECUs to instantiate:

schema: remotive-topology-instance:0.6

platform:
includes:
- ./topology.platform.yaml

ecus:
BCM:

By default all channels that are connected to the ECU are instantiated. This means the resulting topology is:

Notice how all the other ECUs aren't instantiated!

You can optionally specify a subset of channels. For example this only includes a single channel:

schema: remotive-topology-instance:0.6

platform:
includes:
- ./topology.platform.yaml

ecus:
BCM:
channels:
DriverCan0:

This results in the following topology:

ECU configuration

By default RemotiveTopology instantiates ECUs by using RemotiveBroker as this is the default virtualization in RemotiveTopology. You can using any other virtualization tool as long as it can be containerized, see below.

The RemotiveBroker allows you to communicate as an ECU, for example using the correct IP address on a VLAN or using a CAN device. However, you need to control what behavior the RemotiveBroker should have. RemotiveTopology supports Behavioral models or mocks.

Notice that it's not required to specify a behavior, i.e. you can also control the RemotiveBroker either interactively or from your test case.

Behavioral models

A behavioral model is a way to create a reusable component that emulates the behavior of a real ECU. It can receive and send messages.

To instantiate a behavioral model simply add the model to its ECU. Notice that an ECU can have multiple models, but each model must have a unique name.

ecus:
BCM:
models:
bcm:
type: python
include: ../ecus
main: bcm

When working with the RemotiveTopology framework you refer to namespaces which represents your ECUs view on a channel. Namespaces are named <ECU>-<Channel>. If you are unsure about what namespaces exists you can start the topology instance and run:

remotive broker signals namespaces --url http://localhost:50051

Mock

An ECU Mock is a simpler alternative to a Behavioral Model. A common use case is providing a restbus that emulates an ECU so you can test a device in a realistic bus environment.

By default a mock is created for all channels that the ECU is connected to:

ecus:
FLCM:
mock: {}

You can also specify what channels you want to mock. This is useful when combining mocks and behavioral models for the same ECU:

ecus:
FLCM:
mock:
channels:
DriverCan0:

Container

Normally an ECU is instantiated using RemotiveBroker, but you can also use a custom container. This allows you to run any code as the ECU. For example to use a vsomeip implementation of an ECU:

ecus:
ecu_a:
container:
build:
dockerfile: ../../vsomeip.dockerfile
volumes:
- ../../config:/config_mapped
working_dir: /vsomeip/build/examples
command: "sh -c ./notify-sample"
environment:
- VSOMEIP_CONFIGURATION=/config_mapped/vsomeip-udp-service-ecu-a.json
- VSOMEIP_APPLICATION_NAME=service-sample
- VSOMEIP_LOGLEVEL=debug

Notice that the container starts correctly connected to all ECU channels according to the platform, e.g. for ethernet channel the container has the correct IP address.

Channel configuration

Channels must be configured when connecting to physical hardware or when connecting to software running outside the containerized environment.

CAN

RemotiveTopology supports two ways of instantiating a CAN network:

  1. DockerCAN using SocketCAN (default)
  2. Emulation using UDP (by broadcasting ethernet PDUs)

DockerCAN using SocketCAN is needed to connect to physical hardware and to use standard CAN tooling such as candump. However, as SocketCAN is only supported on Linux. On Mac and Windows you need to fall back to emulation. Notice that the UDP packets are still encoded in the same way as the real CAN frames, by using ethernet PDUs.

DockerCAN

DockerCAN provides SocketCAN access to docker containers. SocketCAN is only available on Linux. You need to install RemotiveLabs DockerCAN. For each channel you must specify what CAN device to use on the host. In this example to map candevice0 to channel DriverCan0 you need to specify:

channels:
DriverCan0:
type: can
driver:
type: dockercan
device_name: candevice0
note

While the device on the host is called candevice0, unfortunately docker appends a 0 to the name, i.e. in this case the device name inside the docker container is candevice00.

By default the channel is configured to connect to a device with the same name as the channel (but in lowercase), i.e. like this:

channels:
MyChannel:
type: can
driver:
type: dockercan
device_name: mychannel
note

Remember that inside the docker container the device name has a 0 appended, i.e. in the default case it's called mychannel0.

If you need a different name inside the docker container than on the host you can specify peer:

channels:
DriverCan0:
type: can
driver:
type: dockercan
device_name: candevice0
peer: in-docker
note

Unfortunately as 0 is still appended, the device inside docker is called in-docker0.

info

Linux has a max length of the name of a device. If your channel name is too long, then you have to assign a shorter device_name.

Recommendations:

  • Avoid names such as can0 or can1
  • Rename physical devices to match your target architecture, e.g. sudo ip link set can0 name drivercan0
  • Inside the container try to use a name similar to the channel. This makes it easier to understand in a virtual context.

Emulation using UDP

Emulation using UDP is available on all platform and doesn't require any additional setup. This works by using UDP multicast and encoding frames as ethernet PDUs, i.e. signals are encoded the same ways when using CAN. Simply change this global setting:

settings:
can:
default_driver: udp

Optionally, you can specify this for each instance channel:

channels:
DriverCan0:
type: can
driver:
type: udp

Ethernet

Ethernet doesn't require any configuration by default.

VLAN

To connect physical networks into the topology you need to configure which device should map into what channel. For example this is mapping eth1 device to the ETH channel:

channels:
ETH:
type: ethernet
driver:
type: macvlan
device_name: eth1

This is using macvlan network driver.

note

If the platform has defined a VLAN this tag is added automatically!

Bridge with iptables

docker network create -d bridge \
--subnet=198.0.0.0/24 \
--gateway=198.0.0.252 \
LowSafety
sudo iptables -I DOCKER 1 -d 198.0.0.22/32 -i gre1 -o br-ccea162a699d -c 0 0 -j ACCEPT
sudo iptables -I DOCKER 1 -s 198.0.0.22/32 -i br-ccea162a699d -o gre1 -j ACCEPT

Gateway

Normally a gateway shouldn't be used as all communication typically happens within each subnet. However, if an ECU needs to route packets outside the subnet a gateway is needed.

Docker automatically provides a gateway for each network that handles routing outside the subnet. Also notice that unless a specific network interface is used, the default is the control network that's automatically added by RemotiveTopology.

RemotiveTopology automatically assigns a free i.p address to the gateway, but you can also specify the gateway like this:

channels:
ETH:
type: ethernet
gateway_ip: 10.1.1.192

In general this isn't needed.

TopologyBroker

Every topology includes a central TopologyBroker which coordinates the other brokers and also allows communication with most channels.

RemotiveTopology automatically assign a free IP address to the TopologyBroker, but you can also specify the an IP address like this:

channels:
ETH:
type: ethernet
topology_broker_ip: 10.1.1.199

In general this isn't needed.

Additional containers

RemotiveTopology also provides a way to run arbitrary containers inside the topology. These containers have access to RemotiveBroker and can therefore interact with ECUs in the topology.

A common use case is to run test cases. By using an arbitrary container you can use whatever test framework you want:

containers:
tester:
profiles: [tester]
build:
dockerfile: ../../../python-runner.dockerfile
volumes:
- ../tests:/app
working_dir: /app
command: "pytest --broker_url=http://topology-broker.com:50051 -s -vv"

Profiles

The containers can have one or more profiles. These correspond to profiles in docker compose, i.e. to run the preceding tests you simply start:

docker compose -f build/mytopology/docker-compose.yaml --profile tester up

When running tests it's useful to shut down the topology after the tests have completed using the flag --abort-on-container-exit:

docker compose -f build/mytopology/docker-compose.yaml --profile tester up --abort-on-container-exit

User interface

RemotiveTopology includes a web app that allows you to interact with the topology and inspect signals. To avoid running this in CI you need to trigger the profile: ui

docker compose -f build/mytopology/docker-compose.yaml --profile ui up

Then open http://localhost:8080 to access the user interface.

Settings

CAN

To emulate CAN using UDP for all CAN channels specify:

settings:
can:
default_driver: udp

This setting is optional, by default DockerCAN is used.

Docker

To instantiate the mocks and behavioral models a container or image configuration is needed. This needs python and RemotiveTopology framework, but you can also add custom dependencies here.

settings:
docker:
mock:
image: remotivelabs/remotivelabs-topology-python:0.9.0
python:
build:
dockerfile: ../python-runner.dockerfile

Specifying mock and python is optional. python since this can be configured as part of the Behavioral model and mock since the generator defaults to a docker image. A version of the generator always uses the same docker image.

RemotiveBroker

RemotiveBroker can either be configured using instance.yaml or environment variables.

settings:
remotivebroker:
version: v1.10.1
license_file: ../../../LICENSE_FILE

Corresponding environment variables:

REMOTIVEBROKER_TAG=v1.10.1
REMOTIVEBROKER_LICENSE=/path/to/LICENSE_FILE

Recommendation:

  • Version: Use instance.yaml to ensure that you have consistent behavior in all environments
  • License: Use REMOTIVEBROKER_LICENSE to avoid having LICENSE_FILE in your repository

TopologyBroker

The TopologyBroker needs to have access to all frames on all channels. To achieve this RemotiveTopology automatically merges all necessary signaldatabases for use by the TopologyBroker. However, it might be useful to explicitly set which signaldatabase, for example if you want to use ECU extracts for all ECUs but you also have a complete signaldatabase for the channel available.

settings:
topology_broker:
channels:
DriverCan0:
database: ./special.dbc

These settings are optional.

User interface

You can configure details about the ui web app. It might be useful to specify a different port number. You can also change the profile, for example if you want to use ui profile for your custom containers.

settings:
ui:
port: 8080
profile: ui

These settings are optional.