Skip to content

Repository files navigation

EdgeEmbed Reference Fleet Manager

This repository is a ROS2 ament_python package that demonstrates a VDA 5050-style fleet control architecture for mixed-brand AGVs.

The repo's current role in the EdgeEmbed stack is a lightweight demo/reference fleet manager. It is the fleet-side target that EdgeEmbed Runtime can drive during demos and integration tests.

The demo has three goals:

  • show how multiple AGV brands can communicate with one fleet controller through VDA 5050-style MQTT topics and messages
  • provide a simple 2D dashboard for sales demos, operations reviews, and architecture discussions
  • provide a concrete fleet-manager target for the Runtime -> scenario -> fleet manager integration story

This is a demo integration, not a certified full VDA 5050 implementation.

Runtime Positioning

This repo is not the EdgeEmbed Runtime itself. It is the open fleet demo that the Runtime can govern.

Recommended full story:

VQA / sensors / MES / scenario input
        |
        v
EdgeEmbed Runtime
        |
        | approved business task
        v
fleet/task
        |
        v
this demo fleet manager
        |
        v
VDA 5050-style order over MQTT
        |
        v
vehicle_adapter / robot backend / simulator
        |
        v
state, connection, factsheet feedback
        |
        v
dashboard, scenario assertions, future journal/replay

In this model:

  • VQA and other upstream systems produce structured operational events.
  • EdgeEmbed Runtime applies policy, confidence thresholds, interlocks, and trace logging before any task reaches the fleet manager.
  • This repo accepts approved task requests on fleet/task, performs the demo fleet workflow, and publishes VDA 5050-style robot messages.
  • The E2E scenario runner injects demo events and asserts behavior by observing Runtime decisions, fleet-manager output, adapter state, and dashboard telemetry.

The current repository now implements the fleet-manager target, a minimal Runtime gateway, and an E2E scenario runner for the first end-to-end proof. Structured journal, replay, and real EdgeEmbed-HIL hardware validation remain future integration points.

Architecture

Current standalone flow:

custom fleet/task request
        |
        v
master_control
        |
        v
VDA 5050-style order over MQTT
        |
        v
vehicle_adapter per AGV
        |
        v
Nav2 or simulated adapter motion
        |
        v
VDA 5050-style state, connection, factsheet over MQTT
        |
        v
dashboard WebSocket and 2D canvas

The VDA 5050-style MQTT topic shape is:

uagv/v2/{manufacturer}/{serial}/{message_type}

Examples:

uagv/v2/EdgeEmbed/AGV001/order
uagv/v2/BrandB/AGV002/state
uagv/v2/BrandC/FL-77/factsheet

The custom fleet/task topic is not VDA 5050. It is the high-level business task API for the demo. master_control converts those task requests into VDA 5050-style order messages.

When connected to EdgeEmbed Runtime, fleet/task should be treated as a governed downstream interface. VQA, MES, sensor, or scenario events should enter the Runtime first. Only approved Runtime outputs should be published to fleet/task.

Planned upstream topics:

edgeembed/inference       VQA or AI inference events into Runtime
edgeembed/scenario        optional scenario control
edgeembed/runtime/event   Runtime decision and trace telemetry
fleet/task                approved task request into this fleet demo

ROS2 Nodes

This folder is one ROS2 package, not one node. It exposes these executable nodes:

master_control
runtime_gateway
scenario_runner
vehicle_adapter
dashboard

They are registered in setup.py as console scripts.

master_control

  • subscribes to all AGV state, connection, and factsheet messages
  • accepts approved fleet/task requests
  • selects vehicles by online status, idle state, battery, payload, and distance
  • locks exclusive traffic zones such as corridor_1
  • publishes VDA 5050-style order messages
  • publishes dashboard KPI and zone state

runtime_gateway

  • subscribes to edgeembed/inference
  • calls /home/edgeembed/edgeembed-sdk/runtime/libedgeembed.so
  • loads the demo Runtime bundle from runtime_bundles/fleet_demo
  • publishes Runtime verdicts to edgeembed/runtime/event
  • publishes approved transport tasks to fleet/task
  • blocks events when the Runtime dispatches the reject action

scenario_runner

  • can run a self-contained Runtime -> fleet manager scenario path
  • publishes configured scenarios from config/e2e_scenarios.yaml
  • observes Runtime verdicts, fleet/task, and VDA 5050-style orders
  • fails if blocked inputs produce downstream tasks or orders

vehicle_adapter

  • represents one AGV
  • subscribes to VDA 5050-style order and instantActions
  • publishes state, connection, and factsheet
  • translates order nodes into Nav2 goals when Nav2 is available
  • can run in simulated adapter mode for dynamically added demo vehicles

dashboard

  • serves web/index.html over HTTP
  • opens a WebSocket feed on port 8765
  • listens to MQTT vehicle and master-control telemetry
  • pushes site, vehicle, zone, and KPI snapshots to the browser

Folder Structure

edgeembed_vda5050/
├── edgeembed_vda5050/        Python node source code
├── config/                   Fleet and site topology configuration
├── launch/                   ROS2 launch files
├── maps/                     Nav2 map server files
├── runtime_bundles/           EdgeEmbed Runtime demo bundle JSON
├── web/                      Browser dashboard
├── tools/                    One-key demo scripts
├── resource/                 ROS2 ament package marker
├── package.xml               ROS2 package metadata and dependencies
├── setup.py                  Python package install and entry points
├── setup.cfg                 ROS2 script install paths
└── DEMO_INSTRUCTIONS.md      Detailed sales-demo runbook

Generated by colcon build:

build/     temporary build output
install/   installed runnable package
log/       build logs

Do not edit generated folders directly.

Requirements

Tested with ROS2 Humble.

Required local components:

  • ROS2 Humble
  • Nav2 packages, including nav2_bringup and nav2_simple_commander
  • MQTT broker such as Mosquitto
  • Python packages installed by ROS or apt:
    • paho-mqtt
    • websockets
    • yaml

Install common dependencies on Ubuntu with ROS Humble:

sudo apt install \
  ros-humble-navigation2 \
  ros-humble-nav2-bringup \
  mosquitto \
  mosquitto-clients \
  python3-paho-mqtt \
  python3-websockets \
  python3-yaml

Build

From this package root:

source /opt/ros/humble/setup.bash
colcon build --packages-select edgeembed_vda5050
source install/setup.bash

The Runtime E2E path expects the EdgeEmbed SDK checkout at /home/edgeembed/edgeembed-sdk. The SDK evaluation runtime in this environment requires ThreadSanitizer to be preloaded before Python starts:

export LD_PRELOAD=/lib/x86_64-linux-gnu/libtsan.so.0

Check ROS can see the package:

ros2 pkg executables edgeembed_vda5050

Expected:

edgeembed_vda5050 dashboard
edgeembed_vda5050 master_control
edgeembed_vda5050 runtime_gateway
edgeembed_vda5050 scenario_runner
edgeembed_vda5050 vehicle_adapter

After sourcing the absolute install path, you can run ROS commands from any directory:

source /home/edgeembed/edgeembed_vda5050/install/setup.bash
ros2 run edgeembed_vda5050 dashboard

Basic Run

Terminal 1, start MQTT:

mosquitto -v

Terminal 2, launch the demo:

source /opt/ros/humble/setup.bash
source /home/edgeembed/edgeembed_vda5050/install/setup.bash
ROS_LOG_DIR=/tmp/ros_log ros2 launch edgeembed_vda5050 demo.launch.py

Open the dashboard:

http://localhost:8080

The WebSocket endpoint is:

ws://localhost:8765

If you edit Python, launch, config, map, or web files, rebuild:

colcon build --packages-select edgeembed_vda5050
source install/setup.bash

Then restart the relevant node or launch file.

Expected Demo Behavior

On launch, you should see:

  • master_control start
  • dashboard start
  • one Nav2 bringup group per configured vehicle
  • one vehicle_adapter per configured vehicle

Configured vehicles are in config/fleet.yaml:

AGV001  EdgeEmbed
AGV002  BrandB
FL-77   BrandC

The ROS namespace for FL-77 is sanitized to FL_77, but the MQTT and VDA serial remains FL-77.

If Nav2 logs this:

Timed out waiting for transform from base_link to odom

it means no simulator or robot driver is publishing TF and odometry yet. The dashboard demos still work because the tools/demo_*.sh scripts publish deterministic MQTT telemetry.

Four One-Key Demos

Start MQTT, launch the system, and open http://localhost:8080 first.

Demo 1: Narrow Corridor Meet

tools/demo_1_corridor.sh

What it demonstrates:

  • two tasks route through corridor_1
  • one AGV enters first
  • the corridor turns red
  • the other AGV waits near N01
  • after release, the waiting AGV proceeds

The business task trigger is:

mosquitto_pub -h localhost -t "fleet/task" -m '{"from":"L11","to":"S01","weight":50}'
mosquitto_pub -h localhost -t "fleet/task" -m '{"from":"L31","to":"S02","weight":50}'

Demo 2: Vehicle Lost And Reassignment

tools/demo_2_vehicle_lost.sh

What it demonstrates:

  • AGV002 is marked disconnected
  • the task and traffic lock are recovered
  • the task label moves to another vehicle
  • the dashboard keeps running

The script attempts:

pkill -f "vehicle_adapter.*AGV002"

and publishes a CONNECTIONBROKEN message so the visual is deterministic.

Demo 3: Add A Fourth Brand Live

tools/demo_3_new_brand.sh

Equivalent command:

ros2 run edgeembed_vda5050 vehicle_adapter \
  --ros-args -p serial:=NEW-99 -p manufacturer:=BrandD -p type:=carrier

What it demonstrates:

  • a new brand appears without restarting master or dashboard
  • the vehicle publishes a VDA 5050-style factsheet
  • the dashboard shows a new vehicle color
  • the system remains brand independent

Demo 4: Add Vehicles, Show Bottleneck

tools/demo_4_capacity_kpi.sh

What it demonstrates:

  • first state: 6 vehicles, 142 boxes/hour, 71 percent utilization
  • second state: 8 vehicles, 159 boxes/hour
  • throughput rises only about 12 percent because corridor_1 is the bottleneck

This shifts the sales discussion from number of robots to correct system capacity.

See DEMO_INSTRUCTIONS.md for talk tracks and reset commands.

Runtime End-to-End Scenario Demo

The integration is additive. The current fleet demo still works by publishing directly to fleet/task, and the Runtime front door now produces the same task message only after policy approval.

Browser-Driven Demo

This is the preferred sales-demo path. Start MQTT, launch the web stack, then run onboarding and Runtime scenarios from the browser.

Terminal 1:

mosquitto -v

Terminal 2:

source /opt/ros/humble/setup.bash
source install/setup.bash
ros2 launch edgeembed_vda5050 web_demo.launch.py

Open:

http://localhost:8080

If you run the dashboard on a non-default WebSocket port, pass it in the URL:

http://localhost:8080?wsPort=18765

From the right panel:

  • The web demo auto-onboards two simulated robots, SIM-01 and SIM-02.
  • The top evidence chain shows Input, Runtime, Fleet, and VDA 5050 cards for the active trace.
  • AGV Onboarding lets you add one extra AGV robot at the selected map node. The AGV emits VDA 5050-style connection, factsheet, and state events.
  • AGV VDA Events shows the exact VDA-style event sequence emitted by the onboarded AGV, including MQTT topic names.
  • MES is not onboarded as equipment. It remains a software source event through the MES: Production Complete scenario button.
  • VQA Pallet Ready publishes a VQA-style inference event into Runtime. If the Runtime admits it, master_control dispatches a VDA order and the simulated robot moves on the map.
  • MES: Production Complete publishes a deterministic manufacturing software event into the same Runtime-governed fleet path.
  • Block Low Confidence and Block Overweight publish rejected Runtime cases. They appear in the evidence timeline without producing a fleet task or VDA order.
  • Mark Offline publishes a broken connection state for the selected robot.
  • Reset SIM-01 and SIM-02 moves the two default simulated robots back to P01 and P02 and clears their active order state.

CLI Scenario Runner

Start MQTT:

mosquitto -v

Build and run the self-contained scenario demo:

source /opt/ros/humble/setup.bash
colcon build --packages-select edgeembed_vda5050
source install/setup.bash
export LD_PRELOAD=/lib/x86_64-linux-gnu/libtsan.so.0
ros2 run edgeembed_vda5050 scenario_runner

Expected result:

[scenario] PASS allow_transport
[scenario] PASS block_low_confidence
[scenario] PASS block_out_of_bounds

Runtime gateway

The Runtime-facing gateway subscribes to upstream events such as edgeembed/inference:

{
  "trace_id": "demo-001",
  "class": "pallet_ready",
  "confidence": 0.93,
  "command": {
    "action": "transport",
    "from": "L11",
    "to": "S01",
    "weight": 50
  }
}

The gateway submits fleet_demo::pallet_ready to the real EdgeEmbed runtime library with confidence and weight in the runtime payload. The bundle policy admits the event when confidence is at least 0.85 and weight is at most 1500. It rejects the same event through a fallback reject action otherwise.

If the runtime emits the admit action, the gateway publishes:

{
  "trace_id": "demo-001",
  "from": "L11",
  "to": "S01",
  "weight": 50
}

