10#ifndef _LIFECYCLE_STATUS_CHECK_BASE_HPP
11#define _LIFECYCLE_STATUS_CHECK_BASE_HPP
13#include <rmw/qos_profiles.h>
16#include <lifecycle_msgs/msg/state.hpp>
17#include <lifecycle_msgs/srv/get_state.hpp>
18#include <rclcpp/rclcpp.hpp>
39 const std::string target_node_name,
const std::string expected_state,
const uint32_t timeout_ms)
41 target_node_name_ = target_node_name;
42 expected_state_id_ = parse_state_string(expected_state);
43 timeout_ms_ = timeout_ms;
49 std::string target_node_name_;
50 uint8_t expected_state_id_ = 0;
51 uint32_t timeout_ms_ = 0;
52 std::string status_msg_;
54 std::string get_unique_id()
const override
56 return "LifecycleStatusCheckBase::" + target_node_name_ +
57 "::" + std::to_string(expected_state_id_);
60 bool check_impl(rclcpp::Node::SharedPtr node)
override
62 if (target_node_name_.empty() || timeout_ms_ == 0) {
63 status_msg_ =
"Not set target_node_name or timeout. Please invoke `set_config()` function.";
69 std::string service_name = target_node_name_ +
"/get_state";
71 auto callback_group = node->create_callback_group(rclcpp::CallbackGroupType::Reentrant);
74 auto client = node->create_client<lifecycle_msgs::srv::GetState>(
75 service_name, rclcpp::ServicesQoS(), callback_group);
78 if (!
client->wait_for_service(std::chrono::milliseconds(timeout_ms_ / 2))) {
79 status_msg_ =
"Service not found: " + service_name;
84 auto request = std::make_shared<lifecycle_msgs::srv::GetState::Request>();
85 auto future =
client->async_send_request(request);
88 std::future_status status = future.wait_for(std::chrono::milliseconds(timeout_ms_ / 2));
90 if (status == std::future_status::ready) {
92 auto response = future.get();
93 uint8_t current_state_id = response->current_state.id;
94 std::string current_state_label = response->current_state.label;
97 if (validate_state(current_state_id)) {
98 status_msg_ =
"State valid: " + current_state_label +
99 " (ID: " + std::to_string(current_state_id) +
")";
102 status_msg_ =
"State mismatch. Expected ID: " + std::to_string(expected_state_id_) +
103 ", Actual: " + current_state_label +
" (" +
104 std::to_string(current_state_id) +
")";
107 }
catch (
const std::exception & e) {
108 status_msg_ =
"Exception during service call: " + std::string(e.what());
112 status_msg_ =
"Service call timeout";
117 std::string report_impl([[maybe_unused]] rclcpp::Node::SharedPtr node)
override
119 return "Node: " + target_node_name_ +
" | " + status_msg_;
125 bool validate_state(uint8_t current_id) {
return current_id == expected_state_id_; }
128 int parse_state_string(
const std::string & state_str)
130 if (state_str ==
"unconfigured")
131 return lifecycle_msgs::msg::State::PRIMARY_STATE_UNCONFIGURED;
132 if (state_str ==
"inactive")
return lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE;
133 if (state_str ==
"active")
return lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE;
134 if (state_str ==
"finalized")
return lifecycle_msgs::msg::State::PRIMARY_STATE_FINALIZED;
Base class for checking the state of a Lifecycle Node. Connects to the {node_name}/get_state service ...
Definition: lifecycle_stats_check_base.hpp:30
void set_config(const std::string target_node_name, const std::string expected_state, const uint32_t timeout_ms)
Configuration for the check.
Definition: lifecycle_stats_check_base.hpp:38
virtual void prepare_check(rclcpp::Node::SharedPtr node) override=0
Prepares the check before execution.
Abstract base class for all system check plugins.
Definition: system_check_base.hpp:24
Definition: client.launch.py:1
Definition: action_server_check_base.hpp:25
Abstruct Class of check process.