diff --git a/controller_manager/CMakeLists.txt b/controller_manager/CMakeLists.txt index 689e7c7244..b3f0f59a2c 100644 --- a/controller_manager/CMakeLists.txt +++ b/controller_manager/CMakeLists.txt @@ -9,6 +9,7 @@ set(THIS_PACKAGE_INCLUDE_DEPENDS ament_index_cpp controller_interface controller_manager_msgs + diagnostic_updater hardware_interface pluginlib rclcpp diff --git a/controller_manager/include/controller_manager/controller_manager.hpp b/controller_manager/include/controller_manager/controller_manager.hpp index 4b03a3b4f4..5985bb37af 100644 --- a/controller_manager/include/controller_manager/controller_manager.hpp +++ b/controller_manager/include/controller_manager/controller_manager.hpp @@ -40,6 +40,7 @@ #include "controller_manager_msgs/srv/switch_controller.hpp" #include "controller_manager_msgs/srv/unload_controller.hpp" +#include "diagnostic_updater/diagnostic_updater.hpp" #include "hardware_interface/handle.hpp" #include "hardware_interface/resource_manager.hpp" @@ -394,6 +395,9 @@ class ControllerManager : public rclcpp::Node */ rclcpp::NodeOptions determine_controller_node_options(const ControllerSpec & controller) const; + void controller_activity_diagnostic_callback(diagnostic_updater::DiagnosticStatusWrapper & stat); + diagnostic_updater::Updater diagnostics_updater_; + std::shared_ptr executor_; std::shared_ptr> loader_; diff --git a/controller_manager/package.xml b/controller_manager/package.xml index ee25fd1047..ddf68e5b6a 100644 --- a/controller_manager/package.xml +++ b/controller_manager/package.xml @@ -16,6 +16,7 @@ backward_ros controller_interface controller_manager_msgs + diagnostic_updater hardware_interface launch launch_ros diff --git a/controller_manager/src/controller_manager.cpp b/controller_manager/src/controller_manager.cpp index 7d5672519a..d38bea3e70 100644 --- a/controller_manager/src/controller_manager.cpp +++ b/controller_manager/src/controller_manager.cpp @@ -277,7 +277,8 @@ ControllerManager::ControllerManager( kControllerInterfaceNamespace, kControllerInterfaceClassName)), chainable_loader_( std::make_shared>( - kControllerInterfaceNamespace, kChainableControllerInterfaceClassName)) + kControllerInterfaceNamespace, kChainableControllerInterfaceClassName)), + diagnostics_updater_(this) { if (!get_parameter("update_rate", update_rate_)) { @@ -299,6 +300,11 @@ ControllerManager::ControllerManager( init_resource_manager(robot_description); init_services(); } + + diagnostics_updater_.setHardwareID("ros2_control"); + diagnostics_updater_.add( + "Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback); + init_services(); } ControllerManager::ControllerManager( @@ -313,7 +319,8 @@ ControllerManager::ControllerManager( kControllerInterfaceNamespace, kControllerInterfaceClassName)), chainable_loader_( std::make_shared>( - kControllerInterfaceNamespace, kChainableControllerInterfaceClassName)) + kControllerInterfaceNamespace, kChainableControllerInterfaceClassName)), + diagnostics_updater_(this) { if (!get_parameter("update_rate", update_rate_)) { @@ -328,6 +335,11 @@ ControllerManager::ControllerManager( { init_services(); } + + diagnostics_updater_.setHardwareID("ros2_control"); + diagnostics_updater_.add( + "Controllers Activity", this, &ControllerManager::controller_activity_diagnostic_callback); + init_services(); } ControllerManager::~ControllerManager() @@ -2546,6 +2558,32 @@ controller_interface::return_type ControllerManager::check_preceeding_controller return controller_interface::return_type::OK; } +void ControllerManager::controller_activity_diagnostic_callback( + diagnostic_updater::DiagnosticStatusWrapper & stat) +{ + // lock controllers + std::lock_guard guard(rt_controllers_wrapper_.controllers_lock_); + const std::vector & controllers = rt_controllers_wrapper_.get_updated_list(guard); + bool all_active = true; + for (size_t i = 0; i < controllers.size(); ++i) + { + if (!is_controller_active(controllers[i].c)) + { + all_active = false; + } + stat.add(controllers[i].info.name, controllers[i].c->get_state().label()); + } + + if (all_active) + { + stat.summary(diagnostic_msgs::msg::DiagnosticStatus::OK, "All controllers are active"); + } + else + { + stat.summary(diagnostic_msgs::msg::DiagnosticStatus::ERROR, "Not all controllers are active"); + } +} + bool ControllerManager::controller_sorting( const ControllerSpec & ctrl_a, const ControllerSpec & ctrl_b, const std::vector & controllers) @@ -2669,7 +2707,7 @@ bool ControllerManager::controller_sorting( // The rest of the cases, basically end up at the end of the list return false; } -}; +} rclcpp::NodeOptions ControllerManager::determine_controller_node_options( const ControllerSpec & controller) const