37 std::is_base_of<ModeBase, ModeT>::value,
38 "Template type ModeT must be derived from px4_ros2::ModeBase");
41 explicit NodeWithMode(std::string node_name,
bool enable_debug_output =
false)
44 if (enable_debug_output) {
46 rcutils_logging_set_logger_level(get_logger().get_name(), RCUTILS_LOG_SEVERITY_DEBUG);
48 if (ret != RCUTILS_RET_OK) {
49 RCLCPP_ERROR(get_logger(),
"Error setting severity: %s", rcutils_get_error_string().str);
50 rcutils_reset_error();
54 _mode = std::make_unique<ModeT>(*
this);
56 if (!_mode->doRegister()) {
57 throw std::runtime_error(
"Registration failed");
61 ModeT & getMode()
const
67 std::unique_ptr<ModeT> _mode;
93 std::is_base_of_v<ModeExecutorBase, ModeExecutorT>,
94 "Template type ModeExecutorT must be derived from px4_ros2::ModeExecutorBase");
96 (std::is_base_of_v<ModeBase, OwnedModeT>&& ... && std::is_base_of_v<ModeBase, OtherModesT>),
97 "Template types OwnedModeT and OtherModesT must be derived from px4_ros2::ModeBase");
103 if (enable_debug_output) {
105 rcutils_logging_set_logger_level(get_logger().get_name(), RCUTILS_LOG_SEVERITY_DEBUG);
107 if (ret != RCUTILS_RET_OK) {
108 RCLCPP_ERROR(get_logger(),
"Error setting severity: %s", rcutils_get_error_string().str);
109 rcutils_reset_error();
113 _owned_mode = std::make_unique<OwnedModeT>(*
this);
114 _other_modes = std::make_tuple(std::make_unique<OtherModesT>(*this)...);
115 _mode_executor = createModeExecutor(std::index_sequence_for<OtherModesT...>{});
117 if (!_mode_executor->doRegister() || !std::apply(
118 [](
const auto &... mode) {
120 return (mode->doRegister() && ...);
124 throw std::runtime_error(
"Registration failed");
128 template<
typename ModeT = OwnedModeT>
129 ModeT & getMode()
const
131 if constexpr (std::is_same_v<ModeT, OwnedModeT>) {
134 return *std::get<ModeT>(_other_modes);
139 template<std::size_t... Idx>
140 auto createModeExecutor(std::index_sequence<Idx...>)
142 if constexpr (
sizeof...(Idx) == 0) {
143 return std::make_unique<ModeExecutorT>(*
this, *_owned_mode);
145 return std::make_unique<ModeExecutorT>(*
this, *_owned_mode, *std::get<Idx>(_other_modes)...);
149 std::unique_ptr<ModeExecutorT> _mode_executor;
150 std::unique_ptr<OwnedModeT> _owned_mode;
151 std::tuple<std::unique_ptr<OtherModesT>...> _other_modes;