Skip to content

Commit 3f93d0e

Browse files
committed
feat(cpp_trees): make ros2_medkit dep optional
Add MANYMOVE_WITH_MEDKIT toggle (default OFF). When OFF the mixin and installFaultReporter() compile to no-ops, deps drop from CMake and package.xml. CI matrixes ON/OFF on humble and jazzy.
1 parent f02a179 commit 3f93d0e

7 files changed

Lines changed: 137 additions & 22 deletions

File tree

.github/workflows/ci.yml

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
ros_distro: [humble, jazzy]
17+
# with_medkit: ON exercises the medkit integration path (matches
18+
# selfpatch fork's primary use case); OFF guards the upstream-friendly
19+
# build for users who do not want the ros2_medkit overlay.
20+
with_medkit: ["ON", "OFF"]
21+
22+
name: build-and-test (${{ matrix.ros_distro }}, medkit=${{ matrix.with_medkit }})
1723

1824
container:
1925
image: ros:${{ matrix.ros_distro }}-ros-base
@@ -29,6 +35,7 @@ jobs:
2935
# Pin medkit to the rosdistro-released version so an upstream bump
3036
# does not silently break this CI. Update deliberately when bumping.
3137
MEDKIT_VERSION: "0.4.0-1"
38+
MANYMOVE_WITH_MEDKIT: ${{ matrix.with_medkit == 'ON' && '1' || '0' }}
3239

3340
steps:
3441
- name: Checkout repository
@@ -39,8 +46,9 @@ jobs:
3946
uses: actions/cache@v4
4047
with:
4148
path: /root/.ccache
42-
key: ccache-${{ matrix.ros_distro }}-${{ runner.os }}-v1
49+
key: ccache-${{ matrix.ros_distro }}-medkit-${{ matrix.with_medkit }}-${{ runner.os }}-v1
4350
restore-keys: |
51+
ccache-${{ matrix.ros_distro }}-medkit-${{ matrix.with_medkit }}-
4452
ccache-${{ matrix.ros_distro }}-
4553
4654
- name: Add Isaac ROS apt repository (Jazzy)
@@ -58,6 +66,17 @@ jobs:
5866
> /etc/apt/sources.list.d/isaac-ros.list
5967
apt-get update
6068
69+
- name: Install medkit debs
70+
if: matrix.with_medkit == 'ON'
71+
run: |
72+
set -e
73+
apt-get update
74+
apt-get install -y \
75+
ros-$ROS_DISTRO-ros2-medkit-fault-reporter=$MEDKIT_VERSION* \
76+
ros-$ROS_DISTRO-ros2-medkit-msgs=$MEDKIT_VERSION* \
77+
ros-$ROS_DISTRO-ros2-medkit-fault-manager=$MEDKIT_VERSION* \
78+
ros-$ROS_DISTRO-ros2-medkit-cmake=$MEDKIT_VERSION*
79+
6180
- name: Install build tooling
6281
run: |
6382
set -e
@@ -66,10 +85,6 @@ jobs:
6685
ccache \
6786
ros-$ROS_DISTRO-topic-based-ros2-control \
6887
python3-colcon-common-extensions python3-rosdep git \
69-
ros-$ROS_DISTRO-ros2-medkit-fault-reporter=$MEDKIT_VERSION* \
70-
ros-$ROS_DISTRO-ros2-medkit-msgs=$MEDKIT_VERSION* \
71-
ros-$ROS_DISTRO-ros2-medkit-fault-manager=$MEDKIT_VERSION* \
72-
ros-$ROS_DISTRO-ros2-medkit-cmake=$MEDKIT_VERSION* \
7388
ros-$ROS_DISTRO-moveit \
7489
ros-$ROS_DISTRO-ur \
7590
ros-$ROS_DISTRO-ur-moveit-config \
@@ -121,7 +136,8 @@ jobs:
121136
--event-handlers console_cohesion+ \
122137
--cmake-args \
123138
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
124-
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
139+
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
140+
-DMANYMOVE_WITH_MEDKIT=${{ matrix.with_medkit }}
125141
# Show ccache status after build
126142
ccache -s || true
127143

docs/FAULT_CODES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# manymove fault codes
22