to:

fleet/task

If the Runtime blocks the action, it should publish a Runtime event and no fleet/task message.

E2E scenario runner

The E2E scenario runner can:

  • inject upstream inference events into Runtime
  • inject fleet faults such as CONNECTIONBROKEN
  • inject malformed or stale VDA 5050-style state messages
  • observe MQTT output from Runtime, master_control, and vehicle_adapter
  • assert that expected side effects did or did not happen

Minimum first scenarios:

  • low VQA confidence: Runtime blocks, no fleet/task, no VDA order
  • out-of-bounds command: Runtime blocks, no downstream device action
  • vehicle lost: fleet manager releases the zone and recovers or requeues the task
  • corridor contention: only one vehicle is granted corridor_1

Trace and evidence

The first useful contract field is trace_id. It flows through:

edgeembed/inference -> Runtime verdict -> fleet/task -> VDA order -> state/dashboard -> scenario result

The web dashboard shows this as a live evidence chain:

VQA result -> Runtime decision -> fleet task -> VDA order -> robot state -> scenario assertion

EdgeEmbed-HIL boundary

This repo's scenario_runner is not EdgeEmbed-HIL. It is an MQTT-level E2E scenario harness for the fleet demo. Real EdgeEmbed-HIL integration should call the separate EdgeEmbed-HIL daemon/tools to validate target-side evidence such as deployed adapter code, camera frames, logs, process health, GPIO, or other hardware capabilities.

Manual Dashboard Smoke Test

If you only want to verify the browser view:

mosquitto_pub -t uagv/v2/EdgeEmbed/AGV001/connection -m '{"connectionState":"ONLINE"}'
mosquitto_pub -t uagv/v2/EdgeEmbed/AGV001/factsheet -m '{"typeSpecification":{"seriesName":"tugger","maxLoadMass":1000}}'
mosquitto_pub -t uagv/v2/EdgeEmbed/AGV001/state -m '{"manufacturer":"EdgeEmbed","serialNumber":"AGV001","agvPosition":{"x":44,"y":20,"theta":0},"driving":true,"batteryState":{"batteryCharge":86},"orderId":"ORD-demo","errors":[],"nodeStates":[{"nodeId":"N02"}]}'

Highlight the narrow corridor and set KPI:

mosquitto_pub -t uagv/v2/EdgeEmbed/master_control/dashboard -m '{"zones":{"corridor_1":{"occupied":true,"holder":"AGV001","edges":["E_N01_N02"]}},"kpi":{"completed":6,"throughput_per_hour":142,"utilization_percent":71,"avg_wait_seconds":18}}'

Validation Commands

ament_flake8 edgeembed_vda5050 setup.py launch
ament_pep257 edgeembed_vda5050 setup.py launch
/usr/bin/python3 -m compileall edgeembed_vda5050
source /opt/ros/humble/setup.bash
colcon build --packages-select edgeembed_vda5050

Launch parse check:

ROS_LOG_DIR=/tmp/ros_log ros2 launch edgeembed_vda5050 demo.launch.py --show-args

VDA 5050 Coverage In This Demo

Implemented VDA 5050-style concepts:

  • topic namespace with interface, major version, manufacturer, serial, message
  • common message header fields
  • order
  • state
  • connection
  • factsheet
  • instantActions
  • nodes, edges, sequenceId, and released
  • agvPosition
  • batteryState
  • errors
  • safetyState

Custom demo concepts:

  • fleet/task
  • dashboard KPI messages
  • site topology YAML
  • browser WebSocket payload

Planned EdgeEmbed integration concepts:

  • edgeembed/inference
  • Runtime policy verdicts
  • E2E scenario inputs and assertions
  • trace_id across Runtime, fleet manager, adapter, dashboard, and replay

Limitations

  • This is a demo, not a complete certified VDA 5050 stack.
  • This is not the full EdgeEmbed Runtime implementation. The included runtime_gateway is the minimal demo gateway.
  • E2E scenario assertions are implemented for the first MQTT path, but journal, replay, and real EdgeEmbed-HIL hardware validation are still future work.
  • Real motion needs robot drivers or a simulator publishing TF and odometry.
  • The included Nav2 map is a simple placeholder.
  • pick, drop, and liftTo are simulated actions.
  • Traffic control is intentionally focused on the corridor_1 exclusive-zone demo.

About

A lightweight VDA5050-compatible demo fleet manager for Runtime, HIL, and mixed-brand AMR integration.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages