Skip to content

Conversation

@bburda
Copy link
Contributor

@bburda bburda commented Jan 29, 2026

Description

Major improvements to TurtleBot3 integration demo:

Core Features:

  • Add manifest-based entity discovery (SOVD hierarchy: Areas→Components→Apps→Functions)
  • Implement fault management via diagnostic_bridge + fault_manager
  • Add SQLite storage for persistent fault tracking
  • Support conditional headless/GUI Gazebo modes

Docker & Launch:

  • Fix Dockerfile: add ros2_medkit_fault_manager, fault_reporter, diagnostic_bridge packages
  • Add SQLite dependencies (sqlite3, libsqlite3-dev)
  • Update launch file: conditional Gazebo launch based on headless argument
  • Change default mode from headless to GUI for better UX
  • Add HEADLESS environment variable support in docker-compose.yml

Manifest & Configuration:

  • Add turtlebot3_manifest.yaml defining complete entity hierarchy
  • Configure 4 areas: robot, navigation, diagnostics, bridge
  • Define 6 components: turtlebot3-base, lidar-sensor, nav2-stack, gateway, fault-manager, diagnostic-bridge-unit
  • Define 11 apps with ROS node bindings and dependencies
  • Define 3 functions: autonomous-navigation, robot-control, fault-management

Shell Scripts:

  • Fix all app IDs: underscore format → hyphen format (bt_navigator → bt-navigator, etc.)
  • Add check-entities.sh: explore SOVD entity hierarchy
  • Add check-faults.sh: view active faults
  • Add inject-nav-failure.sh: trigger unreachable goal scenario
  • Add inject-localization-failure.sh: reset AMCL with high uncertainty
  • Add inject-controller-failure.sh: set restrictive velocity limits
  • Add inject-collision.sh: navigate toward obstacles
  • Add restore-normal.sh: restore defaults and clear faults
  • Update send-nav-goal.sh: use SOVD API instead of docker exec

Documentation:

  • Completely rewrite TurtleBot3 demo README with:
    • Clear GUI vs headless mode instructions
    • SOVD entity hierarchy explanation
    • Fault management architecture diagram
    • Fault injection scenarios table
    • Complete REST API examples for all endpoints
    • Scripts reference table

Testing:

  • All scripts verified working with GATEWAY_URL=http://172.19.0.2:8080
  • Navigation goals successfully executed via SOVD API
  • Fault injection scenarios tested
  • 23 components discovered, 0 initial faults confirmed
  • GUI and headless modes both tested and working

Related Issue

closes #9

Checklist

  • Tested locally
  • README updated (if needed)

…ment and GUI as default

Major improvements to TurtleBot3 integration demo:

Core Features:
- Add manifest-based entity discovery (SOVD hierarchy: Areas→Components→Apps→Functions)
- Implement fault management via diagnostic_bridge + fault_manager
- Add SQLite storage for persistent fault tracking
- Support conditional headless/GUI Gazebo modes

Docker & Launch:
- Fix Dockerfile: add ros2_medkit_fault_manager, fault_reporter, diagnostic_bridge packages
- Add SQLite dependencies (sqlite3, libsqlite3-dev)
- Update launch file: conditional Gazebo launch based on headless argument
- Change default mode from headless to GUI for better UX
- Add HEADLESS environment variable support in docker-compose.yml

Manifest & Configuration:
- Add turtlebot3_manifest.yaml defining complete entity hierarchy
- Configure 4 areas: robot, navigation, diagnostics, bridge
- Define 6 components: turtlebot3-base, lidar-sensor, nav2-stack, gateway, fault-manager, diagnostic-bridge-unit
- Define 11 apps with ROS node bindings and dependencies
- Define 3 functions: autonomous-navigation, robot-control, fault-management

Shell Scripts:
- Fix all app IDs: underscore format → hyphen format (bt_navigator → bt-navigator, etc.)
- Add check-entities.sh: explore SOVD entity hierarchy
- Add check-faults.sh: view active faults
- Add inject-nav-failure.sh: trigger unreachable goal scenario
- Add inject-localization-failure.sh: reset AMCL with high uncertainty
- Add inject-controller-failure.sh: set restrictive velocity limits
- Add inject-collision.sh: navigate toward obstacles
- Add restore-normal.sh: restore defaults and clear faults
- Update send-nav-goal.sh: use SOVD API instead of docker exec

