From 44bcbf06b6b8beabab82c530a388795985adcbd3 Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Tue, 26 May 2026 13:47:20 +0200 Subject: [PATCH 1/3] ci: swap Rolling for Lyrical Luth (Ubuntu 26.04) across matrix and docs ROS 2 Lyrical Luth is the new LTS released May 2026, supported until May 2031, targeting Ubuntu 26.04 Resolute Raccoon (Python 3.14, gcc 15, rclcpp 32). Drop the Rolling matrix entry in favour of Lyrical so all three tested distros are LTS. CI matrix: rolling/noble -> lyrical/resolute in ci.yml, docker-publish.yml, opcua-plugin.yml. Jazzy/noble and Humble/jammy entries unchanged. ROS2MedkitCompat.cmake docstrings extended to cover Lyrical (rclcpp 32+, yaml_cpp_vendor target export, ament_target_dependencies removal in ament_cmake 2.8.5+). Runtime detection already handles the new distro; no logic change needed. Docs (README, CONTRIBUTING, QUALITY_DECLARATION, installation, troubleshooting, tutorials, copilot-instructions, cmake/gateway design docs) updated with correct Ubuntu codename pairings (Resolute=26.04, Noble=24.04, Jammy=22.04). C++ comments and source comments swapped Rolling -> Lyrical where the behaviour carries forward; historical attribution preserved as "on Lyrical (originally observed on Rolling)" or "Rolling/Lyrical" where the bug was first reproduced on Rolling. snapshot_capture.cpp C++20 aggregate-init comment updated for gcc 15 (Lyrical). closes #404 --- .github/copilot-instructions.md | 4 +-- .github/workflows/ci.yml | 24 ++++++++++-------- .github/workflows/docker-publish.yml | 2 +- .github/workflows/opcua-plugin.yml | 10 ++++---- CONTRIBUTING.md | 2 +- QUALITY_DECLARATION.md | 8 +++--- README.md | 8 +++--- docs/installation.rst | 16 ++++++------ docs/troubleshooting.rst | 2 +- docs/tutorials/docker.rst | 4 +-- docs/tutorials/plugin-system.rst | 2 +- scripts/check_no_naked_subscriptions.sh | 3 ++- src/ros2_medkit_cmake/README.md | 4 +-- .../cmake/ROS2MedkitCompat.cmake | 25 +++++++++++-------- src/ros2_medkit_cmake/design/index.rst | 4 +-- .../ros2_medkit_beacon_common/CMakeLists.txt | 6 ++--- .../ros2_medkit_param_beacon/CMakeLists.txt | 6 ++--- .../src/param_beacon_plugin.cpp | 11 ++++---- .../ros2_medkit_topic_beacon/CMakeLists.txt | 6 ++--- .../src/topic_beacon_plugin.cpp | 13 +++++----- .../src/snapshot_capture.cpp | 4 +-- src/ros2_medkit_gateway/CMakeLists.txt | 2 +- src/ros2_medkit_gateway/README.md | 2 +- .../design/ros2_subscription_architecture.rst | 13 +++++----- .../compat/generic_client_compat.hpp | 2 +- .../ros2_subscription_executor.hpp | 2 +- src/ros2_medkit_gateway/src/main.cpp | 4 +-- .../test_openapi_response_drift.test.py | 6 ++--- .../ros2_medkit_graph_provider/CMakeLists.txt | 6 ++--- .../src/graph_provider_plugin.cpp | 14 +++++------ .../ros2_medkit_opcua/CMakeLists.txt | 6 ++--- .../ros2_medkit_opcua/src/opcua_client.cpp | 2 +- .../CMakeLists.txt | 6 ++--- src/ros2_medkit_serialization/CMakeLists.txt | 2 +- 34 files changed, 121 insertions(+), 110 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0202ae4a..f652b838 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,7 +4,7 @@ **ros2_medkit** is a ROS 2 diagnostics gateway that exposes ROS 2 system information via a RESTful HTTP API aligned with the **SOVD (Service-Oriented Vehicle Diagnostics)** specification. It models robots as a diagnostic entity tree: **Area -> Component -> App**, with optional **Function** groupings. -**Tech Stack**: C++17, ROS 2 Jazzy/Humble/Rolling, Ubuntu 24.04/22.04 +**Tech Stack**: C++17, ROS 2 Jazzy/Humble/Lyrical Luth, Ubuntu 26.04/24.04/22.04 ## Package Structure @@ -294,7 +294,7 @@ Every code change must include corresponding tests. A feature without tests is n - **Flag** new `.cpp` source files under `src/core/` that aren't picked up by `gateway_core`'s `GLOB_RECURSE` source list, or new ROS-adapter `.cpp` files that aren't added to the `gateway_ros2` STATIC library target in CMakeLists.txt. - **Flag** any `#include ` or message-package include in a file under `core/` - the layer must stay middleware-neutral. The `gateway_core_purity` linter and `test_gateway_core_smoke` link test enforce this; do not paper over their failures. - **Flag** new test targets that don't link to `gateway_ros2` (the default), unless the test is intentionally a core-only smoke test linking `gateway_core` directly. -- **Flag** use of `ament_target_dependencies()` - use `medkit_target_dependencies()` instead (removed in Rolling). +- **Flag** use of `ament_target_dependencies()` - use `medkit_target_dependencies()` instead (deprecated in Kilted, removed in ament_cmake 2.8.5+ which Lyrical ships). - **Flag** direct `find_package(yaml-cpp)` or `find_package(httplib)` - use `medkit_find_yaml_cpp()` / `medkit_find_cpp_httplib()` for multi-distro compatibility. ### Documentation diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a34a9c3..ec26d728 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ jobs: include: - ros_distro: humble os_image: ubuntu:jammy - - ros_distro: rolling - os_image: ubuntu:noble + - ros_distro: lyrical + os_image: ubuntu:resolute container: image: ${{ matrix.os_image }} timeout-minutes: 60 @@ -58,11 +58,12 @@ jobs: fi source /opt/ros/${{ matrix.ros_distro }}/setup.bash rosdep update - # Linters (clang-tidy / clang-format) are gated to the Jazzy lint job - # in quality.yml, but multiple package.xml files still list them as - # . Their rosdep keys are not registered for noble - # (Rolling), which breaks rosdep install on that runner. Skip them - # on every distro this workflow targets - the linters never run here. + # Linters (clang-tidy / clang-format) only run in the Jazzy quality + # job (quality.yml). Multiple package.xml files still list them as + # , so we skip the rosdep keys here to keep build-and- + # test runners from pulling in linter packages they never use. Also + # defensive against transient binary-deb gaps on newly-released + # distros. rosdep install --from-paths src --ignore-src -y \ --skip-keys "ament_cmake_clang_tidy ament_cmake_clang_format" @@ -85,10 +86,11 @@ jobs: # FastRTPS 2.6 on Humble has a known use-after-free in the # discovery-teardown path (EDP::unpairWriterProxy) that segfaults # peer nodes when the gateway shuts down, so we force CycloneDDS - # there. Rolling + Jazzy ship a newer FastRTPS without that bug - # and hit a separate iceoryx-shared-memory crash under CycloneDDS - # during shutdown ("string capacity was zero for allocated data"), - # so on those distros we keep the default FastRTPS. + # there. Lyrical ships a newer FastRTPS without that bug and hits + # a separate iceoryx-shared-memory crash under CycloneDDS during + # shutdown ("string capacity was zero for allocated data"), so on + # Lyrical we keep the default FastRTPS. (Jazzy still uses + # CycloneDDS - see jazzy-test job below for its rationale.) RMW_IMPLEMENTATION: ${{ matrix.ros_distro == 'humble' && 'rmw_cyclonedds_cpp' || '' }} run: | source /opt/ros/${{ matrix.ros_distro }}/setup.bash diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 8587fa30..8743b44d 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - ros_distro: [jazzy, humble, rolling] + ros_distro: [jazzy, humble, lyrical] steps: - name: Checkout repository diff --git a/.github/workflows/opcua-plugin.yml b/.github/workflows/opcua-plugin.yml index 9c321ad9..bfaf1399 100644 --- a/.github/workflows/opcua-plugin.yml +++ b/.github/workflows/opcua-plugin.yml @@ -43,9 +43,9 @@ jobs: os_image: ubuntu:jammy - ros_distro: jazzy os_image: ubuntu:noble - - ros_distro: rolling - os_image: ubuntu:noble - continue-on-error: ${{ matrix.ros_distro == 'rolling' }} + - ros_distro: lyrical + os_image: ubuntu:resolute + continue-on-error: ${{ matrix.ros_distro == 'lyrical' }} container: image: ${{ matrix.os_image }} timeout-minutes: 60 @@ -84,8 +84,8 @@ jobs: source /opt/ros/${{ matrix.ros_distro }}/setup.bash rosdep update # Skip nav2_msgs (vda5050_agent declares it; not available on all - # distros) and the linter rosdep keys. The clang_format / clang_tidy - # keys are not registered for noble (Rolling), and the upstream + # distros) and the linter rosdep keys. Linters only run in the Jazzy + # quality job, so we don't need them installed here. The upstream # medkit packages have already been switched to QUIET + FOUND for # those find_package calls so the build degrades gracefully without # the linter packages installed. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad6b2093..4df3f251 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,7 +107,7 @@ Open `coverage_html/index.html` in your browser. #### CI/CD -All PRs are tested on Ubuntu 24.04 (Jazzy) with parallel lint + test jobs, plus Humble and Rolling (allowed to fail). Coverage is uploaded to Codecov on push to main. All CI jobs use ccache. +All PRs are tested on Ubuntu 24.04 (Jazzy) with parallel lint + test jobs, plus Humble and Lyrical Luth. Coverage is uploaded to Codecov on push to main. All CI jobs use ccache. ### Pull Request Checklist diff --git a/QUALITY_DECLARATION.md b/QUALITY_DECLARATION.md index 6b276e7c..558ff4e6 100644 --- a/QUALITY_DECLARATION.md +++ b/QUALITY_DECLARATION.md @@ -86,7 +86,7 @@ GitHub Copilot code review is used in addition to human review. All pull requests must pass CI before merging: -- **Build & Test job:** Full build + unit/integration tests on Ubuntu Noble / ROS 2 Jazzy, Ubuntu Jammy / ROS 2 Humble, and Ubuntu Noble / ROS 2 Rolling (best-effort, allow-failure). Linter tests on Jazzy only +- **Build & Test job:** Full build + unit/integration tests on Ubuntu Noble / ROS 2 Jazzy, Ubuntu Jammy / ROS 2 Humble, and Ubuntu Resolute / ROS 2 Lyrical Luth. Linter tests on Jazzy only - **Coverage job:** Debug build with coverage. Reports are generated for all PRs as artifacts and uploaded to [Codecov](https://codecov.io/gh/selfpatch/ros2_medkit) on pushes to `main` - Linting enforced: `clang-format`, `clang-tidy` via `ament_lint_auto` @@ -203,9 +203,9 @@ Linter tests are enforced in CI on every pull request. - **Ubuntu 24.04 (Noble)** with **ROS 2 Jazzy** (primary) - **Ubuntu 22.04 (Jammy)** with **ROS 2 Humble** -- **Ubuntu 24.04 (Noble)** with **ROS 2 Rolling** (experimental, best-effort) +- **Ubuntu 26.04 (Resolute Raccoon)** with **ROS 2 Lyrical Luth** (newest LTS, released May 2026) -Jazzy and Humble are the Tier 1 platforms per [REP-2000](https://www.ros.org/reps/rep-2000.html) and are tested in CI. Rolling is tested as best-effort (allow-failure) for forward-compatibility. +Jazzy and Humble are Tier 1 LTS platforms per [REP-2000](https://www.ros.org/reps/rep-2000.html); Lyrical Luth is the newest LTS (May 2026) and is also tested in CI. --- @@ -234,7 +234,7 @@ Security issues can be reported via GitHub Security Advisories on the | Feature tests | Met | 65 tests across unit + integration | | Coverage | Met | 75% line coverage | | Linting | Met | clang-format, clang-tidy, ament_lint | -| Platform support | Met | Ubuntu Noble / ROS 2 Jazzy + Ubuntu Jammy / ROS 2 Humble + Rolling (best-effort) | +| Platform support | Met | Ubuntu Noble / ROS 2 Jazzy + Ubuntu Jammy / ROS 2 Humble + Ubuntu Resolute / ROS 2 Lyrical Luth | | Security policy | Met | REP-2006 compliant | **Caveat:** Version is 0.3.0 (pre-1.0.0, requirement 1.ii). The REST API is versioned (`/api/v1/`) diff --git a/README.md b/README.md index 92d02fab..dcb600d5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![ROS 2 Jazzy](https://img.shields.io/badge/ROS%202-Jazzy-blue)](https://docs.ros.org/en/jazzy/) [![ROS 2 Humble](https://img.shields.io/badge/ROS%202-Humble-blue)](https://docs.ros.org/en/humble/) -[![ROS 2 Rolling](https://img.shields.io/badge/ROS%202-Rolling-orange)](https://docs.ros.org/en/rolling/) +[![ROS 2 Lyrical Luth](https://img.shields.io/badge/ROS%202-Lyrical%20Luth-blue)](https://docs.ros.org/en/lyrical/) [![Discord](https://img.shields.io/badge/Discord-Join%20Us-7289DA?logo=discord&logoColor=white)](https://discord.gg/6CXPMApAyq) [![Quality Level 3](https://img.shields.io/badge/Quality-Level%203-yellow)](QUALITY_DECLARATION.md) @@ -42,7 +42,7 @@ cd selfpatch_demos/demos/turtlebot3_integration Open `http://localhost:3000` in your browser. You will see a TurtleBot3 with Nav2, organized into a browsable entity tree with live faults, topic data, and parameter access. -**Build from source** (ROS 2 Jazzy, Humble, or Rolling): +**Build from source** (ROS 2 Jazzy, Humble, or Lyrical Luth): ```bash source /opt/ros/jazzy/setup.bash # or humble - adjust for your distro @@ -148,8 +148,8 @@ This entity model follows the **SOVD (Service-Oriented Vehicle Diagnostics)** st ## 📋 Requirements -- **OS:** Ubuntu 24.04 LTS (Jazzy / Rolling) or Ubuntu 22.04 LTS (Humble) -- **ROS 2:** Jazzy Jalisco, Humble Hawksbill, or Rolling (experimental) +- **OS:** Ubuntu 26.04 LTS (Resolute Raccoon, for Lyrical Luth), Ubuntu 24.04 LTS (Noble, for Jazzy), or Ubuntu 22.04 LTS (Jammy, for Humble) +- **ROS 2:** Jazzy Jalisco, Humble Hawksbill, or Lyrical Luth (LTS, released May 2026) - **Compiler:** GCC 11+ (C++17 support) - **Build System:** colcon + ament_cmake diff --git a/docs/installation.rst b/docs/installation.rst index d5993934..941e67c2 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -2,7 +2,7 @@ Installation ============ This guide covers installation of ros2_medkit on Ubuntu 24.04 with ROS 2 Jazzy, -Ubuntu 22.04 with ROS 2 Humble, or Ubuntu 24.04 with ROS 2 Rolling. +Ubuntu 22.04 with ROS 2 Humble, or Ubuntu 26.04 with ROS 2 Lyrical Luth. System Requirements ------------------- @@ -14,25 +14,25 @@ System Requirements * - Requirement - Version * - Operating System - - Ubuntu 24.04 LTS (Noble) or Ubuntu 22.04 LTS (Jammy) + - Ubuntu 26.04 LTS (Resolute), Ubuntu 24.04 LTS (Noble), or Ubuntu 22.04 LTS (Jammy) * - ROS 2 Distribution - - Jazzy, Humble, or Rolling + - Jazzy, Humble, or Lyrical Luth * - C++ Compiler - GCC 11+ (C++17 support required) * - CMake - 3.22+ * - Python - - 3.10+ (Humble) / 3.12+ (Jazzy / Rolling) + - 3.10+ (Humble) / 3.12+ (Jazzy) / 3.14+ (Lyrical Luth) Prerequisites ------------- -**ROS 2 Jazzy, Humble, or Rolling** must be installed and sourced. Follow the official installation guide +**ROS 2 Jazzy, Humble, or Lyrical Luth** must be installed and sourced. Follow the official installation guide for your distribution: - Jazzy: https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html - Humble: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html -- Rolling: https://docs.ros.org/en/rolling/Installation/Ubuntu-Install-Debs.html +- Lyrical Luth: https://docs.ros.org/en/lyrical/Installation/Ubuntu-Install-Debs.html .. note:: @@ -136,8 +136,8 @@ ROS 2 distributions: # Humble docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-humble:latest - # Rolling - docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-rolling:latest + # Lyrical Luth + docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-lyrical:latest The gateway will be available at http://localhost:8080/api/v1/health. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 29bddb6c..bdaf2358 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -219,7 +219,7 @@ parameter changes) only happen when explicitly requested via the API. **Q: Can I use ros2_medkit with ROS 1?** -No. ros2_medkit requires ROS 2 (Jazzy, Humble, or Rolling). For ROS 1 systems, consider using +No. ros2_medkit requires ROS 2 (Jazzy, Humble, or Lyrical Luth). For ROS 1 systems, consider using the ``ros1_bridge`` and running ros2_medkit on the ROS 2 side. **Q: Is ros2_medkit production-ready?** diff --git a/docs/tutorials/docker.rst b/docs/tutorials/docker.rst index 62924868..8c51d566 100644 --- a/docs/tutorials/docker.rst +++ b/docs/tutorials/docker.rst @@ -33,8 +33,8 @@ Images are available for all supported ROS 2 distributions: - ``ghcr.io/selfpatch/ros2_medkit-jazzy:latest`` * - Humble - ``ghcr.io/selfpatch/ros2_medkit-humble:latest`` - * - Rolling - - ``ghcr.io/selfpatch/ros2_medkit-rolling:latest`` + * - Lyrical Luth + - ``ghcr.io/selfpatch/ros2_medkit-lyrical:latest`` Each image includes the gateway and all open-core packages: diff --git a/docs/tutorials/plugin-system.rst b/docs/tutorials/plugin-system.rst index 00195619..eb0289cf 100644 --- a/docs/tutorials/plugin-system.rst +++ b/docs/tutorials/plugin-system.rst @@ -271,7 +271,7 @@ providing access to gateway data and utilities: ``create_generic_subscription()``, or ``create_callback_group()`` directly on this node. Issue #375 showed that concurrent rcl mutations on the gateway node race its internal hash map and - SIGSEGV under load on Rolling. The regression gate in + SIGSEGV under load on Rolling/Lyrical. The regression gate in ``scripts/check_no_naked_subscriptions.sh`` is run in CI and will fail PRs that add such calls outside the allowlist. Use ``ros2_medkit_gateway::ros2_common::Ros2SubscriptionSlot::create_typed`` diff --git a/scripts/check_no_naked_subscriptions.sh b/scripts/check_no_naked_subscriptions.sh index 38f0309a..57c64296 100755 --- a/scripts/check_no_naked_subscriptions.sh +++ b/scripts/check_no_naked_subscriptions.sh @@ -5,7 +5,8 @@ # callback-group creation APIs from gateway and fault_manager code outside # `ros2_common/` is forbidden because it bypasses Ros2SubscriptionExecutor's # serial worker (or fault_manager's LockedSubscriptionGuard) and reintroduces -# the rcl hash-map race that triggered SIGSEGV on Rolling. +# the rcl hash-map race that triggered SIGSEGV on Rolling (still applicable +# on Lyrical and any future distro that ships the same rcl hash-map code). # # Callers in the gateway must go through: # ros2_medkit_gateway::ros2_common::Ros2SubscriptionSlot::create_typed / create_generic diff --git a/src/ros2_medkit_cmake/README.md b/src/ros2_medkit_cmake/README.md index 7f5bb502..eb28abdf 100644 --- a/src/ros2_medkit_cmake/README.md +++ b/src/ros2_medkit_cmake/README.md @@ -9,7 +9,7 @@ build acceleration, and centralized linting configuration across all packages. |--------|-------------| | `ROS2MedkitCcache.cmake` | Auto-detect and configure ccache with PCH-aware sloppiness settings | | `ROS2MedkitLinting.cmake` | Centralized clang-tidy configuration (opt-in locally, mandatory in CI) | -| `ROS2MedkitCompat.cmake` | Multi-distro compatibility shims for ROS 2 Humble, Jazzy, and Rolling | +| `ROS2MedkitCompat.cmake` | Multi-distro compatibility shims for ROS 2 Humble, Jazzy, and Lyrical Luth | ### ROS2MedkitCompat @@ -17,7 +17,7 @@ Resolves dependency differences across ROS 2 distributions: - `medkit_find_yaml_cpp()` - Finds yaml-cpp (namespaced targets on Jazzy, manual fallback on Humble) - `medkit_find_cpp_httplib()` - Finds cpp-httplib >= 0.14 via pkg-config, CMake config, or vendored fallback (`VENDORED_DIR` param) -- `medkit_target_dependencies()` - Drop-in replacement for `ament_target_dependencies` (removed on Rolling) +- `medkit_target_dependencies()` - Drop-in replacement for `ament_target_dependencies` (removed on Lyrical) - `medkit_detect_compat_defs()` / `medkit_apply_compat_defs()` - Compile definitions for version-specific APIs ## Usage diff --git a/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake b/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake index bcb7f5c8..8825ef84 100644 --- a/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake +++ b/src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake @@ -17,7 +17,7 @@ # ============================================================================= # # Centralizes all dependency resolution workarounds for supporting multiple -# ROS 2 distributions (Humble, Jazzy, Rolling) in a single place. +# ROS 2 distributions (Humble, Jazzy, Lyrical) in a single place. # # Usage (in each package's CMakeLists.txt): # find_package(ros2_medkit_cmake REQUIRED) @@ -31,7 +31,7 @@ # medkit_target_dependencies(target ...) - Drop-in ament_target_dependencies replacement # # Variables set by medkit_detect_compat_defs(): -# MEDKIT_RCLCPP_VERSION_MAJOR — integer (e.g., 16 for Humble, 28 for Jazzy) +# MEDKIT_RCLCPP_VERSION_MAJOR — integer (16=Humble, 28=Jazzy, 32+=Lyrical) # MEDKIT_ROSBAG2_OLD_TIMESTAMP — ON if rosbag2_storage < 0.22.0 (Humble) # @@ -40,9 +40,11 @@ include_guard(GLOBAL) # --------------------------------------------------------------------------- # medkit_find_yaml_cpp() # --------------------------------------------------------------------------- -# Jazzy's yaml_cpp_vendor exports a namespaced yaml-cpp::yaml-cpp cmake target. -# Humble's yaml_cpp_vendor bundles yaml-cpp but does NOT export the cmake target. -# This macro creates an IMPORTED INTERFACE target when find_package doesn't. +# Jazzy's and Lyrical's yaml_cpp_vendor export a namespaced yaml-cpp::yaml-cpp +# cmake target (Jazzy directly; Lyrical via its Findyaml-cpp.cmake module that +# aliases the upstream yaml-cpp 0.8+ target). Humble's yaml_cpp_vendor bundles +# yaml-cpp but does NOT export the cmake target. This macro creates an IMPORTED +# INTERFACE target when find_package doesn't. # # Prerequisite: find_package(yaml_cpp_vendor REQUIRED) must be called before. # --------------------------------------------------------------------------- @@ -120,7 +122,7 @@ endmacro() # Call AFTER find_package(rclcpp) and optionally find_package(rosbag2_storage). # # Sets: -# MEDKIT_RCLCPP_VERSION_MAJOR — integer (16=Humble, 21+=Iron, 28+=Jazzy) +# MEDKIT_RCLCPP_VERSION_MAJOR — integer (16=Humble, 21+=Iron, 28+=Jazzy, 32+=Lyrical) # MEDKIT_ROSBAG2_OLD_TIMESTAMP — ON if rosbag2_storage < 0.22.0 (Humble) # --------------------------------------------------------------------------- macro(medkit_detect_compat_defs) @@ -166,11 +168,14 @@ endfunction() # --------------------------------------------------------------------------- # medkit_target_dependencies(target [PUBLIC|PRIVATE|INTERFACE] dep1 dep2 ...) # --------------------------------------------------------------------------- -# Drop-in replacement for ament_target_dependencies that works on Rolling -# (where ament_target_dependencies was removed from ament_cmake). +# Drop-in replacement for ament_target_dependencies that works on Lyrical +# (ament_target_dependencies was deprecated in Kilted / ament_cmake 2.7.3 +# and removed in ament_cmake 2.8.5+, which Lyrical ships). # # On Humble/Jazzy: delegates to ament_target_dependencies (available). -# On Rolling: uses target_link_libraries with ${dep_TARGETS}. +# On Lyrical: uses target_link_libraries with ${dep_TARGETS}. +# The branch is selected at runtime via if(COMMAND ament_target_dependencies) +# so any future distro keeps working regardless of where the removal lands. # # When no visibility keyword (PUBLIC/PRIVATE/INTERFACE) is passed, the macro # uses the plain target_link_libraries signature. This avoids conflicts with @@ -185,7 +190,7 @@ macro(medkit_target_dependencies target) if(COMMAND ament_target_dependencies) ament_target_dependencies(${target} ${ARGN}) else() - # Rolling fallback: resolve dependency targets explicitly. + # Lyrical fallback: resolve dependency targets explicitly. # # CMake forbids mixing the "plain" and "keyword" (PUBLIC/PRIVATE/INTERFACE) # signatures of target_link_libraries on the same target. diff --git a/src/ros2_medkit_cmake/design/index.rst b/src/ros2_medkit_cmake/design/index.rst index 90741d3d..f7981f98 100644 --- a/src/ros2_medkit_cmake/design/index.rst +++ b/src/ros2_medkit_cmake/design/index.rst @@ -41,7 +41,7 @@ The package provides four CMake modules installed to the ament index: - ``medkit_find_cpp_httplib()`` - Finds cpp-httplib >= 0.14 via pkg-config, cmake config, or vendored fallback (``VENDORED_DIR`` param) - ``medkit_detect_compat_defs()`` - Detects rclcpp and rosbag2 versions, sets ``MEDKIT_RCLCPP_VERSION_MAJOR`` and ``MEDKIT_ROSBAG2_OLD_TIMESTAMP`` - ``medkit_apply_compat_defs(target)`` - Applies compile definitions based on detected versions - - ``medkit_target_dependencies(target ...)`` - Drop-in replacement for ``ament_target_dependencies`` that also works on Rolling (where ``ament_target_dependencies`` was removed) + - ``medkit_target_dependencies(target ...)`` - Drop-in replacement for ``ament_target_dependencies`` that also works on Lyrical (where ``ament_target_dependencies`` was removed) Design Decisions ---------------- @@ -60,5 +60,5 @@ Multi-Distro Strategy Rather than maintaining separate branches per ROS 2 distribution, the compat module detects version numbers at configure time and adapts. This keeps a single -source tree building on Humble, Jazzy, and Rolling without ``#ifdef`` proliferation +source tree building on Humble, Jazzy, and Lyrical Luth without ``#ifdef`` proliferation in application code. diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt b/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt index b30e4190..28936579 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_beacon_common/CMakeLists.txt @@ -79,9 +79,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt index 556edce5..68d04f6b 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/CMakeLists.txt @@ -65,9 +65,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp index 93f2d87e..a00dc5ff 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_param_beacon/src/param_beacon_plugin.cpp @@ -35,9 +35,10 @@ using ros2_medkit_gateway::PluginContext; using ros2_medkit_gateway::SovdEntityType; ParameterBeaconPlugin::~ParameterBeaconPlugin() noexcept { - // On Rolling, ~rclcpp::Node can throw graph_listener::NodeNotFoundError - // once rclcpp::shutdown() has invalidated the context. An exception - // escaping a destructor calls std::terminate(), so swallow it here. + // On Lyrical (originally observed on Rolling), ~rclcpp::Node can throw + // graph_listener::NodeNotFoundError once rclcpp::shutdown() has invalidated + // the context. An exception escaping a destructor calls std::terminate(), + // so swallow it here. try { shutdown(); } catch (...) { @@ -157,8 +158,8 @@ void ParameterBeaconPlugin::shutdown() { backoff_counts_.clear(); skip_remaining_.clear(); } - // ~rclcpp::Node can throw graph_listener::NodeNotFoundError on Rolling - // when the context was already torn down by rclcpp::shutdown(). Swallow + // ~rclcpp::Node can throw graph_listener::NodeNotFoundError on Lyrical + // (and Rolling) when the context was already torn down by rclcpp::shutdown(). Swallow // it so the plugin_manager shutdown sequence (and the plugin destructor // that calls back into us) does not abort the process. try { diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt index b20a45ef..a9deaddf 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/CMakeLists.txt @@ -71,9 +71,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp index aa8ce05a..c133cb9c 100644 --- a/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp +++ b/src/ros2_medkit_discovery_plugins/ros2_medkit_topic_beacon/src/topic_beacon_plugin.cpp @@ -33,9 +33,10 @@ using ros2_medkit_gateway::PluginContext; using ros2_medkit_gateway::SovdEntityType; TopicBeaconPlugin::~TopicBeaconPlugin() noexcept { - // On Rolling, ~rclcpp::Subscription can throw graph_listener::NodeNotFoundError - // once rclcpp::shutdown() has invalidated the context. An exception - // escaping a destructor calls std::terminate(), so swallow it here. + // On Lyrical (originally observed on Rolling), ~rclcpp::Subscription can throw + // graph_listener::NodeNotFoundError once rclcpp::shutdown() has invalidated + // the context. An exception escaping a destructor calls std::terminate(), + // so swallow it here. try { shutdown(); } catch (...) { @@ -113,9 +114,9 @@ void TopicBeaconPlugin::shutdown() { if (shutdown_requested_.exchange(true)) { return; } - // ~rclcpp::Subscription can throw on Rolling when the rclcpp context - // was torn down before us; swallow so plugin_manager shutdown and the - // plugin destructor calling back into us do not abort the process. + // ~rclcpp::Subscription can throw on Lyrical (and Rolling) when the rclcpp + // context was torn down before us; swallow so plugin_manager shutdown and + // the plugin destructor calling back into us do not abort the process. try { subscription_.reset(); } catch (...) { diff --git a/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp b/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp index f833053d..625d0c04 100644 --- a/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp +++ b/src/ros2_medkit_fault_manager/src/snapshot_capture.cpp @@ -44,9 +44,9 @@ struct LockedSubscriptionGuard { // C++20 [dcl.init.aggr] disqualifies a class as an aggregate if it has // any user-declared constructors, including ``= delete`` ones (the rule // tightened from "user-provided" in C++17 to "user-declared" in C++20). - // Rolling's gcc 14 / libstdc++ enforces the C++20 wording even when + // Lyrical's gcc 15 / libstdc++ enforces the C++20 wording even when // CMAKE_CXX_STANDARD is 17, so brace-init ``LockedSubscriptionGuard{ - // &mtx, sub, cg}`` would fail to find a matching constructor on rolling. + // &mtx, sub, cg}`` would fail to find a matching constructor on Lyrical. // An explicit constructor sidesteps the aggregate-init rules entirely. LockedSubscriptionGuard(std::mutex * m, rclcpp::GenericSubscription::SharedPtr s, rclcpp::CallbackGroup::SharedPtr cg) : mtx(m), subscription(std::move(s)), callback_group(std::move(cg)) { diff --git a/src/ros2_medkit_gateway/CMakeLists.txt b/src/ros2_medkit_gateway/CMakeLists.txt index 171a5c09..5bbf59df 100644 --- a/src/ros2_medkit_gateway/CMakeLists.txt +++ b/src/ros2_medkit_gateway/CMakeLists.txt @@ -317,7 +317,7 @@ if(BUILD_TESTING) # Configure clang-format to only check our source files (not vendored). # ament_cmake_clang_format is intentionally only installed in the Jazzy - # quality job (ci.yml skips its rosdep key on Humble + Rolling), so use + # quality job (ci.yml skips its rosdep key in the build-and-test job), so use # QUIET + FOUND check instead of REQUIRED to gracefully degrade on the # build-and-test runners without breaking the build. find_package(ament_cmake_clang_format QUIET) diff --git a/src/ros2_medkit_gateway/README.md b/src/ros2_medkit_gateway/README.md index ff478cab..f8c7086c 100644 --- a/src/ros2_medkit_gateway/README.md +++ b/src/ros2_medkit_gateway/README.md @@ -1589,7 +1589,7 @@ All rcl subscription create/destroy calls must go through `Ros2SubscriptionSlot::create_typed` / `create_generic` (defined in `ros2_common/`). Calling `node->create_subscription()`, `create_generic_subscription()`, or `create_callback_group()` anywhere -else triggers the race from issue #375 and SIGSEGVs on Rolling under +else triggers the race from issue #375 and SIGSEGVs on Rolling/Lyrical under concurrent HTTP load. The regression gate is `scripts/check_no_naked_subscriptions.sh`. It diff --git a/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst b/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst index 918c95a6..54251a31 100644 --- a/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst +++ b/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst @@ -8,9 +8,10 @@ The gateway's original ``NativeTopicSampler`` created a short-lived ``rclcpp::GenericSubscription`` for every ``/data`` sample call. Under concurrent HTTP load, multiple cpp-httplib handler threads invoked ``Node::create_generic_subscription()`` on the same node, racing inside rcl's -internal hash map and corrupting its linked entries. The symptom was a Rolling -SIGSEGV in ``test_data_read`` (issue #375) and intermittent non-deterministic -crashes on sample-heavy deployments. +internal hash map and corrupting its linked entries. The symptom was a SIGSEGV +in ``test_data_read`` (issue #375, first reproduced on the Rolling distro that +later became Lyrical) and intermittent non-deterministic crashes on sample-heavy +deployments. This document describes the replacement architecture: a single-writer subscription executor, a RAII slot handle, and a per-topic pool. @@ -92,7 +93,7 @@ Public API (summary): Graph change detection uses the public ``rclcpp::Node::get_graph_event()`` API and a wall timer polling ``event->check_and_clear()`` on the subscription node. Internal ``GraphListener`` is intentionally avoided - it is not a stable -public API across Humble / Jazzy / Rolling. +public API across Humble / Jazzy / Lyrical Luth. Shutdown drains the queue: the worker processes any already-enqueued tasks so pending ``run_sync`` promises are fulfilled before the worker exits. Bounded @@ -226,8 +227,8 @@ executor:: node.reset(); // ~GatewayNode with executor still alive rclcpp::shutdown(); -``remove_node`` + explicit ``node.reset()`` are required on rolling / newer -jazzy: rclcpp aborts with ``Node ... needs to be associated with an executor`` +``remove_node`` + explicit ``node.reset()`` are required on Lyrical / newer +Jazzy: rclcpp aborts with ``Node ... needs to be associated with an executor`` if ``~GatewayNode`` touches a service client while stack-unwind has already destroyed the executor. diff --git a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp index e095b38c..a7a704ef 100644 --- a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp +++ b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/compat/generic_client_compat.hpp @@ -32,7 +32,7 @@ #include // Detect whether rclcpp::GenericClient is available. -// rclcpp/version.h exists in all supported distros (Humble, Jazzy, Rolling). +// rclcpp/version.h exists in all supported distros (Humble, Jazzy, Lyrical). #include #if defined(RCLCPP_VERSION_MAJOR) && RCLCPP_VERSION_MAJOR >= 21 diff --git a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp index aec60187..6cc7a240 100644 --- a/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp +++ b/src/ros2_medkit_gateway/include/ros2_medkit_gateway/ros2_common/ros2_subscription_executor.hpp @@ -303,7 +303,7 @@ class Ros2SubscriptionExecutor final { std::array graph_in_flight_{}; std::condition_variable graph_in_flight_cv_; - // Public rclcpp graph API - stable across Humble / Jazzy / Rolling + // Public rclcpp graph API - stable across Humble / Jazzy / Lyrical rclcpp::Event::SharedPtr graph_event_; // Dedicated auxiliary thread driving the watchdog and graph-event polling. diff --git a/src/ros2_medkit_gateway/src/main.cpp b/src/ros2_medkit_gateway/src/main.cpp index 06e64e94..b28f68b5 100644 --- a/src/ros2_medkit_gateway/src/main.cpp +++ b/src/ros2_medkit_gateway/src/main.cpp @@ -80,7 +80,7 @@ int main(int argc, char ** argv) { // Stand up the ROS 2 subscription executor + topic data provider. // Issue #375: all subscription create/destroy calls are funneled through the // serial worker owned by sub_exec, eliminating the rcl hash-map race that - // previously killed /data on Rolling when concurrent HTTP handler threads + // previously killed /data on Rolling (now Lyrical) when concurrent HTTP handler threads // created subscriptions on the same node. const auto exec_cfg = declare_executor_config(*node); const auto dp_cfg = declare_data_provider_config(*node); @@ -104,7 +104,7 @@ int main(int argc, char ** argv) { // Teardown order (issue #375): stack-unwind destructs executor before node // which leaves ~GatewayNode running against a dead executor. Newer rclcpp - // (rolling; recent jazzy patch releases) asserts 'node needs to be + // (Lyrical; recent Jazzy patch releases) asserts 'node needs to be // associated with an executor' and aborts with exit -6 when the managers' // shutdown paths touch service clients. Explicit teardown avoids that: // 1. detach the provider from GatewayNode so the managers stop using it diff --git a/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py b/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py index 4591ede2..aee3c2a9 100644 --- a/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py +++ b/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py @@ -52,9 +52,9 @@ import requests # Humble (Ubuntu 22.04) ships python3-jsonschema 3.2 which only has draft-7; -# Jazzy/Rolling (Ubuntu 24.04) ship 4.10+ with Draft202012. Prefer the newest -# draft for OpenAPI 3.1 alignment, fall back to Draft7 on Humble. The properties -# we validate (required, type, properties) behave identically across drafts. +# Jazzy (Ubuntu 24.04) / Lyrical Luth (Ubuntu 26.04) ship 4.10+ with Draft202012. +# Prefer the newest draft for OpenAPI 3.1 alignment, fall back to Draft7 on Humble. +# The properties we validate (required, type, properties) behave identically across drafts. try: from jsonschema.validators import Draft202012Validator as _Validator except ImportError: diff --git a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt index 1f4e0f3a..665ab812 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt +++ b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/CMakeLists.txt @@ -74,9 +74,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp index ad3cf0f4..7ad0cb52 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp +++ b/src/ros2_medkit_plugins/ros2_medkit_graph_provider/src/graph_provider_plugin.cpp @@ -318,10 +318,10 @@ nlohmann::json build_graph_document_for_apps(const std::string & function_id, } // namespace GraphProviderPlugin::~GraphProviderPlugin() noexcept { - // On Rolling, destroying rclcpp resources (Subscription, Node) after - // rclcpp::shutdown() has invalidated the context can throw - // graph_listener::NodeNotFoundError. An exception escaping a destructor - // calls std::terminate(), so swallow it here. + // On Lyrical (originally observed on Rolling), destroying rclcpp resources + // (Subscription, Node) after rclcpp::shutdown() has invalidated the context + // can throw graph_listener::NodeNotFoundError. An exception escaping a + // destructor calls std::terminate(), so swallow it here. try { shutdown(); } catch (...) { @@ -332,9 +332,9 @@ void GraphProviderPlugin::shutdown() { if (shutdown_requested_.exchange(true)) { return; } - // ~rclcpp::Subscription can throw on Rolling when the rclcpp context - // was torn down before us; swallow so plugin_manager shutdown and the - // plugin destructor calling back into us do not abort the process. + // ~rclcpp::Subscription can throw on Lyrical (and Rolling) when the rclcpp + // context was torn down before us; swallow so plugin_manager shutdown and + // the plugin destructor calling back into us do not abort the process. try { diagnostics_sub_.reset(); } catch (...) { diff --git a/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt b/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt index b2a4fcd3..d66c3ecc 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt +++ b/src/ros2_medkit_plugins/ros2_medkit_opcua/CMakeLists.txt @@ -133,9 +133,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp b/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp index 64850ac6..f26a13e5 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp +++ b/src/ros2_medkit_plugins/ros2_medkit_opcua/src/opcua_client.cpp @@ -44,7 +44,7 @@ inline rclcpp::Logger opcua_client_logger() { // Pre-gate for traces whose stream-build cost is non-trivial (e.g. per-arg // loops). RCLCPP_DEBUG_STREAM constructs the std::stringstream // unconditionally, so for hot paths we check the effective level first. -// Uses the rcutils-level API (available in Humble through Rolling) instead +// Uses the rcutils-level API (available in Humble through Lyrical) instead // of rclcpp::Logger::get_effective_level (Jazzy+ only). inline bool client_debug_enabled() { return rcutils_logging_logger_is_enabled_for("opcua.client", RCUTILS_LOG_SEVERITY_DEBUG); diff --git a/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt b/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt index 0e238b21..63db5912 100644 --- a/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt +++ b/src/ros2_medkit_plugins/ros2_medkit_sovd_service_interface/CMakeLists.txt @@ -73,9 +73,9 @@ if(BUILD_TESTING) ) ament_lint_auto_find_test_dependencies() - # ci.yml skips the ament_cmake_clang_format rosdep key on Humble + Rolling - # (linters only run in the Jazzy quality job), so QUIET + FOUND check - # avoids hard-failing on those runners. + # ci.yml skips the ament_cmake_clang_format rosdep key in the build-and-test + # job (linters only run in the Jazzy quality job), so QUIET + FOUND check + # avoids hard-failing when the package is not installed. find_package(ament_cmake_clang_format QUIET) if(ament_cmake_clang_format_FOUND) file(GLOB_RECURSE _format_files diff --git a/src/ros2_medkit_serialization/CMakeLists.txt b/src/ros2_medkit_serialization/CMakeLists.txt index d1ef6660..96d4aa2d 100644 --- a/src/ros2_medkit_serialization/CMakeLists.txt +++ b/src/ros2_medkit_serialization/CMakeLists.txt @@ -138,7 +138,7 @@ if(BUILD_TESTING) # Configure clang-format manually for non-vendored files only. # ament_cmake_clang_format is intentionally only installed in the Jazzy - # quality job (ci.yml skips its rosdep key on Humble + Rolling), so use + # quality job (ci.yml skips its rosdep key in the build-and-test job), so use # QUIET + FOUND check instead of REQUIRED to gracefully degrade on the # build-and-test runners without breaking the build. find_package(ament_cmake_clang_format QUIET) From aa47120172dbcaf5ed91db3bf47817f8b80098a3 Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Tue, 26 May 2026 14:03:21 +0200 Subject: [PATCH 2/3] docs(readme): shorten Lyrical badge label to match Jazzy/Humble style --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dcb600d5..71035605 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![ROS 2 Jazzy](https://img.shields.io/badge/ROS%202-Jazzy-blue)](https://docs.ros.org/en/jazzy/) [![ROS 2 Humble](https://img.shields.io/badge/ROS%202-Humble-blue)](https://docs.ros.org/en/humble/) -[![ROS 2 Lyrical Luth](https://img.shields.io/badge/ROS%202-Lyrical%20Luth-blue)](https://docs.ros.org/en/lyrical/) +[![ROS 2 Lyrical](https://img.shields.io/badge/ROS%202-Lyrical-blue)](https://docs.ros.org/en/lyrical/) [![Discord](https://img.shields.io/badge/Discord-Join%20Us-7289DA?logo=discord&logoColor=white)](https://discord.gg/6CXPMApAyq) [![Quality Level 3](https://img.shields.io/badge/Quality-Level%203-yellow)](QUALITY_DECLARATION.md) From 7e22a0a049c078bdde01f4cba05973d570d1ca70 Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Tue, 26 May 2026 14:34:31 +0200 Subject: [PATCH 3/3] docs: shorten 'Lyrical Luth'/'Resolute Raccoon' to codenames for consistency --- .github/copilot-instructions.md | 2 +- CONTRIBUTING.md | 2 +- QUALITY_DECLARATION.md | 8 ++++---- README.md | 4 ++-- docs/installation.rst | 12 ++++++------ docs/troubleshooting.rst | 2 +- docs/tutorials/docker.rst | 2 +- src/ros2_medkit_cmake/README.md | 2 +- src/ros2_medkit_cmake/design/index.rst | 2 +- .../design/ros2_subscription_architecture.rst | 2 +- .../features/test_openapi_response_drift.test.py | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index f652b838..3aeb0438 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,7 +4,7 @@ **ros2_medkit** is a ROS 2 diagnostics gateway that exposes ROS 2 system information via a RESTful HTTP API aligned with the **SOVD (Service-Oriented Vehicle Diagnostics)** specification. It models robots as a diagnostic entity tree: **Area -> Component -> App**, with optional **Function** groupings. -**Tech Stack**: C++17, ROS 2 Jazzy/Humble/Lyrical Luth, Ubuntu 26.04/24.04/22.04 +**Tech Stack**: C++17, ROS 2 Jazzy/Humble/Lyrical, Ubuntu 26.04/24.04/22.04 ## Package Structure diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4df3f251..deb93188 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,7 +107,7 @@ Open `coverage_html/index.html` in your browser. #### CI/CD -All PRs are tested on Ubuntu 24.04 (Jazzy) with parallel lint + test jobs, plus Humble and Lyrical Luth. Coverage is uploaded to Codecov on push to main. All CI jobs use ccache. +All PRs are tested on Ubuntu 24.04 (Jazzy) with parallel lint + test jobs, plus Humble and Lyrical. Coverage is uploaded to Codecov on push to main. All CI jobs use ccache. ### Pull Request Checklist diff --git a/QUALITY_DECLARATION.md b/QUALITY_DECLARATION.md index 558ff4e6..984074fb 100644 --- a/QUALITY_DECLARATION.md +++ b/QUALITY_DECLARATION.md @@ -86,7 +86,7 @@ GitHub Copilot code review is used in addition to human review. All pull requests must pass CI before merging: -- **Build & Test job:** Full build + unit/integration tests on Ubuntu Noble / ROS 2 Jazzy, Ubuntu Jammy / ROS 2 Humble, and Ubuntu Resolute / ROS 2 Lyrical Luth. Linter tests on Jazzy only +- **Build & Test job:** Full build + unit/integration tests on Ubuntu Noble / ROS 2 Jazzy, Ubuntu Jammy / ROS 2 Humble, and Ubuntu Resolute / ROS 2 Lyrical. Linter tests on Jazzy only - **Coverage job:** Debug build with coverage. Reports are generated for all PRs as artifacts and uploaded to [Codecov](https://codecov.io/gh/selfpatch/ros2_medkit) on pushes to `main` - Linting enforced: `clang-format`, `clang-tidy` via `ament_lint_auto` @@ -203,9 +203,9 @@ Linter tests are enforced in CI on every pull request. - **Ubuntu 24.04 (Noble)** with **ROS 2 Jazzy** (primary) - **Ubuntu 22.04 (Jammy)** with **ROS 2 Humble** -- **Ubuntu 26.04 (Resolute Raccoon)** with **ROS 2 Lyrical Luth** (newest LTS, released May 2026) +- **Ubuntu 26.04 (Resolute)** with **ROS 2 Lyrical** (newest LTS, released May 2026) -Jazzy and Humble are Tier 1 LTS platforms per [REP-2000](https://www.ros.org/reps/rep-2000.html); Lyrical Luth is the newest LTS (May 2026) and is also tested in CI. +Jazzy and Humble are Tier 1 LTS platforms per [REP-2000](https://www.ros.org/reps/rep-2000.html); Lyrical is the newest LTS (May 2026) and is also tested in CI. --- @@ -234,7 +234,7 @@ Security issues can be reported via GitHub Security Advisories on the | Feature tests | Met | 65 tests across unit + integration | | Coverage | Met | 75% line coverage | | Linting | Met | clang-format, clang-tidy, ament_lint | -| Platform support | Met | Ubuntu Noble / ROS 2 Jazzy + Ubuntu Jammy / ROS 2 Humble + Ubuntu Resolute / ROS 2 Lyrical Luth | +| Platform support | Met | Ubuntu Noble / ROS 2 Jazzy + Ubuntu Jammy / ROS 2 Humble + Ubuntu Resolute / ROS 2 Lyrical | | Security policy | Met | REP-2006 compliant | **Caveat:** Version is 0.3.0 (pre-1.0.0, requirement 1.ii). The REST API is versioned (`/api/v1/`) diff --git a/README.md b/README.md index 71035605..6beacae4 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ cd selfpatch_demos/demos/turtlebot3_integration Open `http://localhost:3000` in your browser. You will see a TurtleBot3 with Nav2, organized into a browsable entity tree with live faults, topic data, and parameter access. -**Build from source** (ROS 2 Jazzy, Humble, or Lyrical Luth): +**Build from source** (ROS 2 Jazzy, Humble, or Lyrical): ```bash source /opt/ros/jazzy/setup.bash # or humble - adjust for your distro @@ -148,7 +148,7 @@ This entity model follows the **SOVD (Service-Oriented Vehicle Diagnostics)** st ## 📋 Requirements -- **OS:** Ubuntu 26.04 LTS (Resolute Raccoon, for Lyrical Luth), Ubuntu 24.04 LTS (Noble, for Jazzy), or Ubuntu 22.04 LTS (Jammy, for Humble) +- **OS:** Ubuntu 26.04 LTS (Resolute, for Lyrical), Ubuntu 24.04 LTS (Noble, for Jazzy), or Ubuntu 22.04 LTS (Jammy, for Humble) - **ROS 2:** Jazzy Jalisco, Humble Hawksbill, or Lyrical Luth (LTS, released May 2026) - **Compiler:** GCC 11+ (C++17 support) - **Build System:** colcon + ament_cmake diff --git a/docs/installation.rst b/docs/installation.rst index 941e67c2..80626094 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -2,7 +2,7 @@ Installation ============ This guide covers installation of ros2_medkit on Ubuntu 24.04 with ROS 2 Jazzy, -Ubuntu 22.04 with ROS 2 Humble, or Ubuntu 26.04 with ROS 2 Lyrical Luth. +Ubuntu 22.04 with ROS 2 Humble, or Ubuntu 26.04 with ROS 2 Lyrical. System Requirements ------------------- @@ -16,23 +16,23 @@ System Requirements * - Operating System - Ubuntu 26.04 LTS (Resolute), Ubuntu 24.04 LTS (Noble), or Ubuntu 22.04 LTS (Jammy) * - ROS 2 Distribution - - Jazzy, Humble, or Lyrical Luth + - Jazzy, Humble, or Lyrical * - C++ Compiler - GCC 11+ (C++17 support required) * - CMake - 3.22+ * - Python - - 3.10+ (Humble) / 3.12+ (Jazzy) / 3.14+ (Lyrical Luth) + - 3.10+ (Humble) / 3.12+ (Jazzy) / 3.14+ (Lyrical) Prerequisites ------------- -**ROS 2 Jazzy, Humble, or Lyrical Luth** must be installed and sourced. Follow the official installation guide +**ROS 2 Jazzy, Humble, or Lyrical** must be installed and sourced. Follow the official installation guide for your distribution: - Jazzy: https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html - Humble: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html -- Lyrical Luth: https://docs.ros.org/en/lyrical/Installation/Ubuntu-Install-Debs.html +- Lyrical: https://docs.ros.org/en/lyrical/Installation/Ubuntu-Install-Debs.html .. note:: @@ -136,7 +136,7 @@ ROS 2 distributions: # Humble docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-humble:latest - # Lyrical Luth + # Lyrical docker run -p 8080:8080 ghcr.io/selfpatch/ros2_medkit-lyrical:latest The gateway will be available at http://localhost:8080/api/v1/health. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index bdaf2358..5f5057b1 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -219,7 +219,7 @@ parameter changes) only happen when explicitly requested via the API. **Q: Can I use ros2_medkit with ROS 1?** -No. ros2_medkit requires ROS 2 (Jazzy, Humble, or Lyrical Luth). For ROS 1 systems, consider using +No. ros2_medkit requires ROS 2 (Jazzy, Humble, or Lyrical). For ROS 1 systems, consider using the ``ros1_bridge`` and running ros2_medkit on the ROS 2 side. **Q: Is ros2_medkit production-ready?** diff --git a/docs/tutorials/docker.rst b/docs/tutorials/docker.rst index 8c51d566..61cbf9fb 100644 --- a/docs/tutorials/docker.rst +++ b/docs/tutorials/docker.rst @@ -33,7 +33,7 @@ Images are available for all supported ROS 2 distributions: - ``ghcr.io/selfpatch/ros2_medkit-jazzy:latest`` * - Humble - ``ghcr.io/selfpatch/ros2_medkit-humble:latest`` - * - Lyrical Luth + * - Lyrical - ``ghcr.io/selfpatch/ros2_medkit-lyrical:latest`` Each image includes the gateway and all open-core packages: diff --git a/src/ros2_medkit_cmake/README.md b/src/ros2_medkit_cmake/README.md index eb28abdf..8d2052f6 100644 --- a/src/ros2_medkit_cmake/README.md +++ b/src/ros2_medkit_cmake/README.md @@ -9,7 +9,7 @@ build acceleration, and centralized linting configuration across all packages. |--------|-------------| | `ROS2MedkitCcache.cmake` | Auto-detect and configure ccache with PCH-aware sloppiness settings | | `ROS2MedkitLinting.cmake` | Centralized clang-tidy configuration (opt-in locally, mandatory in CI) | -| `ROS2MedkitCompat.cmake` | Multi-distro compatibility shims for ROS 2 Humble, Jazzy, and Lyrical Luth | +| `ROS2MedkitCompat.cmake` | Multi-distro compatibility shims for ROS 2 Humble, Jazzy, and Lyrical | ### ROS2MedkitCompat diff --git a/src/ros2_medkit_cmake/design/index.rst b/src/ros2_medkit_cmake/design/index.rst index f7981f98..c21709c4 100644 --- a/src/ros2_medkit_cmake/design/index.rst +++ b/src/ros2_medkit_cmake/design/index.rst @@ -60,5 +60,5 @@ Multi-Distro Strategy Rather than maintaining separate branches per ROS 2 distribution, the compat module detects version numbers at configure time and adapts. This keeps a single -source tree building on Humble, Jazzy, and Lyrical Luth without ``#ifdef`` proliferation +source tree building on Humble, Jazzy, and Lyrical without ``#ifdef`` proliferation in application code. diff --git a/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst b/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst index 54251a31..df2dc0e1 100644 --- a/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst +++ b/src/ros2_medkit_gateway/design/ros2_subscription_architecture.rst @@ -93,7 +93,7 @@ Public API (summary): Graph change detection uses the public ``rclcpp::Node::get_graph_event()`` API and a wall timer polling ``event->check_and_clear()`` on the subscription node. Internal ``GraphListener`` is intentionally avoided - it is not a stable -public API across Humble / Jazzy / Lyrical Luth. +public API across Humble / Jazzy / Lyrical. Shutdown drains the queue: the worker processes any already-enqueued tasks so pending ``run_sync`` promises are fulfilled before the worker exits. Bounded diff --git a/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py b/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py index aee3c2a9..9fe9bac8 100644 --- a/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py +++ b/src/ros2_medkit_integration_tests/test/features/test_openapi_response_drift.test.py @@ -52,7 +52,7 @@ import requests # Humble (Ubuntu 22.04) ships python3-jsonschema 3.2 which only has draft-7; -# Jazzy (Ubuntu 24.04) / Lyrical Luth (Ubuntu 26.04) ship 4.10+ with Draft202012. +# Jazzy (Ubuntu 24.04) / Lyrical (Ubuntu 26.04) ship 4.10+ with Draft202012. # Prefer the newest draft for OpenAPI 3.1 alignment, fall back to Draft7 on Humble. # The properties we validate (required, type, properties) behave identically across drafts. try: