Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
58c22fc
feat(demo): scaffold multi-ECU aggregation demo package
bburda Mar 30, 2026
ada0602
feat(demo): add all 10 ROS 2 nodes for multi-ECU aggregation demo
bburda Mar 30, 2026
902d128
feat(demo): add config files for multi-ECU aggregation demo
bburda Mar 30, 2026
99def4b
feat(demo): add launch files for perception, planning, actuation ECUs
bburda Mar 30, 2026
a8a223e
feat(demo): add Dockerfile and docker-compose for multi-ECU demo
bburda Mar 30, 2026
5c31a75
feat(demo): add shell scripts and container scripts for fault injection
bburda Mar 30, 2026
9fb1a97
docs(demo): add README for multi-ECU aggregation demo
bburda Mar 30, 2026
b49fb6e
fix(demo): correct YAML namespace for gateway params
bburda Mar 30, 2026
36ac3c5
fix(demo): enable aggregation on actuation ECU and hide unmanifested …
bburda Mar 30, 2026
263e522
fix(demo): add infrastructure apps to manifests, use unmanifested_nod…
bburda Mar 31, 2026
c4cc503
fix(demo): change ROS2_MEDKIT_REF from feature branch to main
bburda Apr 2, 2026
f64870c
fix(demo): address review findings - shellcheck, clock type, timer re…
bburda Apr 2, 2026
d49cdda
fix(demo): update member variable on rate fallback in motor_controlle…
bburda Apr 2, 2026
18f4256
fix(demo): update gripper_rate_ on fallback, add explicit geometry_ms…
bburda Apr 2, 2026
f62533b
fix(demo): improve code quality, add CI and smoke test for multi-ECU …
bburda Apr 2, 2026
902abb5
fix(demo): fix actuation namespace references in main() functions
bburda Apr 2, 2026
6782a50
fix(demo): fix domain_bridge node names and relax component assertion…
bburda Apr 2, 2026
9c66caf
fix(demo): check ECU subcomponents at correct endpoint
bburda Apr 2, 2026
e3cee3e
fix: address review feedback on planning params and docker-compose
bburda Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ docker-compose.local.yml
.env
.venv/
venv/
demos/multi_ecu_aggregation/launch/__pycache__/
68 changes: 68 additions & 0 deletions demos/multi_ecu_aggregation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
cmake_minimum_required(VERSION 3.8)
project(multi_ecu_demo)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(nav_msgs REQUIRED)
find_package(vision_msgs REQUIRED)
find_package(diagnostic_msgs REQUIRED)
find_package(rcl_interfaces REQUIRED)
find_package(ros2_medkit_msgs REQUIRED)

# --- Perception ECU nodes ---
add_executable(lidar_driver src/perception/lidar_driver.cpp)
ament_target_dependencies(lidar_driver rclcpp sensor_msgs diagnostic_msgs rcl_interfaces)

add_executable(camera_driver src/perception/camera_driver.cpp)
ament_target_dependencies(camera_driver rclcpp sensor_msgs diagnostic_msgs rcl_interfaces)

add_executable(point_cloud_filter src/perception/point_cloud_filter.cpp)
ament_target_dependencies(point_cloud_filter rclcpp sensor_msgs diagnostic_msgs rcl_interfaces)

add_executable(object_detector src/perception/object_detector.cpp)
ament_target_dependencies(object_detector rclcpp sensor_msgs vision_msgs diagnostic_msgs rcl_interfaces)

# --- Planning ECU nodes ---
add_executable(path_planner src/planning/path_planner.cpp)
ament_target_dependencies(path_planner rclcpp nav_msgs vision_msgs diagnostic_msgs rcl_interfaces)
Comment thread
bburda marked this conversation as resolved.
Outdated

add_executable(behavior_planner src/planning/behavior_planner.cpp)
ament_target_dependencies(behavior_planner rclcpp nav_msgs geometry_msgs diagnostic_msgs rcl_interfaces)

add_executable(task_scheduler src/planning/task_scheduler.cpp)
ament_target_dependencies(task_scheduler rclcpp std_msgs diagnostic_msgs rcl_interfaces)

# --- Actuation ECU nodes ---
add_executable(motor_controller src/actuation/motor_controller.cpp)
ament_target_dependencies(motor_controller rclcpp sensor_msgs geometry_msgs diagnostic_msgs rcl_interfaces)

add_executable(joint_driver src/actuation/joint_driver.cpp)
ament_target_dependencies(joint_driver rclcpp sensor_msgs diagnostic_msgs rcl_interfaces)

add_executable(gripper_controller src/actuation/gripper_controller.cpp)
ament_target_dependencies(gripper_controller rclcpp sensor_msgs geometry_msgs diagnostic_msgs rcl_interfaces)

# --- Install ---
install(TARGETS
lidar_driver camera_driver point_cloud_filter object_detector
path_planner behavior_planner task_scheduler
motor_controller joint_driver gripper_controller
DESTINATION lib/${PROJECT_NAME}
)

install(DIRECTORY launch/ DESTINATION share/${PROJECT_NAME}/launch)
install(DIRECTORY config/ DESTINATION share/${PROJECT_NAME}/config)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
endif()

ament_package()
71 changes: 71 additions & 0 deletions demos/multi_ecu_aggregation/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Multi-ECU Aggregation Demo
FROM ros:jazzy-ros-base

ENV DEBIAN_FRONTEND=noninteractive
ENV ROS_DISTRO=jazzy
ENV COLCON_WS=/root/demo_ws

# Install minimal dependencies (no GUI/simulation)
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-${ROS_DISTRO}-vision-msgs \
ros-${ROS_DISTRO}-nav-msgs \
ros-${ROS_DISTRO}-domain-bridge \
ros-${ROS_DISTRO}-ament-lint-auto \
ros-${ROS_DISTRO}-ament-lint-common \
ros-${ROS_DISTRO}-ament-cmake-gtest \
ros-${ROS_DISTRO}-yaml-cpp-vendor \
ros-${ROS_DISTRO}-example-interfaces \
python3-colcon-common-extensions \
python3-requests \
nlohmann-json3-dev \
libcpp-httplib-dev \
libsystemd-dev \
sqlite3 \
libsqlite3-dev \
git \
curl \
jq \
&& rm -rf /var/lib/apt/lists/*

# Clone ros2_medkit from GitHub (gateway + dependencies + plugins)
ARG ROS2_MEDKIT_REF=feat/entity-model-and-aggregation
WORKDIR ${COLCON_WS}/src
RUN git clone --depth 1 --branch ${ROS2_MEDKIT_REF} https://github.com/selfpatch/ros2_medkit.git && \
mv ros2_medkit/src/ros2_medkit_cmake . && \
mv ros2_medkit/src/ros2_medkit_gateway . && \
mv ros2_medkit/src/ros2_medkit_serialization . && \
mv ros2_medkit/src/ros2_medkit_msgs . && \
mv ros2_medkit/src/ros2_medkit_fault_manager . && \
mv ros2_medkit/src/ros2_medkit_fault_reporter . && \
mv ros2_medkit/src/ros2_medkit_diagnostic_bridge . && \
mv ros2_medkit/src/ros2_medkit_plugins/ros2_medkit_graph_provider . && \
rm -rf ros2_medkit

# Copy demo package
COPY package.xml CMakeLists.txt ${COLCON_WS}/src/multi_ecu_demo/
COPY src/ ${COLCON_WS}/src/multi_ecu_demo/src/
COPY config/ ${COLCON_WS}/src/multi_ecu_demo/config/
COPY launch/ ${COLCON_WS}/src/multi_ecu_demo/launch/

# Copy container scripts
COPY container_scripts/ /var/lib/ros2_medkit/scripts/
RUN find /var/lib/ros2_medkit/scripts -name "*.bash" -exec chmod +x {} \;

# Build all packages (skip test dependencies that aren't in ros-base)
WORKDIR ${COLCON_WS}
RUN bash -c "source /opt/ros/jazzy/setup.bash && \
rosdep update && \
rosdep install --from-paths src --ignore-src -r -y \
--skip-keys='ament_cmake_clang_format ament_cmake_clang_tidy test_msgs example_interfaces sqlite3' && \
colcon build --symlink-install --cmake-args -DBUILD_TESTING=OFF"

# Setup environment
RUN echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc && \
echo "source ${COLCON_WS}/install/setup.bash" >> ~/.bashrc

# Expose gateway port
EXPOSE 8080

# ECU_LAUNCH env var selects which launch file to run
ENV ECU_LAUNCH=perception.launch.py
CMD ["bash", "-c", "mkdir -p /var/lib/ros2_medkit/rosbags && source /opt/ros/jazzy/setup.bash && source /root/demo_ws/install/setup.bash && ros2 launch multi_ecu_demo ${ECU_LAUNCH}"]
Loading
Loading