Documentation:
- Completely rewrite TurtleBot3 demo README with:
  * Clear GUI vs headless mode instructions
  * SOVD entity hierarchy explanation
  * Fault management architecture diagram
  * Fault injection scenarios table
  * Complete REST API examples for all endpoints
  * Scripts reference table

Testing:
- All scripts verified working with GATEWAY_URL=http://172.19.0.2:8080
- Navigation goals successfully executed via SOVD API
- Fault injection scenarios tested
- 23 components discovered, 0 initial faults confirmed
- GUI and headless modes both tested and working
@bburda bburda requested a review from mfaferek93 January 29, 2026 16:24
@bburda bburda self-assigned this Jan 29, 2026
Copilot AI review requested due to automatic review settings January 29, 2026 16:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR significantly enhances the TurtleBot3 integration demo by adding complete SOVD-compliant entity discovery, fault management capabilities, and improved Docker deployment options with both GUI and headless Gazebo modes.

Changes:

  • Implemented manifest-based entity discovery with complete SOVD hierarchy (Areas → Components → Apps → Functions)
  • Added fault management system with diagnostic_bridge for legacy /diagnostics topic support and persistent SQLite storage
  • Introduced conditional Gazebo launch modes (GUI/headless) with default GUI mode for better user experience
  • Created comprehensive fault injection scripts and monitoring tools for testing fault scenarios
  • Updated all documentation with REST API examples, entity hierarchy explanations, and fault management architecture

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
send-nav-goal.sh Migrated from docker exec to SOVD API for navigation goals, added robust validation and error handling
run-demo.sh Added --headless flag with environment variable support for conditional Gazebo modes
restore-normal.sh New script to restore default parameters and clear all faults after testing scenarios
inject-nav-failure.sh New fault injection script for unreachable navigation goals
inject-localization-failure.sh New fault injection script triggering AMCL uncertainty via global relocalization
inject-controller-failure.sh New fault injection script setting restrictive velocity limits
inject-collision.sh New fault injection script navigating toward obstacles
check-faults.sh New script to query and display active faults from gateway
check-entities.sh New script to explore complete SOVD entity hierarchy
demo.launch.py Added conditional headless/GUI Gazebo launch, fault_manager and diagnostic_bridge nodes, manifest path configuration
turtlebot3_manifest.yaml New complete SOVD manifest defining 4 areas, 6 components, 11 apps, and 3 functions
medkit_params.yaml Updated with hybrid discovery mode, DELETE method in CORS, and manifest configuration
docker-compose.yml Added HEADLESS environment variable support, switched to pre-built sovd_web_ui image
Dockerfile Added SQLite dependencies and ros2_medkit fault management packages
README.md (root) Expanded overview with SOVD capabilities, added both demo quick starts, included API examples
README.md (turtlebot3) Complete rewrite with GUI/headless instructions, entity hierarchy documentation, fault injection scenarios, comprehensive API reference

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


# Stop the robot
curl -X POST http://localhost:8080/api/v1/topics/publish \
curl -X PUT http://localhost:8080/api/v1/apps/turtlebot3_node/data/cmd_vel \
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app ID used in the API endpoints is incorrect. The manifest defines the app ID as "turtlebot3-node" (with hyphen), but the documentation uses "turtlebot3_node" (with underscore). This inconsistency will cause API calls to fail.

All references to "apps/turtlebot3_node" should be changed to "apps/turtlebot3-node" to match the manifest definition in config/turtlebot3_manifest.yaml line 83.

Copilot uses AI. Check for mistakes.
exit 1
fi
echo "✓ Gateway is healthy"

Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing dependency check for 'jq'. This script uses jq extensively throughout (lines 34, 37, 40, 43, 47, 56) but doesn't verify it's installed. If jq is not available, the script will fail with unclear error messages.

Add a check similar to the one in send-nav-goal.sh lines 19-22 to verify jq is installed before proceeding.

