Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Using the GenericAnalyzer
Description: Uses the GenericAnalyzer to analyze diagnostics from EtherCAT devices, hardware drivers and robot computers. Shows the complete feature set of the GenericAnalyzer.Tutorial Level: INTERMEDIATE
Contents
Overview
The diagnostic_aggregator package is designed to collect, process and analyze data on the /diagnostics topic. To do this, it uses the aggregator_node to load plugins of "diagnostic analyzers". The diagnostic_aggregator::GenericAnalyzer is the most basic of these plugins, and can be configured for use on any robot system.
The GenericAnalyzer can easily categorize a group of diagnostics data under a common header. When viewed with the robot_monitor, the data will appear under a common parent item in the tree.
For example, a hokuyo_node might publish diagnostics data with the following names:
tilt_hokuyo_node: Connection Status tilt_hokuyo_node: Driver Status tilt_hokuyo_node: Frequency Status
A GenericAnalyzer that was using the hokuyo_node might collect this data and output diagnostics with names:
Tilt Hokuyo Tilt Hokuyo/Connection Status Tilt Hokuyo/Driver Status Tilt Hokuyo/Frequency Status
And when viewed in the robot_monitor, the "Tilt Hokuyo" item would have the "Connection Status", etc items underneath it. If any of the sub-items went into warning or error state, the "Tilt Hokuyo" item would go into that state too.
The GenericAnalyzer doesn't just make the diagnostics easier to view, it can warn when items are stale, missing or go into warning or error state.
Other tutorials, like the Configuring Diagnostic Aggregators tutorial show how Analyzers are loaded by the diagnostic Aggregator. This tutorial shows how to use all the features of the GenericAnalyzer.
GenericAnalyzer Code
"diagnostic_aggregator/include/diagnostic_aggregator/generic_analyzer.h" declares the GenericAnalyzer class, which is the most basic of the analyzers. It is used by the aggregator_node to store, process and republish diagnostics data. The GenericAnalyzer is loaded by the pluginlib as an analyzer plugin.
Loading a GenericAnalyzer
To load a GenericAnalyzer into the aggregator_node, the GenericAnalyzer parameters must be in the ~analyzers namespace of the aggregator_node. Each namespace under ~analyzers will create one analyzer.
analyzers: motors: type: GenericAnalyzer path: Motors contains: 'motor'
Looking at the parameters above:
motors: Each analyzer is loaded in a new namespace under ~analyzers. In this case, the motors namespace.
type: All analyzers, including the GenericAnalyzer, use the type parameter to load the analyzers as plugins. The type parameter is the class name of the Analyzer plugin.
contains: In this case, the GenericAnalyzer will analyze any value that contains "motor". We'll explain options for matching diagnostics data besides contains below.
For more details on loading diagnostic analyzers into the aggregator_node, see Configuring Diagnostic Aggregators.
Analyzing a Device Driver
Let's analyze the diagnostics from a hokuyo_node like the example above. As we can see from the example input, all the incoming data has names starting with "tilt_hokuyo_node". The GenericAnalyzer can be set up to collect any data that starts with a certain prefix.
Add this in the YAML file for the aggregator_node:
analyzers: tilt_hokuyo: type: GenericAnalyzer path: Tilt Hokuyo startswith: tilt_hokuyo_node
Now any diagnostic item with a name that starts with "tilt_hokuyo_node" will be collected under "Tilt Hokuyo".
Unfortunately, this still leaves the ugly "tilt_hokuyo_node" prefix in front of every status name. Since all the data will be under the "Tilt Hokuyo" path, this is unnecessary. To get rid of this, add:
remove_prefix: tilt_hokuyo_node
To the end of the file.
For shorthand:
find_and_remove_prefix: tilt_hokuyo_node
We need to do one more thing to the Hokuyo analyzer. If the Hokuyo crashes after launch, we simply won't see it in the diagnostics. We can add a num_items parameter to the GenericAnalyzer to make sure we have an exact number of diagnostic items.
The Tilt Hokuyo analyzer parameters become:
analyzers: tilt_hokuyo: type: GenericAnalyzer path: Tilt Hokuyo find_and_remove_prefix: tilt_hokuyo_node num_items: 3
Now we will monitor everything from the "tilt_hokuyo_node", clean up the processed names, and if we don't get any data from the node, the analyzer will report that items are missing.
Analyzing a PR2 Power System
The following parameters will create a GenericAnalyzer to monitor a PR2 power system.
analyzers: powersystem: type: GenericAnalyzer prefix: Power System expected: [ 'IBPS 0', 'IBPS 1'] startswith: [ 'Smart Battery'] name: [ 'Power Node 1018'] contains: [ 'Battery'] timeout: 10
That would create a GenericAnalyzer that will process any diagnostic_msgs/DiagnosticStatus messages that have a name that matches the given criteria ("startswith", "contains", "name").
The timeout parameter tells the GenericAnalyzer to mark any item that hasn't been updated in the timeout as "Stale". It will show up with a special "Stale" icon in the robot_monitor. The default it 5.0 seconds. Using this for the power system is important, since the battery drivers don't always update quickly.
Analyzing Controllers
The PR2 controllers control the motion of the robot. The controllers are loaded and unloaded while the robot is operating by pr2_controller_manager.
analyzers: controllers: type: GenericAnalyzer path: Controllers name: [ 'pr2_base_controller', 'torso_trajectory_controller' ] expected: 'Realtime Control Loop' regex: 'control*' discard_stale: true
name - The name parameter requires an exact name match. Can be string or list.
expected - An expected item requires an exact name match. If it is not present, it will be reported as stale and missing. Can be string or list.
regex - Users might feel more comfortable with regular expressions to configure their analyzer. Use the regex parameter to give regex values. Can be string or list.
discard_stale - Since controllers can be unloaded by the pr2_controller_manager, we don't want to report controllers in a "Stale" state if we haven't heard from them. Any item that isn't updated in the timeout will be discarded. Since the "Realtime Control Loop" is "expected", we never discard it.
More Tips
Top Level Status
The GenericAnalyzer reports a "top-level" status, with the name of "path". In the controllers example above, the top-level name is "Controllers". The status level (OK/Warning/Error/Stale) of the top-level is determined by the children.
- Maximum of all children - The top-level status is max of all children. A child in warning makes the parent go to warning.
- Stale children mean "Error" - If any child is stale, the top-level status will be "Error", unless...
All stale children is "Stale" - If all children are stale, the top-level status will be "Stale", and have the message "All Stale"
Timeouts
The timeout parameter is used to mark items as stale. Any item that disappears for longer than the timeout is marked as stale, and will show up with a stale icon in the robot_monitor. A GenericAnalyzer with one or more stale items will have an error state for its top level status. Default timeout is 5 seconds. A timeout of less than zero means diagnostic data will never be marked stale.
Formatting parameters
The configuration parameters below can be given as strings or a list of strings.
startswith
contains
name
expected
remove_prefix
find_and_remove_prefix
regex