Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e6d3a7b
only one distro per branch
ct2034 May 13, 2024
483f3b8
readme update (#343)
ct2034 May 13, 2024
ab7af61
Using ubuntu ntp server in systemtest (#346) (#347)
ct2034 May 14, 2024
294e5a4
Update test.yaml
ct2034 May 14, 2024
5076eb1
NTP monitor improvements (#342) (#350)
ct2034 Jun 26, 2024
ac82a29
refactor(ram_monitor): ros2 port (#338)
reinzor Jun 26, 2024
c8499c7
Fix usage of rclcpp::ok with a non-default context (#352)
haudren-woven Jun 26, 2024
e914474
Aggregator: publish diagnostics_toplevel_state immediately on every d…
ct2034 Jun 27, 2024
5933c90
Add add_analyzer functionality (#329) (#359)
ct2034 Jun 27, 2024
58c3ac1
Adopting CI changes similar to jazzy #358 (#362)
ct2034 Jun 27, 2024
57c5ca4
refactor(sensors_monitor): ros2 port #339 (#365)
ct2034 Jun 27, 2024
1ebcbd7
change(diagnosed-publisher): allow specifying node clock (#340) (#370)
ct2034 Jun 27, 2024
a64d8ad
changelogs
ct2034 Jun 27, 2024
5e28e01
3.2.1
ct2034 Jun 27, 2024
e2a9d17
4.0.0
ct2034 Jun 27, 2024
0e22c8c
versioning info (#373) (#374)
ct2034 Jun 27, 2024
56533b2
writing down the backport tool and its usage (#377) (#378)
ct2034 Jun 27, 2024
fe98a48
[ros2-humble] Port hd_monitor to ROS2 (#334) (#381)
ct2034 Jul 17, 2024
a2737ca
adding buildfarm statuses (#394) (#395)
ct2034 Dec 3, 2024
c1e03f9
Skipping flaky tests (#413) (#414)
ct2034 Dec 6, 2024
b78e24a
Add missing rclpy dependency to common_diagnostics to fix rosdoc2 out…
ct2034 Dec 6, 2024
af8f695
common_diagnostics cleaned hostname string (#405) (#419)
ct2034 Dec 18, 2024
f21a049
Support custom `rclcpp::NodeOptions` (#417) (#422)
ct2034 Jan 7, 2025
af5a76f
Add Windows support (#426) (#428)
ct2034 Jan 27, 2025
04c9a04
Checking licenses in CI (#431) (#432)
ct2034 Jan 27, 2025
d96767c
Changelogs
ct2034 Feb 10, 2025
56d07e0
4.0.2
ct2034 Feb 10, 2025
83bf46f
EOL iron, adding kilted (#437) (#438)
ct2034 Feb 10, 2025
1b28cec
[ros2-humble] Grafana Integration (#425) (#444)
ct2034 Mar 4, 2025
fd95a4c
Don't use `match` (#442)
christophfroehlich Mar 12, 2025
80a3b79
cleanup (#450) (#451)
ct2034 Mar 12, 2025
590682f
Fix reported hd_monitor available value (#443) (#454)
ct2034 Mar 12, 2025
4ab7e66
Propagate clock instead of creating default
redvinaa Apr 1, 2025
a5e2a3d
Lint
redvinaa Apr 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
pull_request:
push:
branches:
- ros2
- ros2-humble
schedule:
# Run every week at 20:00 on Sunday
- cron: "0 20 * * 0"
Expand All @@ -22,18 +22,30 @@ jobs:
uncrustify,
xmllint,
]
runs-on: ubuntu-latest
include:
- distro: humble
os: ubuntu-22.04
runs-on: ${{ matrix.os }}
env:
AMENT_CPPCHECK_ALLOW_SLOW_VERSIONS: 1
steps:
- uses: actions/checkout@v1
- uses: ros-tooling/setup-ros@master
- run: sudo pip install pydocstyle==6.1.1 # downgrade to fix https://github.com/ament/ament_lint/pull/428
with:
required-ros-distributions: ${{ matrix.distro }}
- uses: ros-tooling/action-ros-lint@master
with:
linter: ${{ matrix.linter }}
package-name: |
diagnostic_aggregator
diagnostic_common_diagnostics
diagnostic_remote_logging
diagnostic_updater
self_test

check_licenses:
name: Check licenses
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: boschresearch/ros_license_toolkit@2.0.1
13 changes: 5 additions & 8 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
pull_request:
push:
branches:
- ros2
- ros2-humble
schedule:
# Run every week at 20:00 on Sunday
- cron: "0 20 * * 0"
Expand All @@ -14,25 +14,22 @@ jobs:
strategy:
fail-fast: false
matrix:
package:
[
package: [
diagnostic_aggregator,
diagnostic_common_diagnostics,
diagnostic_remote_logging,
diagnostic_updater,
self_test,
]
distro: [humble, iron, rolling]
include:
- distro: humble
os: 22.04
- distro: iron
os: 22.04
- distro: rolling
os: 24.04
runs-on: ubuntu-latest
container: ubuntu:${{ matrix.os }}
steps:
- uses: ros-tooling/setup-ros@master
with:
required-ros-distributions: ${{ matrix.distro }}
- uses: ros-tooling/action-ros-ci@master
with:
target-ros2-distro: ${{ matrix.distro }}
Expand Down
79 changes: 72 additions & 7 deletions README.md

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions diagnostic_aggregator/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@
Changelog for package diagnostic_aggregator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

4.0.2 (2025-02-10)
------------------
* Checking licenses in CI (`#431 <https://github.com/ros/diagnostics/issues/431>`_) (`#432 <https://github.com/ros/diagnostics/issues/432>`_)
* Checking licenses in ci
* Add Windows support (`#426 <https://github.com/ros/diagnostics/issues/426>`_) (`#428 <https://github.com/ros/diagnostics/issues/428>`_)
Co-authored-by: Silvio Traversaro <silvio@traversaro.it>
* Support custom `rclcpp::NodeOptions` (`#417 <https://github.com/ros/diagnostics/issues/417>`_) (`#422 <https://github.com/ros/diagnostics/issues/422>`_)
* Support custom `rclcpp::NodeOptions` This eases static composition of multiple ROS 2 nodes
Co-authored-by: Patrick Roncagliolo <ronca.pat@gmail.com>
* Skipping flaky tests (`#413 <https://github.com/ros/diagnostics/issues/413>`_) (`#414 <https://github.com/ros/diagnostics/issues/414>`_)
* skipping flaky ntp test
* Contributors: Christian Henkel

3.2.1 (2024-06-27)
------------------
* Add add_analyzer functionality (`#329 <https://github.com/ros/diagnostics/issues/329>`_) (`#359 <https://github.com/ros/diagnostics/issues/359>`_)
* Aggregator: publish diagnostics_toplevel_state immediately on every degradation (`#324 <https://github.com/ros/diagnostics/issues/324>`_) (`#355 <https://github.com/ros/diagnostics/issues/355>`_)
* Contributors: Christian Henkel

3.2.0 (2024-03-22)
------------------
* Avoid rolling up an ERROR state when empty GenericAnalyzer blocks are marked discard_stale, or when all of their items are STALE. (`#315 <https://github.com/ros/diagnostics/issues/315>`_)
Expand Down
54 changes: 45 additions & 9 deletions diagnostic_aggregator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

find_package(ament_cmake REQUIRED)
find_package(diagnostic_msgs REQUIRED)
find_package(pluginlib REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rcl_interfaces REQUIRED)
find_package(std_msgs REQUIRED)

add_library(${PROJECT_NAME} SHARED
Expand Down Expand Up @@ -67,6 +69,10 @@ add_executable(aggregator_node src/aggregator_node.cpp)
target_link_libraries(aggregator_node
${PROJECT_NAME})

# Add analyzer
add_executable(add_analyzer src/add_analyzer.cpp)
ament_target_dependencies(add_analyzer rclcpp rcl_interfaces)

# Testing macro
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
Expand All @@ -77,6 +83,7 @@ if(BUILD_TESTING)
find_package(launch_testing_ament_cmake REQUIRED)

file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}/lib/${PROJECT_NAME}/aggregator_node" AGGREGATOR_NODE)
file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}/lib/${PROJECT_NAME}/add_analyzer" ADD_ANALYZER)
file(TO_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/test_listener.py" TEST_LISTENER)
set(create_analyzers_tests
"primitive_analyzers"
Expand Down Expand Up @@ -124,22 +131,50 @@ if(BUILD_TESTING)
)
endforeach()

add_launch_test(
test/test_critical_pub.py
TIMEOUT 30
)
set(add_analyzers_tests
"all_analyzers")

foreach(test_name ${add_analyzers_tests})
file(TO_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/default.yaml" PARAMETER_FILE)
file(TO_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/${test_name}.yaml" ADD_PARAMETER_FILE)
file(TO_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/expected_output/add_${test_name}" EXPECTED_OUTPUT)

ament_add_pytest_test(test_discard_behavior
"${CMAKE_CURRENT_SOURCE_DIR}/test/test_discard_behavior.py"
TIMEOUT 60
)
configure_file(
"test/add_analyzers.launch.py.in"
"test_add_${test_name}.launch.py"
@ONLY
)
add_launch_test(
"${CMAKE_CURRENT_BINARY_DIR}/test_add_${test_name}.launch.py"
TARGET "test_add_${test_name}"
TIMEOUT 30
ENV
)
endforeach()

# SKIPPING FLAKY TEST
# add_launch_test(
# test/test_critical_pub.py
# TIMEOUT 30
# )

# SKIPPING FLAKY TEST
# ament_add_pytest_test(test_discard_behavior
# "${CMAKE_CURRENT_SOURCE_DIR}/test/test_discard_behavior.py"
# TIMEOUT 60
# )
endif()

install(
TARGETS aggregator_node
DESTINATION lib/${PROJECT_NAME}
)

install(
TARGETS add_analyzer
DESTINATION lib/${PROJECT_NAME}
)

install(
TARGETS ${PROJECT_NAME} ${ANALYZERS}
EXPORT ${PROJECT_NAME}Targets
Expand All @@ -157,6 +192,7 @@ ament_python_install_package(${PROJECT_NAME})

# Install Example
set(ANALYZER_PARAMS_FILEPATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/example_analyzers.yaml")
set(ADD_ANALYZER_PARAMS_FILEPATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/example_add_analyzers.yaml")
configure_file(example/example.launch.py.in example.launch.py @ONLY)
install( # launch descriptor
FILES ${CMAKE_CURRENT_BINARY_DIR}/example.launch.py
Expand All @@ -167,7 +203,7 @@ install( # example publisher
DESTINATION lib/${PROJECT_NAME}
)
install( # example aggregator configration
FILES example/example_analyzers.yaml
FILES example/example_analyzers.yaml example/example_add_analyzers.yaml
DESTINATION share/${PROJECT_NAME}
)

Expand Down
27 changes: 27 additions & 0 deletions diagnostic_aggregator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,33 @@ You can launch the `aggregator_node` like this (see [example.launch.py.in](examp
])
```

You can add analyzers at runtime using the `add_analyzer` node like this (see [example.launch.py.in](example/example.launch.py.in)):
```
add_analyzer = launch_ros.actions.Node(
package='diagnostic_aggregator',
executable='add_analyzer',
output='screen',
parameters=[add_analyzer_params_filepath])
return launch.LaunchDescription([
add_analyzer,
])
```
This node updates the parameters of the `aggregator_node` by calling the service `/analyzers/set_parameters_atomically`.
The `aggregator_node` will detect when a `parameter-event` has introduced new parameters to it.
When this happens the `aggregator_node` will reload all analyzers based on its new set of parameters.
Adding analyzers this way can be done at runtime and can be made conditional.

In the example, `add_analyzer` will add an analyzer for diagnostics that are marked optional:
``` yaml
/**:
ros__parameters:
optional:
type: diagnostic_aggregator/GenericAnalyzer
path: Optional
startswith: [ '/optional' ]
```
This will move the `/optional/runtime/analyzer` diagnostic from the "Other" to "Aggregation" where it will not go stale after 5 seconds and will be taken into account for the toplevel state.

# Basic analyzers
The `diagnostic_aggregator` package provides a few basic analyzers that you can use to aggregate your diagnostics.

Expand Down
4 changes: 3 additions & 1 deletion diagnostic_aggregator/example/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Aggregator Example

This is a simple example to show the diagnostic_aggregator in action. It involves one python script producing dummy diagnostic data ([example_pub.py](./example_pub.py)), and one diagnostic aggregator configuration ([example.yaml](./example.yaml)) that provides analyzers aggregating it.
This is a simple example to show the diagnostic_aggregator and add_analyzer in action. It involves one python script producing dummy diagnostic data ([example_pub.py](./example_pub.py)), one diagnostic aggregator configuration ([example_analyzers.yaml](./example_analyzers.yaml)) and one add_analyzer configuration ([example_add_analyzers.yaml](./example_add_analyzers.yaml)).

The aggregator will launch and load all the analyzers listed in ([example_analyzers.yaml](./example_analyzers.yaml)). Then the aggregator will be notified that there are additional analyzers that we also want to load in ([example_add_analyzers.yaml](./example_add_analyzers.yaml)). After this reload all analyzers will be active.

Run the example with `ros2 launch diagnostic_aggregator example.launch.py`
8 changes: 8 additions & 0 deletions diagnostic_aggregator/example/example.launch.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import launch
import launch_ros.actions

analyzer_params_filepath = "@ANALYZER_PARAMS_FILEPATH@"
add_analyzer_params_filepath = "@ADD_ANALYZER_PARAMS_FILEPATH@"


def generate_launch_description():
Expand All @@ -12,11 +13,18 @@ def generate_launch_description():
executable='aggregator_node',
output='screen',
parameters=[analyzer_params_filepath])
add_analyzer = launch_ros.actions.Node(
package='diagnostic_aggregator',
executable='add_analyzer',
output='screen',
parameters=[add_analyzer_params_filepath]
)
diag_publisher = launch_ros.actions.Node(
package='diagnostic_aggregator',
executable='example_pub.py')
return launch.LaunchDescription([
aggregator,
add_analyzer,
diag_publisher,
launch.actions.RegisterEventHandler(
event_handler=launch.event_handlers.OnProcessExit(
Expand Down
6 changes: 6 additions & 0 deletions diagnostic_aggregator/example/example_add_analyzers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**:
ros__parameters:
optional:
type: diagnostic_aggregator/GenericAnalyzer
path: Optional
contains: [ '/optional' ]
4 changes: 4 additions & 0 deletions diagnostic_aggregator/example/example_pub.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ def __init__(self):
name='/sensors/front/cam', message='OK'),
DiagnosticStatus(level=DiagnosticStatus.OK,
name='/sensors/rear/cam', message='OK'),

# Optional
DiagnosticStatus(level=DiagnosticStatus.OK,
name='/optional/runtime/analyzer', message='OK'),
]

def timer_callback(self):
Expand Down
19 changes: 19 additions & 0 deletions diagnostic_aggregator/include/diagnostic_aggregator/aggregator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ class Aggregator
DIAGNOSTIC_AGGREGATOR_PUBLIC
Aggregator();

/*!
*\brief Constructor initializes with main prefix (ex: '/Robot') and custom node options
*/
DIAGNOSTIC_AGGREGATOR_PUBLIC
explicit Aggregator(rclcpp::NodeOptions options);


DIAGNOSTIC_AGGREGATOR_PUBLIC
virtual ~Aggregator();

Expand All @@ -133,6 +140,8 @@ class Aggregator
rclcpp::Service<diagnostic_msgs::srv::AddDiagnostics>::SharedPtr add_srv_;
/// DiagnosticArray, /diagnostics
rclcpp::Subscription<diagnostic_msgs::msg::DiagnosticArray>::SharedPtr diag_sub_;
/// ParameterEvent, /parameter_events
rclcpp::Subscription<rcl_interfaces::msg::ParameterEvent>::SharedPtr param_sub_;
/// DiagnosticArray, /diagnostics_agg
rclcpp::Publisher<diagnostic_msgs::msg::DiagnosticArray>::SharedPtr agg_pub_;
/// DiagnosticStatus, /diagnostics_toplevel_state
Expand Down Expand Up @@ -165,6 +174,16 @@ class Aggregator
/// Records all ROS warnings. No warnings are repeated.
std::set<std::string> ros_warnings_;

/*
*!\brief Checks for new parameters to trigger reinitialization of the AnalyzerGroup and OtherAnalyzer
*/
void parameterCallback(const rcl_interfaces::msg::ParameterEvent::SharedPtr param_msg);

/*
*!\brief (re)initializes the AnalyzerGroup and OtherAnalyzer
*/
void initAnalyzers();

/*
*!\brief Checks timestamp of message, and warns if timestamp is 0 (not set)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ class Analyzer
/*!
*\brief Default constructor, called by pluginlib.
*/
Analyzer()
: clock_(std::make_shared<rclcpp::Clock>()) {}
Analyzer() {}

virtual ~Analyzer() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ class GenericAnalyzer : public GenericAnalyzerBase
virtual bool match(const std::string & name);

private:
rclcpp::Node::SharedPtr node_;
std::vector<std::string> chaff_; /**< Removed from the start of node names. */
std::vector<std::string> expected_;
std::vector<std::string> startswith_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,16 @@ class GenericAnalyzerBase : public Analyzer
* Must be initialized in order to prepend the path to all outgoing status messages.
*/
bool init(
const std::string & path, const std::string & breadcrumb, double timeout = -1.0,
const std::string & path, const std::string & breadcrumb,
const rclcpp::Node::SharedPtr node, double timeout = -1.0,
int num_items_expected = -1, bool discard_stale = false)
{
num_items_expected_ = num_items_expected;
timeout_ = timeout;
path_ = path + "/" + nice_name_;
discard_stale_ = discard_stale;
breadcrumb_ = breadcrumb;
clock_ = node->get_clock();

if (discard_stale_ && timeout <= 0) {
RCLCPP_WARN(
Expand Down
Loading