Suggested change
# Check for jq dependency
if ! command -v jq >/dev/null 2>&1; then
echo "❌ 'jq' is required but not installed."
echo " Please install jq (e.g., 'sudo apt-get install jq') and retry."
exit 1
fi

Copilot uses AI. Check for mistakes.
echo "❌ Gateway not available at ${GATEWAY_URL}"
exit 1
fi

Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing dependency check for 'jq'. This script uses jq on lines 21, 22, and 51 but doesn't verify it's installed. If jq is not available, the script will fail with unclear error messages.

Add a check similar to the one in send-nav-goal.sh lines 19-22 to verify jq is installed before proceeding.

Suggested change
# Check jq dependency
if ! command -v jq > /dev/null 2>&1; then
echo "❌ Missing dependency: 'jq' is required but not installed."
echo " Please install jq (https://stedolan.github.io/jq/) and try again."
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +68
depends_on:
- turtlebot3-demo
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sovd-web-ui service declares a dependency on "turtlebot3-demo", but when users run with the nvidia profile (docker compose --profile nvidia up), only the "turtlebot3-demo-nvidia" service will start. This means sovd-web-ui won't start in nvidia mode because its dependency won't be satisfied.

Consider either:

  1. Removing the depends_on clause (the web UI can retry connecting)
  2. Creating a conditional dependency that works with both service variants
  3. Using a shared service name with profiles

The simplest fix is to remove the depends_on clause since the web UI can handle the gateway not being immediately available.

Suggested change
depends_on:
- turtlebot3-demo

Copilot uses AI. Check for mistakes.
# Send velocity command (moves robot forward)
curl -X POST http://localhost:8080/api/v1/topics/publish \
# Send velocity command using Apps data endpoint (moves robot forward)
curl -X PUT http://localhost:8080/api/v1/apps/turtlebot3_node/data/cmd_vel \
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app ID used in the API endpoints is incorrect. The manifest defines the app ID as "turtlebot3-node" (with hyphen), but the documentation uses "turtlebot3_node" (with underscore). This inconsistency will cause API calls to fail.

All references to "apps/turtlebot3_node" should be changed to "apps/turtlebot3-node" to match the manifest definition in config/turtlebot3_manifest.yaml line 83.

Copilot uses AI. Check for mistakes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot seems to be right here :)

Comment on lines +156 to +169
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data/scan | jq '{
angle_min: .angle_min,
angle_max: .angle_max,
sample_ranges: .ranges[:5]
}'

# Get odometry data
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data/odom | jq '{
position: .pose.pose.position,
orientation: .pose.pose.orientation
}'

# List all data topics for an app
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data | jq
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app ID used in the API endpoint is incorrect. The manifest defines the app ID as "turtlebot3-node" (with hyphen), but the documentation uses "turtlebot3_node" (with underscore). This inconsistency will cause API calls to fail.

Change "apps/turtlebot3_node" to "apps/turtlebot3-node" to match the manifest definition.

Suggested change
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data/scan | jq '{
angle_min: .angle_min,
angle_max: .angle_max,
sample_ranges: .ranges[:5]
}'
# Get odometry data
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data/odom | jq '{
position: .pose.pose.position,
orientation: .pose.pose.orientation
}'
# List all data topics for an app
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data | jq
curl http://localhost:8080/api/v1/apps/turtlebot3-node/data/scan | jq '{
angle_min: .angle_min,
angle_max: .angle_max,
sample_ranges: .ranges[:5]
}'
# Get odometry data
curl http://localhost:8080/api/v1/apps/turtlebot3-node/data/odom | jq '{
position: .pose.pose.position,
orientation: .pose.pose.orientation
}'
# List all data topics for an app
curl http://localhost:8080/api/v1/apps/turtlebot3-node/data | jq

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +26
#!/bin/bash
# Check current faults from ros2_medkit gateway
# Faults are collected from Nav2/TurtleBot3 via diagnostic_bridge

GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}"
API_BASE="${GATEWAY_URL}/api/v1"

echo "🔍 Checking faults from ros2_medkit gateway..."
echo ""

# Wait for gateway
echo "Checking gateway health..."
if ! curl -sf "${API_BASE}/health" > /dev/null 2>&1; then
echo "❌ Gateway not available at ${GATEWAY_URL}"
echo " Start with: ./run-demo.sh"
exit 1
fi
echo "✓ Gateway is healthy"
echo ""

# Get all faults
echo "📋 Active Faults:"
FAULTS=$(curl -s "${API_BASE}/faults")

# Check if there are any faults
FAULT_COUNT=$(echo "$FAULTS" | jq '.items | length')
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing dependency check for 'jq'. This script uses jq extensively but doesn't verify it's installed before attempting to use it. If jq is not available, the script will fail with unclear error messages.

Add a check similar to the one in send-nav-goal.sh lines 19-22 to verify jq is installed before proceeding.

Copilot uses AI. Check for mistakes.
from launch.conditions import IfCondition, UnlessCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch.substitutions import LaunchConfiguration, PythonExpression
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import. The PythonExpression class is imported but never used in the launch file. This should be removed to keep the imports clean.

Suggested change
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch.substitutions import LaunchConfiguration

Copilot uses AI. Check for mistakes.
# Publish to topic (see examples above)
curl -X POST http://localhost:8080/api/v1/topics/publish ...
# Clear a specific fault
curl -X DELETE http://localhost:8080/api/v1/apps/diagnostic_bridge/faults/TURTLEBOT3_NODE
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app ID used in the API endpoint is incorrect. The manifest defines the app ID as "diagnostic-bridge" (with hyphen at line 177 of turtlebot3_manifest.yaml), but the documentation uses "diagnostic_bridge" (with underscore). This inconsistency will cause API calls to fail.

Change "apps/diagnostic_bridge" to "apps/diagnostic-bridge" to match the manifest definition.

Suggested change
curl -X DELETE http://localhost:8080/api/v1/apps/diagnostic_bridge/faults/TURTLEBOT3_NODE
curl -X DELETE http://localhost:8080/api/v1/apps/diagnostic-bridge/faults/TURTLEBOT3_NODE

Copilot uses AI. Check for mistakes.
mv ros2_medkit/src/ros2_medkit_gateway \
ros2_medkit/src/ros2_medkit_msgs \
ros2_medkit/src/ros2_medkit_serialization \
ros2_medkit/src/ros2_medkit_fault_manager \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we're cloning from the main branch with --depth 1, builds might break if the upstream repo changes. Maybe worth pinning to a specific commit or tag for reproducibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We’re cloning these packages only because they haven’t been deployed to the ROS Index yet.
For now, I suggest we leave this as-is and open a follow-up issue to replace all git clone/mv steps for ros2_medkit packages with a simple rosdep install driven by package.xml.

launch_arguments={"use_sim_time": use_sim_time}.items(),
condition=UnlessCondition(headless),
),
# Spawn TurtleBot3 robot (both modes)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "Spawn TurtleBot3 robot (both modes)" but looking at the condition on line 109, it only spawns in headless mode.

}
}')

echo "$RESPONSE" | jq '.' 2>/dev/null || echo "$RESPONSE"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might blow up if the gateway returns an error message instead of JSON - jq will just fail silently. Maybe add a quick check before piping to jq?

Comment on lines +32 to +34
curl -s -X PUT "${API_BASE}/apps/velocity-smoother/configurations/max_velocity" \
-H "Content-Type: application/json" \
-d '{"value": [0.26, 0.0, 1.0]}' > /dev/null 2>&1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see all the curl errors are going to /dev/null here - makes for clean output but could be tricky to debug if something goes wrong. Maybe keep stderr visible or log to a file?

# Send velocity command (moves robot forward)
curl -X POST http://localhost:8080/api/v1/topics/publish \
# Send velocity command using Apps data endpoint (moves robot forward)
curl -X PUT http://localhost:8080/api/v1/apps/turtlebot3_node/data/cmd_vel \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot seems to be right here :)

),
# Launch ros2_medkit fault_manager in root namespace
# Aggregates faults from all nodes via ReportFault service
Node(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The launch file uses ros2_medkit_fault_manager and ros2_medkit_diagnostic_bridge packages, but they're not listed in package.xml exec_depend. It works in Docker because everything's built together, but for completeness you might want to add

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also can we put a real email/name in package.xml instead of demo@example.com?


echo_step "5. Sample Data (LiDAR Scan)"
echo "Getting latest LiDAR scan from TurtleBot3..."
curl -s "${API_BASE}/apps/turtlebot3-node/data/scan" 2>/dev/null | jq '{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check-entities.sh uses the correct manifest ID:
curl -s "${API_BASE}/apps/turtlebot3-node/data/scan"
But README.md:156 uses:
curl http://localhost:8080/api/v1/apps/turtlebot3_node/data/scan
One of these won't work 😅

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

echo "✓ Gateway is healthy"

echo_step "1. Areas (Namespace Groupings)"
curl -s "${API_BASE}/areas" | jq '.items[] | {id: .id, name: .name, description: .description}'
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script uses jq extensively for parsing JSON responses (lines 34, 37, 40, 43, 47, 56, 62-64) but does not check if jq is installed. If jq is not available, the script will fail with cryptic errors. Consider adding a check for required dependencies at the beginning of the script.

Copilot uses AI. Check for mistakes.
}
}')

echo "$RESPONSE" | jq '.' 2>/dev/null || echo "$RESPONSE"
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script uses jq for parsing JSON responses (line 34) but does not check if jq is installed. If jq is not available, the script will fail with a cryptic error. Consider adding a check for required dependencies at the beginning of the script.

Copilot uses AI. Check for mistakes.
os.path.join(ros_gz_sim_dir, "launch", "gz_sim.launch.py")
),
launch_arguments={
"gz_args": ["-r -s -v2 ", world_file],
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gz_args list construction ["-r -s -v2 ", world_file] will concatenate the flag string with the world file path, potentially resulting in improper spacing. This could work but is fragile. Consider using separate list items for clarity: ["-r", "-s", "-v2", world_file].

Suggested change
"gz_args": ["-r -s -v2 ", world_file],
"gz_args": ["-r", "-s", "-v2", world_file],

Copilot uses AI. Check for mistakes.

# Stop the robot
curl -X POST http://localhost:8080/api/v1/topics/publish \
curl -X PUT http://localhost:8080/api/v1/apps/turtlebot3_node/data/cmd_vel \
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app ID should be "turtlebot3-node" (with hyphens) to match the manifest definition, not "turtlebot3_node" (with underscores).

Copilot uses AI. Check for mistakes.
echo "✓ Normal operation restored!"
echo ""
echo "Current fault status:"
curl -s "${API_BASE}/faults" | jq '.items | length' | xargs -I {} echo " Active faults: {}"
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script uses jq for parsing JSON responses (line 51) but does not check if jq is installed. If jq is not available, the script will fail with a cryptic error. Consider adding a check similar to send-nav-goal.sh that validates the presence of required dependencies.

Copilot uses AI. Check for mistakes.
}
}')

echo "$RESPONSE" | jq '.' 2>/dev/null || echo "$RESPONSE"
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script uses jq for parsing JSON responses (line 35) but does not check if jq is installed. If jq is not available, the script will fail with a cryptic error. Consider adding a check for required dependencies at the beginning of the script.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +109
# Spawn TurtleBot3 robot (both modes)
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(turtlebot3_gazebo_dir, "launch", "spawn_turtlebot3.launch.py")
),
launch_arguments={"x_pose": x_pose, "y_pose": y_pose}.items(),
condition=IfCondition(headless),
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says "Spawn TurtleBot3 robot (both modes)" but the code only spawns in headless mode (condition=IfCondition(headless)). This is actually correct since turtlebot3_world.launch.py already spawns the robot in GUI mode, but the comment is misleading. Consider updating the comment to clarify that spawning only happens explicitly in headless mode, as GUI mode already includes it.

Copilot uses AI. Check for mistakes.
# Publish to topic (see examples above)
curl -X POST http://localhost:8080/api/v1/topics/publish ...
# Clear a specific fault
curl -X DELETE http://localhost:8080/api/v1/apps/diagnostic_bridge/faults/TURTLEBOT3_NODE
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app ID should be "diagnostic-bridge" (with hyphens) to match the manifest definition, not "diagnostic_bridge" (with underscores).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sync Turtlebot demo with ros2_medkit changes

3 participants