33
This is the catalogue of fault codes emitted by `manymove_cpp_trees` BT action
4-
nodes via [`ros2_medkit_fault_reporter`](https://github.com/selfpatch/ros2_medkit).
4+
nodes via [`ros2_medkit_fault_reporter`](https://github.com/selfpatch/ros2_medkit)
5+
when built with `MANYMOVE_WITH_MEDKIT=ON` (see the package README for the
6+
build instructions). With the option OFF the same `reportFault()` call sites
7+
compile to no-ops and nothing is published.
58
Each entry below maps to one or more `reportFault()` call sites in the action
69
node sources; the source-of-truth string constants live in
710
`manymove_cpp_trees/include/manymove_cpp_trees/fault_codes.hpp`.

manymove_cpp_trees/CMakeLists.txt

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
1111
add_compile_options(-Wthread-safety)
1212
endif()
1313

14+
#--------------------------------------------------------------------
15+
# Build options
16+
#--------------------------------------------------------------------
17+
# ros2_medkit fault reporting is off by default to keep the upstream
18+
# build free of extra deps. Turn it on (-DMANYMOVE_WITH_MEDKIT=ON plus
19+
# MANYMOVE_WITH_MEDKIT=1 in the env for rosdep) to pull in the medkit
20+
# overlay; with it off, the FaultReporting mixin and installFaultReporter()
21+
# compile to no-ops so action nodes build unchanged.
22+
option(MANYMOVE_WITH_MEDKIT
23+
"Build with ros2_medkit fault reporting integration"
24+
OFF)
25+
1426
#--------------------------------------------------------------------
1527
# Dependencies
1628
#--------------------------------------------------------------------
@@ -32,8 +44,11 @@ find_package(std_msgs REQUIRED)
3244
find_package(simulation_interfaces REQUIRED)
3345
find_package(vision_msgs REQUIRED)
3446
find_package(rcpputils REQUIRED)
35-
find_package(ros2_medkit_fault_reporter REQUIRED)
36-
find_package(ros2_medkit_msgs REQUIRED)
47+
48+
if(MANYMOVE_WITH_MEDKIT)
49+
find_package(ros2_medkit_fault_reporter REQUIRED)
50+
find_package(ros2_medkit_msgs REQUIRED)
51+
endif()
3752

3853
#--------------------------------------------------------------------
3954
# Library with all BT helper nodes
@@ -59,9 +74,17 @@ ament_target_dependencies(manymove_cpp_trees_lib
5974
manymove_planner manymove_object_manager
6075
trajectory_msgs geometry_msgs tf2 tf2_ros tf2_geometry_msgs std_srvs manymove_msgs control_msgs
6176
std_msgs simulation_interfaces vision_msgs rcpputils
62-
ros2_medkit_fault_reporter ros2_medkit_msgs
6377
)
6478

79+
if(MANYMOVE_WITH_MEDKIT)
80+
ament_target_dependencies(manymove_cpp_trees_lib
81+
ros2_medkit_fault_reporter ros2_medkit_msgs)
82+
# PUBLIC so consumers (bt_client_* execs, tests) inherit the define and
83+
# pick the medkit-enabled branches in fault_reporting.hpp /
84+
# main_imports_helper.hpp without each target having to set it again.
85+
target_compile_definitions(manymove_cpp_trees_lib PUBLIC MANYMOVE_WITH_MEDKIT)
86+
endif()
87+
6588
#--------------------------------------------------------------------
6689
# Helper macro to create BT-client executables
6790
#--------------------------------------------------------------------
@@ -75,8 +98,12 @@ macro(bt_client_exec NAME)
7598
manymove_planner manymove_object_manager
7699
trajectory_msgs tf2 std_srvs manymove_msgs control_msgs
77100
std_msgs simulation_interfaces rcpputils
78-
ros2_medkit_fault_reporter ros2_medkit_msgs
79101
)
102+
103+
if(MANYMOVE_WITH_MEDKIT)
104+
ament_target_dependencies(${NAME}
105+
ros2_medkit_fault_reporter ros2_medkit_msgs)
106+
endif()
80107
endmacro()
81108

82109
bt_client_exec(bt_client)
@@ -131,9 +158,12 @@ ament_export_dependencies(
131158
manymove_planner manymove_object_manager
132159
trajectory_msgs tf2 tf2_ros tf2_geometry_msgs std_srvs manymove_msgs control_msgs
133160
std_msgs simulation_interfaces vision_msgs rcpputils
134-
ros2_medkit_fault_reporter ros2_medkit_msgs
135161
)
136162

163+
if(MANYMOVE_WITH_MEDKIT)
164+
ament_export_dependencies(ros2_medkit_fault_reporter ros2_medkit_msgs)
165+
endif()
166+
137167
if(BUILD_TESTING)
138168
find_package(ament_lint_auto REQUIRED)
139169
find_package(ament_cmake_uncrustify REQUIRED)
@@ -152,8 +182,11 @@ if(BUILD_TESTING)
152182
rclcpp rclcpp_action behaviortree_cpp_v3
153183
manymove_planner manymove_object_manager
154184
trajectory_msgs geometry_msgs tf2 tf2_ros tf2_geometry_msgs std_srvs manymove_msgs control_msgs
155-
std_msgs simulation_interfaces vision_msgs rcpputils
156-
ros2_medkit_fault_reporter ros2_medkit_msgs)
185+
std_msgs simulation_interfaces vision_msgs rcpputils)
186+
if(MANYMOVE_WITH_MEDKIT)
187+
ament_target_dependencies(${target}
188+
ros2_medkit_fault_reporter ros2_medkit_msgs)
189+
endif()
157190
endif()
158191
endfunction()
159192

