Skip to content

Commit 7e891e0

Browse files
committed
Resolves #321. Make aggregator composable
1 parent 14f4ba2 commit 7e891e0

6 files changed

Lines changed: 96 additions & 18 deletions

File tree

diagnostic_aggregator/CMakeLists.txt

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ find_package(ament_cmake REQUIRED)
1515
find_package(diagnostic_msgs REQUIRED)
1616
find_package(pluginlib REQUIRED)
1717
find_package(rclcpp REQUIRED)
18+
find_package(rclcpp_components REQUIRED)
1819
find_package(rcl_interfaces REQUIRED)
1920
find_package(std_msgs REQUIRED)
2021

2122
add_library(${PROJECT_NAME} SHARED
2223
src/status_item.cpp
23-
src/analyzer_group.cpp
2424
src/aggregator.cpp)
2525
target_include_directories(${PROJECT_NAME} PUBLIC
2626
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
@@ -30,6 +30,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
3030
${std_msgs_TARGETS}
3131
pluginlib::pluginlib
3232
rclcpp::rclcpp
33+
rclcpp_components::component
3334
)
3435
target_compile_definitions(${PROJECT_NAME}
3536
PRIVATE "DIAGNOSTIC_AGGREGATOR_BUILDING_DLL")
@@ -46,7 +47,8 @@ set(ANALYZERS "${PROJECT_NAME}_analyzers")
4647
add_library(${ANALYZERS} SHARED
4748
src/generic_analyzer.cpp
4849
src/discard_analyzer.cpp
49-
src/ignore_analyzer.cpp)
50+
src/ignore_analyzer.cpp
51+
src/analyzer_group.cpp)
5052
target_include_directories(${ANALYZERS} PUBLIC
5153
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
5254
$<INSTALL_INTERFACE:include>)
@@ -60,13 +62,20 @@ target_link_libraries(${ANALYZERS} PUBLIC
6062
target_compile_definitions(${ANALYZERS}
6163
PRIVATE "DIAGNOSTIC_AGGREGATOR_BUILDING_DLL")
6264

65+
# Register the aggregator node as a component
66+
rclcpp_components_register_node(
67+
${PROJECT_NAME}
68+
PLUGIN "diagnostic_aggregator::Aggregator"
69+
EXECUTABLE aggregator_node
70+
)
71+
6372
# prevent pluginlib from using boost
6473
target_compile_definitions(${ANALYZERS} PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
6574

66-
# Aggregator node
67-
add_executable(aggregator_node src/aggregator_node.cpp)
68-
target_link_libraries(aggregator_node
69-
${PROJECT_NAME})
75+
# # Aggregator node
76+
# add_executable(aggregator_node src/aggregator_node.cpp)
77+
# target_link_libraries(aggregator_node
78+
# ${PROJECT_NAME})
7079

7180
# Add analyzer
7281
add_executable(add_analyzer src/add_analyzer.cpp)
@@ -165,10 +174,10 @@ if(BUILD_TESTING)
165174
# )
166175
endif()
167176

168-
install(
169-
TARGETS aggregator_node
170-
DESTINATION lib/${PROJECT_NAME}
171-
)
177+
# install(
178+
# TARGETS aggregator_node
179+
# DESTINATION lib/${PROJECT_NAME}
180+
# )
172181

173182
install(
174183
TARGETS add_analyzer
@@ -194,8 +203,11 @@ ament_python_install_package(${PROJECT_NAME})
194203
set(ANALYZER_PARAMS_FILEPATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/example_analyzers.yaml")
195204
set(ADD_ANALYZER_PARAMS_FILEPATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/example_add_analyzers.yaml")
196205
configure_file(example/example.launch.py.in example.launch.py @ONLY)
206+
configure_file(example/compose_example.launch.py.in compose_example.launch.py @ONLY)
197207
install( # launch descriptor
198-
FILES ${CMAKE_CURRENT_BINARY_DIR}/example.launch.py
208+
FILES
209+
${CMAKE_CURRENT_BINARY_DIR}/example.launch.py
210+
${CMAKE_CURRENT_BINARY_DIR}/compose_example.launch.py
199211
DESTINATION share/${PROJECT_NAME}
200212
)
201213
install( # example publisher
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Launch analyzer loader with parameters from yaml."""
2+
3+
import launch
4+
from launch_ros.actions import ComposableNodeContainer, Node
5+
from launch_ros.descriptions import ComposableNode
6+
7+
analyzer_params_filepath = "@ANALYZER_PARAMS_FILEPATH@"
8+
add_analyzer_params_filepath = "@ADD_ANALYZER_PARAMS_FILEPATH@"
9+
10+
11+
def generate_launch_description():
12+
container = ComposableNodeContainer(
13+
name="diagnostics_container",
14+
namespace='',
15+
package='rclcpp_components',
16+
executable='component_container',
17+
composable_node_descriptions=[
18+
ComposableNode(
19+
package='diagnostic_aggregator',
20+
plugin='diagnostic_aggregator::Aggregator',
21+
name='analyzers',
22+
parameters=[analyzer_params_filepath]
23+
)
24+
]
25+
)
26+
27+
diag_publisher = Node(
28+
package='diagnostic_aggregator',
29+
executable='example_pub.py'
30+
)
31+
return launch.LaunchDescription([
32+
container,
33+
# add_analyzer,
34+
diag_publisher,
35+
])

diagnostic_aggregator/example/example_pub.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,11 @@ def timer_callback(self):
114114
def main(args=None):
115115
rclpy.init(args=args)
116116

117-
node = DiagnosticTalker()
118-
rclpy.spin(node)
117+
try:
118+
node = DiagnosticTalker()
119+
rclpy.spin(node)
120+
except KeyboardInterrupt:
121+
pass
119122

120123
node.destroy_node()
121124
rclpy.try_shutdown()

diagnostic_aggregator/include/diagnostic_aggregator/aggregator.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@
4646
#include <vector>
4747

4848
#include "diagnostic_aggregator/analyzer.hpp"
49-
#include "diagnostic_aggregator/analyzer_group.hpp"
5049
#include "diagnostic_aggregator/other_analyzer.hpp"
5150
#include "diagnostic_aggregator/status_item.hpp"
5251
#include "diagnostic_aggregator/visibility_control.hpp"
5352

53+
#include "pluginlib/class_loader.hpp"
54+
5455
#include "diagnostic_msgs/msg/diagnostic_array.hpp"
5556
#include "diagnostic_msgs/msg/diagnostic_status.hpp"
5657
#include "diagnostic_msgs/msg/key_value.hpp"
@@ -130,6 +131,8 @@ class Aggregator
130131
DIAGNOSTIC_AGGREGATOR_PUBLIC
131132
rclcpp::Node::SharedPtr get_node() const;
132133

134+
DIAGNOSTIC_AGGREGATOR_PUBLIC
135+
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr get_node_base_interface() const;
133136
private:
134137
rclcpp::Node::SharedPtr n_;
135138

@@ -156,7 +159,8 @@ class Aggregator
156159
*/
157160
void diagCallback(const diagnostic_msgs::msg::DiagnosticArray::SharedPtr diag_msg);
158161

159-
std::unique_ptr<AnalyzerGroup> analyzer_group_;
162+
std::shared_ptr<pluginlib::ClassLoader<Analyzer>> analyzer_loader_;
163+
std::shared_ptr<Analyzer> analyzer_group_;
160164
std::unique_ptr<OtherAnalyzer> other_analyzer_;
161165

162166
std::string base_path_; /**< \brief Prepended to all status names of aggregator. */

diagnostic_aggregator/package.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@
2424
<build_depend>pluginlib</build_depend>
2525
<build_depend>rcl_interfaces</build_depend>
2626
<build_depend>rclcpp</build_depend>
27+
<build_depend>rclcpp_components</build_depend>
2728
<build_depend>std_msgs</build_depend>
2829

2930
<depend>rclpy</depend>
3031

32+
<exec_depend>rclcpp_components</exec_depend>
33+
3134
<test_depend>ament_cmake_gtest</test_depend>
3235
<test_depend>ament_cmake_pytest</test_depend>
3336
<test_depend>ament_lint_auto</test_depend>

diagnostic_aggregator/src/aggregator.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,21 @@ void Aggregator::initAnalyzers()
137137

138138
{ // lock the mutex while analyzer_group_ and other_analyzer_ are being updated
139139
std::lock_guard<std::mutex> lock(mutex_);
140-
analyzer_group_ = std::make_unique<AnalyzerGroup>();
141-
if (!analyzer_group_->init(base_path_, "", n_)) {
142-
RCLCPP_ERROR(logger_, "Analyzer group for diagnostic aggregator failed to initialize!");
140+
141+
// Load analyzer_group as a plugin
142+
try {
143+
if (!analyzer_loader_) {
144+
analyzer_loader_ = std::make_shared<pluginlib::ClassLoader<Analyzer>>(
145+
"diagnostic_aggregator", "diagnostic_aggregator::Analyzer");
146+
}
147+
analyzer_group_ = analyzer_loader_->createSharedInstance(
148+
"diagnostic_aggregator/AnalyzerGroup");
149+
150+
if (!analyzer_group_->init(base_path_, "", n_)) {
151+
RCLCPP_ERROR(logger_, "Analyzer group for diagnostic aggregator failed to initialize!");
152+
}
153+
} catch (pluginlib::PluginlibException & e) {
154+
RCLCPP_ERROR(logger_, "Failed to load AnalyzerGroup plugin: %s", e.what());
143155
}
144156

145157
// Last analyzer handles remaining data
@@ -269,4 +281,13 @@ rclcpp::Node::SharedPtr Aggregator::get_node() const
269281
return this->n_;
270282
}
271283

284+
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr Aggregator::get_node_base_interface() const
285+
{
286+
RCLCPP_DEBUG(logger_, "get_node_base_interface()");
287+
return this->n_->get_node_base_interface();
288+
}
289+
272290
} // namespace diagnostic_aggregator
291+
292+
#include "rclcpp_components/register_node_macro.hpp"
293+
RCLCPP_COMPONENTS_REGISTER_NODE(diagnostic_aggregator::Aggregator)

0 commit comments

Comments
 (0)