This example has two components communicating by publishing to and reading data from the Kuksa Databroker.
Carsim is a basic kinematic model ("bicycle vehicle model"). Ref: VEHICLE DYNAMICS: THE KINEMATIC BICYCLE MODEL.
It takes three external inputs: accelerator/brake position and steering wheel angle and propagates the model system in time with a step defined through variable simulation_step
(default: 0.001 s).
The simulator itself can be found in the carsim.py
file.
carsim_runner.py
is the "bridge" between the kuksa databroker python API and the simulator. It reads the following datapoints from the databroker:
DP_BRAKE_POS = "Vehicle.Chassis.Brake.PedalPosition" # uint8
DP_ACCELR_POS = "Vehicle.Chassis.Accelerator.PedalPosition" # uint8
DP_STEER_ANGLE = "Vehicle.Chassis.SteeringWheel.Angle" # int16
updates the simulator controls with them and steps through the simulator update.
After the new values for the acceleration components, speed and position are calculated, carsim_runner.py
publishes the following datapoints to the databroker:
DP_SPEED = "Vehicle.Speed" # float
DP_ACCEL_LAT = "Vehicle.Acceleration.Lateral" # float
DP_ACCEL_LONG = "Vehicle.Acceleration.Longitudinal" # float
DP_ACCEL_VERT = "Vehicle.Acceleration.Vertical" # float
This runner can serve as an example of how to read/write to the Kuksa Databroker via the kuksa python API. More information on the datapoints, their data types and allowed values can be found in the VSS.
This is an open-loop data feeder. It generates data for accelerator, brake and steering angle without reading back the state of the controlled system.
The simulation step is still a parameter and has to match the simulation step for carsim.
The feeder has roughly two states:
-
"Good driver" - slowly accelerates and moves the steering angle accordingly and then slowly brakes.
-
"Bad driver" - accelerates hard (full throttle), moves the steering wheel randomly in both directions, brakes hard.
After a set amount of time (based on simulation_step) it switches back and forth between the two states.
Roughly the fed data looks like so:
Acceleration/Brake %:
The runner is similar to the carsim_runner but only publishes to the databroker the system controls and steps through the simulation after each update.
Clone the repo and run in 3 separate terminals:
TERMINAL 1 (Databroker):
$ docker run -it --rm --net=host ghcr.io/eclipse/kuksa.val/databroker:master
TERMINAL 2 (Carsim):
$ pip3 install -r carsim/requirements.txt
$ python3 carsim/carsim_runner.py
TERMINAL 3 (Driversim):
$ pip3 install -r driversim/requirements.txt
$ python3 driversim/driver_runner.py
This would be somewhat equivalent to running the scripts directly on the host, but without needing to install the python dependencies (or having python installed on the host).
TERMINAL 1 (Databroker):
$ docker run -it --rm --net=host ghcr.io/eclipse/kuksa.val/databroker:master
TERMINAL 2 (Carsim):
docker run --net=host -e "LOG_LEVEL=INFO" --rm -it ghcr.io/eclipse-leda/leda-example-applications/leda-example-carsim:main
TERMINAL 3 (Driversim):
docker run --net=host -e "LOG_LEVEL=INFO" --rm -it ghcr.io/eclipse-leda/leda-example-applications/leda-example-driversim:main
- Create a custom docker bridge network :
$ docker network create --driver bridge sim-net
In 3 separate terminals:
- Run the kuksa container
$ docker run --name databroker_cont --network sim-net --rm -it ghcr.io/eclipse/kuksa.val/databroker:master
- Run the car simulator
$ docker run --name simulator --network sim-net -e "LOG_LEVEL=INFO" -e "DATABROKER_ADDRESS=databroker_cont:55555" --rm -it ghcr.io/eclipse-leda/leda-example-applications/leda-example-carsim:main
- Run the driver simulator
$ docker run --name driver --network sim-net -e "LOG_LEVEL=INFO" -e "DATABROKER_ADDRESS=databroker_cont:55555" --rm -it ghcr.io/eclipse-leda/leda-example-applications/leda-example-driversim:main
$ carsim/docker-build.sh --local <arch>
$ driversim/docker-build.sh --local <arch>
Note: The docker-build.sh
script can bootstrap an amd64/arm64/armv6 build by substituting the required architecture as an argument. The host architecture has to match or you should use QEMU. Otherwise staticx might fail to statically link the final binary.
Under the manifests directory you can find the Kanto Container Management deployment descriptors for the two containers built in this repository's workflows.
On a Leda device you would have the databroker already deployed and running. That's why a manifest for it is not provided here, but can be found in the meta-leda repository