Skip to content

Commit 77c40f8

Browse files
committed
feat: update all demos to gateway v0.4.0 with plugins
- Add new packages to all 3 Dockerfiles: ros2_medkit_cmake, ros2_medkit_graph_provider, beacon plugins (topic, param, common), and linux introspection plugins (procfs, systemd, container) - Add libsystemd-dev dependency for systemd introspection plugin - Add ARG ROS2_MEDKIT_REF=main for pinnable builds (sensor, turtlebot) - Add -DBUILD_TESTING=OFF to turtlebot3 Dockerfile - Fix broken discovery params: discovery_mode -> discovery.mode, manifest_path -> discovery.manifest_path (nested namespace) - Configure graph_provider and procfs_introspection plugins in all demo launch files with dynamic path resolution - Rename web UI references: sovd_web_ui -> ros2_medkit_web_ui (Docker image, service name, container name, READMEs) Closes #40
1 parent 5295aab commit 77c40f8

16 files changed

Lines changed: 207 additions & 40 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ to complete mobile robot integration:
3333
Both demos support:
3434

3535
- REST API access via SOVD protocol
36-
- Web UI for visualization ([sovd_web_ui](https://github.com/selfpatch/sovd_web_ui))
36+
- Web UI for visualization ([ros2_medkit_web_ui](https://github.com/selfpatch/ros2_medkit_web_ui))
3737
- Fault injection and monitoring
3838
- Docker deployment for easy setup
3939

@@ -176,7 +176,7 @@ See individual demo READMEs for more examples.
176176
## Related Projects
177177

178178
- [ros2_medkit](https://github.com/selfpatch/ros2_medkit) — Core diagnostics library with SOVD-compliant gateway
179-
- [sovd_web_ui](https://github.com/selfpatch/sovd_web_ui) — Web-based visualization and control interface
179+
- [ros2_medkit_web_ui](https://github.com/selfpatch/ros2_medkit_web_ui) — Web-based visualization and control interface
180180
- [ros2_medkit_mcp](https://github.com/selfpatch/ros2_medkit_mcp) — MCP server for LLM integration
181181
- [ros2_medkit documentation](https://selfpatch.github.io/ros2_medkit/) — Full documentation and API reference
182182

demos/moveit_pick_place/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ RUN apt-get update && apt-get install -y \
3131
libcpp-httplib-dev \
3232
ros-jazzy-rosbag2-storage-mcap \
3333
ros-jazzy-foxglove-bridge \
34+
libsystemd-dev \
3435
sqlite3 libsqlite3-dev git curl \
3536
&& rm -rf /var/lib/apt/lists/*
3637

@@ -41,12 +42,18 @@ RUN mkdir -p /var/lib/ros2_medkit/rosbags
4142
ARG ROS2_MEDKIT_REF=main
4243
WORKDIR ${COLCON_WS}/src
4344
RUN git clone --depth 1 --branch ${ROS2_MEDKIT_REF} https://github.com/selfpatch/ros2_medkit.git && \
45+
mv ros2_medkit/src/ros2_medkit_cmake . && \
4446
mv ros2_medkit/src/ros2_medkit_gateway \
4547
ros2_medkit/src/ros2_medkit_msgs \
4648
ros2_medkit/src/ros2_medkit_serialization \
4749
ros2_medkit/src/ros2_medkit_fault_manager \
4850
ros2_medkit/src/ros2_medkit_fault_reporter \
4951
ros2_medkit/src/ros2_medkit_diagnostic_bridge . && \
52+
mv ros2_medkit/src/ros2_medkit_plugins/ros2_medkit_graph_provider . && \
53+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common . && \
54+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon . && \
55+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon . && \
56+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_linux_introspection . && \
5057
rm -rf ros2_medkit
5158

5259
# Copy demo package from local context

demos/moveit_pick_place/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ That's it! The script will:
4040
1. Build the Docker image (first run: ~15-20 min, ~7 GB)
4141
2. Set up X11 forwarding for Gazebo GUI
4242
3. Launch Panda robot in factory world + MoveIt 2 + ros2_medkit gateway
43-
4. Launch sovd_web_ui at http://localhost:3000
43+
4. Launch ros2_medkit_web_ui at http://localhost:3000
4444

4545
**REST API:** http://localhost:8080/api/v1/
4646
**Web UI:** http://localhost:3000/
@@ -120,7 +120,7 @@ docker exec -it moveit_medkit_demo bash # Shell into container
120120
121121
┌─────────────┼─────────────┐
122122
│ │ │
123-
sovd_web_ui curl/httpie MCP Server
123+
ros2_medkit_web_ui curl/httpie MCP Server
124124
:3000 (LLM tools)
125125
```
126126

@@ -300,7 +300,7 @@ curl http://localhost:8080/api/v1/faults | jq '.items[] | {fault_code, severity_
300300

301301
## Web UI
302302

303-
The sovd_web_ui container starts automatically at **http://localhost:3000**.
303+
The ros2_medkit_web_ui container starts automatically at **http://localhost:3000**.
304304

305305
Connect it to the gateway at `http://localhost:8080` to browse:
306306
- Entity tree (Areas → Components → Apps)

demos/moveit_pick_place/config/medkit_params.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ diagnostics:
2121
max_parallel_topic_samples: 10
2222

2323
# Discovery configuration
24-
discovery_mode: "hybrid" # runtime_only, manifest_only, or hybrid
25-
manifest_path: "" # Will be set via launch argument
26-
manifest_strict_validation: true
27-
2824
discovery:
25+
mode: "hybrid" # runtime_only, manifest_only, or hybrid
26+
manifest_path: "" # Will be set via launch argument
27+
manifest_strict_validation: true
2928
runtime:
3029
create_synthetic_components: false # Manifest defines components
3130

31+
# Plugin configuration (paths set by launch file)
32+
plugins: ["graph_provider", "procfs_introspection"]
33+
plugins.graph_provider.path: ""
34+
plugins.procfs_introspection.path: ""
35+
3236
# Fault Manager configuration (runs in root namespace)
3337
fault_manager:
3438
ros__parameters:

demos/moveit_pick_place/docker-compose.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ services:
6262
source /root/demo_ws/install/setup.bash &&
6363
ros2 launch moveit_medkit_demo $${LAUNCH_FILE} headless:=$${HEADLESS}"
6464
65-
# SOVD Web UI pre-built from GHCR
66-
sovd-web-ui:
67-
image: ghcr.io/selfpatch/sovd_web_ui:latest
68-
container_name: sovd_web_ui
65+
# Web UI - pre-built from GHCR
66+
medkit-web-ui:
67+
image: ghcr.io/selfpatch/ros2_medkit_web_ui:latest
68+
container_name: ros2_medkit_web_ui
6969
ports:
7070
- "3000:80"

demos/moveit_pick_place/launch/demo.launch.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
import os
1313

14+
from ament_index_python.packages import get_package_prefix
1415
from ament_index_python.packages import get_package_share_directory
16+
from ament_index_python.packages import PackageNotFoundError
1517
from launch import LaunchDescription
1618
from launch.actions import (
1719
DeclareLaunchArgument,
@@ -24,6 +26,18 @@
2426
from launch_ros.actions import Node
2527

2628

29+
def _resolve_plugin_path(package_name, lib_name):
30+
"""Resolve a gateway plugin .so path, returning empty string if not found."""
31+
try:
32+
prefix = get_package_prefix(package_name)
33+
path = os.path.join(prefix, 'lib', package_name, f'lib{lib_name}.so')
34+
if os.path.isfile(path):
35+
return path
36+
except PackageNotFoundError:
37+
pass
38+
return ''
39+
40+
2741
def generate_launch_description():
2842
# Get package share directories
2943
demo_pkg_dir = get_package_share_directory("moveit_medkit_demo")
@@ -35,6 +49,24 @@ def generate_launch_description():
3549
medkit_params_file = os.path.join(demo_pkg_dir, "config", "medkit_params.yaml")
3650
manifest_file = os.path.join(demo_pkg_dir, "config", "panda_manifest.yaml")
3751

52+
# Resolve plugin paths
53+
graph_provider_path = _resolve_plugin_path(
54+
'ros2_medkit_graph_provider', 'ros2_medkit_graph_provider_plugin')
55+
procfs_plugin_path = _resolve_plugin_path(
56+
'ros2_medkit_linux_introspection', 'procfs_introspection')
57+
58+
# Build plugin overrides - only include plugins that were found
59+
plugin_overrides = {}
60+
active_plugins = []
61+
if graph_provider_path:
62+
active_plugins.append('graph_provider')
63+
plugin_overrides['plugins.graph_provider.path'] = graph_provider_path
64+
if procfs_plugin_path:
65+
active_plugins.append('procfs_introspection')
66+
plugin_overrides['plugins.procfs_introspection.path'] = procfs_plugin_path
67+
if active_plugins:
68+
plugin_overrides['plugins'] = active_plugins
69+
3870
# Launch configuration variables
3971
use_sim_time = LaunchConfiguration("use_sim_time", default="False")
4072
headless = LaunchConfiguration("headless", default="False")
@@ -126,8 +158,9 @@ def generate_launch_description():
126158
medkit_params_file,
127159
{
128160
"use_sim_time": use_sim_time,
129-
"manifest_path": manifest_file,
161+
"discovery.manifest_path": manifest_file,
130162
},
163+
plugin_overrides,
131164
],
132165
),
133166
# === Foxglove Bridge (WebSocket on port 8765) ===

demos/moveit_pick_place/launch/demo_gazebo.launch.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
import xacro
2323
import yaml
24+
from ament_index_python.packages import get_package_prefix
2425
from ament_index_python.packages import get_package_share_directory
26+
from ament_index_python.packages import PackageNotFoundError
2527
from launch import LaunchDescription
2628
from launch.actions import (
2729
DeclareLaunchArgument,
@@ -36,6 +38,18 @@
3638
from launch_ros.substitutions import FindPackageShare
3739

3840

41+
def _resolve_plugin_path(package_name, lib_name):
42+
"""Resolve a gateway plugin .so path, returning empty string if not found."""
43+
try:
44+
prefix = get_package_prefix(package_name)
45+
path = os.path.join(prefix, 'lib', package_name, f'lib{lib_name}.so')
46+
if os.path.isfile(path):
47+
return path
48+
except PackageNotFoundError:
49+
pass
50+
return ''
51+
52+
3953
def generate_launch_description():
4054
# ── Package directories ──────────────────────────────────────────
4155
demo_pkg_dir = get_package_share_directory("moveit_medkit_demo")
@@ -54,6 +68,24 @@ def generate_launch_description():
5468
demo_pkg_dir, "config", "panda_manifest.yaml"
5569
)
5670

71+
# Resolve plugin paths
72+
graph_provider_path = _resolve_plugin_path(
73+
'ros2_medkit_graph_provider', 'ros2_medkit_graph_provider_plugin')
74+
procfs_plugin_path = _resolve_plugin_path(
75+
'ros2_medkit_linux_introspection', 'procfs_introspection')
76+
77+
# Build plugin overrides - only include plugins that were found
78+
plugin_overrides = {}
79+
active_plugins = []
80+
if graph_provider_path:
81+
active_plugins.append('graph_provider')
82+
plugin_overrides['plugins.graph_provider.path'] = graph_provider_path
83+
if procfs_plugin_path:
84+
active_plugins.append('procfs_introspection')
85+
plugin_overrides['plugins.procfs_introspection.path'] = procfs_plugin_path
86+
if active_plugins:
87+
plugin_overrides['plugins'] = active_plugins
88+
5789
# Factory world file path
5890
factory_world = os.path.join(
5991
demo_pkg_dir, "worlds", "factory.sdf"
@@ -470,8 +502,9 @@ def generate_launch_description():
470502
medkit_params_file,
471503
{
472504
"use_sim_time": True,
473-
"manifest_path": manifest_file,
505+
"discovery.manifest_path": manifest_file,
474506
},
507+
plugin_overrides,
475508
],
476509
),
477510
# ═════════════════════════════════════════════════════════

demos/sensor_diagnostics/Dockerfile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,30 @@ RUN apt-get update && apt-get install -y \
1616
python3-requests \
1717
nlohmann-json3-dev \
1818
libcpp-httplib-dev \
19+
libsystemd-dev \
1920
sqlite3 \
2021
libsqlite3-dev \
2122
git \
2223
curl \
2324
jq \
2425
&& rm -rf /var/lib/apt/lists/*
2526

26-
# Clone ros2_medkit from GitHub (gateway + dependencies)
27+
# Clone ros2_medkit from GitHub (gateway + dependencies + plugins)
28+
ARG ROS2_MEDKIT_REF=main
2729
WORKDIR ${COLCON_WS}/src
28-
RUN git clone --depth 1 https://github.com/selfpatch/ros2_medkit.git && \
30+
RUN git clone --depth 1 --branch ${ROS2_MEDKIT_REF} https://github.com/selfpatch/ros2_medkit.git && \
31+
mv ros2_medkit/src/ros2_medkit_cmake . && \
2932
mv ros2_medkit/src/ros2_medkit_gateway . && \
3033
mv ros2_medkit/src/ros2_medkit_serialization . && \
3134
mv ros2_medkit/src/ros2_medkit_msgs . && \
3235
mv ros2_medkit/src/ros2_medkit_fault_manager . && \
3336
mv ros2_medkit/src/ros2_medkit_fault_reporter . && \
3437
mv ros2_medkit/src/ros2_medkit_diagnostic_bridge . && \
38+
mv ros2_medkit/src/ros2_medkit_plugins/ros2_medkit_graph_provider . && \
39+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common . && \
40+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon . && \
41+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon . && \
42+
mv ros2_medkit/src/ros2_medkit_discovery_plugins/ros2_medkit_linux_introspection . && \
3543
rm -rf ros2_medkit
3644

3745
# Copy demo package

demos/sensor_diagnostics/config/medkit_params.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ diagnostics:
1919
max_parallel_topic_samples: 10
2020

2121
# Discovery configuration
22-
discovery_mode: "hybrid" # runtime_only, manifest_only, or hybrid
23-
manifest_path: "" # Will be set via launch argument
24-
manifest_strict_validation: true
25-
2622
discovery:
23+
mode: "hybrid" # runtime_only, manifest_only, or hybrid
24+
manifest_path: "" # Will be set via launch argument
25+
manifest_strict_validation: true
2726
runtime:
2827
create_synthetic_components: false # Manifest defines components
2928

29+
# Plugin configuration (paths set by launch file)
30+
plugins: ["graph_provider", "procfs_introspection"]
31+
plugins.graph_provider.path: ""
32+
plugins.procfs_introspection.path: ""
33+
3034
# Fault Manager configuration (runs in root namespace)
3135
fault_manager:
3236
ros__parameters:

demos/sensor_diagnostics/docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ services:
2020
ros2 launch sensor_diagnostics_demo demo.launch.py"
2121
2222
# Web UI for visualization (optional)
23-
sovd-web-ui:
24-
image: ghcr.io/selfpatch/sovd_web_ui:latest
25-
container_name: sovd_web_ui
23+
medkit-web-ui:
24+
image: ghcr.io/selfpatch/ros2_medkit_web_ui:latest
25+
container_name: ros2_medkit_web_ui
2626
ports:
2727
- "3000:80"
2828
depends_on:

0 commit comments

Comments
 (0)