@@ -184,8 +217,10 @@ if(BUILD_TESTING)
184217
manymove_cpp_trees_add_gtest(test_bt_integration
185218
test/test_bt_integration.cpp)
186219

187-
manymove_cpp_trees_add_gtest(test_fault_reporting
188-
test/test_fault_reporting.cpp)
220+
if(MANYMOVE_WITH_MEDKIT)
221+
manymove_cpp_trees_add_gtest(test_fault_reporting
222+
test/test_fault_reporting.cpp)
223+
endif()
189224
endif()
190225

191226
ament_package()

manymove_cpp_trees/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@ Each executable spins the BT factory, registers the custom nodes, and runs the `
4242
- Control and runtime messaging: `rclcpp`, `rclcpp_action`, `control_msgs`, `std_msgs`, `std_srvs`, `topic_based_ros2_control`
4343
- Simulation and perception bridges: `simulation_interfaces`, `vision_msgs`
4444

45+
## Optional: ros2_medkit fault reporting
46+
The package can emit structured fault events via
47+
[`ros2_medkit`](https://github.com/selfpatch/ros2_medkit) when built with
48+
`MANYMOVE_WITH_MEDKIT=ON`. With the option OFF (default) the action nodes
49+
build with no extra dependencies and every `reportFault()` call compiles
50+
to a no-op. To enable:
51+
52+
```bash
53+
export MANYMOVE_WITH_MEDKIT=1 # for rosdep
54+
rosdep install --from-paths src --ignore-src -y
55+
colcon build --cmake-args -DMANYMOVE_WITH_MEDKIT=ON # for the build
56+
```
57+
58+
See [`docs/FAULT_CODES.md`](../docs/FAULT_CODES.md) for the catalogue.
59+
4560
## Notes
4661
- Robot safety mechanisms (stop buttons, workspace supervision) must be handled externally.
4762
- Review the main README for project-wide disclaimers, contribution guidance, and licensing details.

manymove_cpp_trees/include/manymove_cpp_trees/fault_reporting.hpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
#include <memory>
3535
#include <string>
3636

37+
#ifdef MANYMOVE_WITH_MEDKIT
3738
#include <ros2_medkit_fault_reporter/fault_reporter.hpp>
3839
#include <ros2_medkit_msgs/msg/fault.hpp>
40+
#endif
3941

4042
namespace manymove_cpp_trees
4143
{
@@ -45,13 +47,23 @@ namespace manymove_cpp_trees
4547
// main_imports_helper.hpp.
4648
inline constexpr char kFaultReporterBlackboardKey[] = "fault_reporter";
4749

50+
#ifdef MANYMOVE_WITH_MEDKIT
4851
// Severity aliases that mirror ros2_medkit_msgs::msg::Fault::SEVERITY_*. Kept
4952
// here as a header-local convenience so call sites do not have to spell out
5053
// the verbose qualified constants on every reportFault() invocation.
5154
inline constexpr uint8_t kSeverityInfo = ros2_medkit_msgs::msg::Fault::SEVERITY_INFO;
5255
inline constexpr uint8_t kSeverityWarn = ros2_medkit_msgs::msg::Fault::SEVERITY_WARN;
5356
inline constexpr uint8_t kSeverityError = ros2_medkit_msgs::msg::Fault::SEVERITY_ERROR;
5457
inline constexpr uint8_t kSeverityCritical = ros2_medkit_msgs::msg::Fault::SEVERITY_CRITICAL;
58+
#else
59+
// Severity constants kept value-compatible with ros2_medkit_msgs::msg::Fault
60+
// so call sites compile unchanged when the medkit dep is disabled at build
61+
// time (MANYMOVE_WITH_MEDKIT=OFF).
62+
inline constexpr uint8_t kSeverityInfo = 0;
63+
inline constexpr uint8_t kSeverityWarn = 1;
64+
inline constexpr uint8_t kSeverityError = 2;
65+
inline constexpr uint8_t kSeverityCritical = 3;
66+
#endif
5567

5668
// Capability class that gives a BT action node one-line access to the
5769
// process-wide FaultReporter installed on the blackboard. Inherited as a
@@ -63,10 +75,11 @@ inline constexpr uint8_t kSeverityCritical = ros2_medkit_msgs::msg::Fault::SEVER
6375
// inherit this: their FAILURE return is normal control flow, not a fault,
6476
// and instrumenting them would flood the FaultManager.
6577
//
66-
// Lifetime: keeps a shared_ptr to the reporter so it is safe to use from any
67-
// callback running on the same node executor. The reporter itself is owned
68-
// by the bt_client_*.cpp main(); destruction order is fine because the
69-
// blackboard outlives every BT node that pulled the pointer in its ctor.
78+
// When the package is built with MANYMOVE_WITH_MEDKIT=OFF the class becomes a
79+
// stub with identical public API: every reportFault()/reportFaultPassed()
80+
// call compiles to a no-op and no medkit headers are pulled in. This lets
81+
// downstream users build manymove without the ros2_medkit overlay while
82+
// keeping the integrated build (ON) the default.
7083
class FaultReporting
7184
{
7285
public:
@@ -75,6 +88,7 @@ class FaultReporting
7588
FaultReporting() = default;
7689

7790
protected:
91+
#ifdef MANYMOVE_WITH_MEDKIT
7892
explicit FaultReporting(const BT::Blackboard::Ptr & blackboard)
7993
{
8094
if (blackboard) {
@@ -103,6 +117,17 @@ class FaultReporting
103117
}
104118

105119
std::shared_ptr<ros2_medkit_fault_reporter::FaultReporter> reporter_;
120+
#else
121+
explicit FaultReporting(const BT::Blackboard::Ptr & /*blackboard*/) {}
122+
123+
void reportFault(
124+
const char * /*fault_code*/, uint8_t /*severity*/,
125+
const std::string & /*description*/) const
126+
{
127+
}
128+
129+
void reportFaultPassed(const char * /*fault_code*/) const {}
130+
#endif
106131
};
107132

108133
} // namespace manymove_cpp_trees

manymove_cpp_trees/include/manymove_cpp_trees/main_imports_helper.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040

4141
#include <rclcpp/rclcpp.hpp>
4242

43+
#ifdef MANYMOVE_WITH_MEDKIT
44+
#include <ros2_medkit_fault_reporter/fault_reporter.hpp>
45+
#endif
46+
4347
#include "manymove_cpp_trees/action_nodes_logic.hpp"
4448
#include "manymove_cpp_trees/action_nodes_objects.hpp"
4549
#include "manymove_cpp_trees/action_nodes_planner.hpp"
@@ -109,6 +113,12 @@ namespace manymove_cpp_trees
109113
//
110114
// service_name lets callers remap the FaultManager service for namespaced
111115
// test rigs or multi-robot setups (e.g. "/robot1/fault_manager/report_fault").
116+
//
117+
// When the package is built with MANYMOVE_WITH_MEDKIT=OFF this is a no-op
118+
// kept for source compatibility: bt_client_*.cpp main() can call it
119+
// unconditionally and the FaultReporting mixin in every action node still
120+
// compiles, with reportFault()/reportFaultPassed() folding to no-ops.
121+
#ifdef MANYMOVE_WITH_MEDKIT
112122
inline void installFaultReporter(
113123
BT::Blackboard::Ptr blackboard, rclcpp::Node::SharedPtr node,
114124
const std::string & service_name = "/fault_manager/report_fault")
@@ -117,6 +127,13 @@ inline void installFaultReporter(
117127
node, node->get_fully_qualified_name(), service_name);
118128
blackboard->set(manymove_cpp_trees::kFaultReporterBlackboardKey, reporter);
119129
}
130+
#else
131+
inline void installFaultReporter(
132+
BT::Blackboard::Ptr /*blackboard*/, rclcpp::Node::SharedPtr /*node*/,
133+
const std::string & /*service_name*/ = "/fault_manager/report_fault")
134+
{
135+
}
136+
#endif
120137

121138
} // namespace manymove_cpp_trees
122139

manymove_cpp_trees/package.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
<depend>simulation_interfaces</depend>
2828
<depend>vision_msgs</depend>
2929
<depend>rcpputils</depend>
30-
<depend>ros2_medkit_fault_reporter</depend>
31-
<depend>ros2_medkit_msgs</depend>
30+
<!-- ros2_medkit deps follow the MANYMOVE_WITH_MEDKIT CMake option (default
31+
OFF). The rosdep condition keys off the env var of the same name:
32+
MANYMOVE_WITH_MEDKIT=1 -> install, unset or any other value -> skip.
33+
Keep this aligned with the CMake option in CMakeLists.txt. -->
34+
<depend condition="$MANYMOVE_WITH_MEDKIT == 1">ros2_medkit_fault_reporter</depend>
35+
<depend condition="$MANYMOVE_WITH_MEDKIT == 1">ros2_medkit_msgs</depend>
3236

3337
<test_depend>ament_lint_auto</test_depend>
3438
<test_depend>ament_lint_common</test_depend>

0 commit comments

Comments
 (0)