Skip to content

Aggregator Example

For the aggregator present some hierarchy, you have to specify a yaml file with the analyzers.

/status_aggregator/config/mvector

pub_rate: 2.0
analyzers:
    sensors:
      type: diagnostic_aggregator/StatusAnalyzer
      path: Sensors
      analyzers:
        leaks:    
            type: diagnostic_aggregator/GenericAnalyzer
            path: Leaks
            contains: Leaks
        pressure:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Pressure
            contains: Pressure
        temp:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Temperature
            contains: Temperature
        imu:
            type: diagnostic_aggregator/GenericAnalyzer
            path: IMU
            contains: IMU
        gps:
            type: diagnostic_aggregator/GenericAnalyzer
            path: GPS
            contains: GPS
        altimeter:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Altimeter
            contains: Altimeter
        depth_cell:
            type: diagnostic_aggregator/GenericAnalyzer
            path: DepthCell
            contains: DepthCell
        dvl:
            type: diagnostic_aggregator/GenericAnalyzer
            path: DVL
            contains: DVL
    actuators:
      type: diagnostic_aggregator/StatusAnalyzer
      path: Actuators
      analyzers:
        thruster_0:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Thruster0
            contains: Thruster0
        thruster_1:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Thruster1
            contains: Thruster1
        thruster_3:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Thruster3
            contains: Thruster3
        thruster_2:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Thruster2
            contains: Thruster2
        thruster_4:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Thruster4
            contains: Thruster4
        thruster_5:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Thruster5
            contains: Thruster5
    power_system:
      type: diagnostic_aggregator/StatusAnalyzer
      path: Power System
      analyzers:
        batmonit:
            type: diagnostic_aggregator/GenericAnalyzer
            path: Batmonit
            contains: Batmonit

This yaml file can have 3 parameters:

  • The pub_rate which is the frequency at which the aggregator publishes to the /diagnostics_agg topic.
  • The base_path (and a secret one, path) which adds an additional root level in the hierarchy (e.g. /MyRobot/Sensors/IMU/…). But it’s useless, since there can only be one aggregator in the system, and so the separation between different robots cannot happen at this level. Thus, you can simply ignore it!
  • The analyzers which is a list of… you guessed it, analyzers. The analyzers have a type, a name (a.k.a. path), and several options for matching criteria. The type can be GenericAnalyzer which does a grouping of status items based on their name or StatusAnalyzer which does a categorization of analyzers (e.g. Sensors/..., Actuators/..., Power System/...).

Now, comes the interesting part. What if we want to react to an error? We’ll have to write an analyzer that does this. But we won’t just write an analyzer. Since the categorization offered by the default analyzers is always relevant, we’ll extend the generic or group analyzers so that we maintain their functionality. The analyzers have two methods that can be of interest:

  • The analyze method which can be useful for processing the data of a status message before we store it.
  • The report method which can be used to make a decision based on the status messages to be reported by the analyzer.

In the accompanying code, there are two analyzers. One is based on the GroupAnalyzer and the other is based on the GenericAnalyzer. They both rely on the report method. They look at the reported statuses by their parent class and they publish a message if a condition is met. The StatusAnalyzer finds a group (/Sensors, /Actuator, or Power System) status and reacts when its level transitions from OK to something else. The GenericAnalyzer is the default one, but you can have specific ones for your needs. Any required parameters are provided in the yaml file.

Extending an analyzer

First make a analyzer_plugins.xml file, like the following:

<library path="lib/libstatus_aggregator_analyzers">
  <class name="diagnostic_aggregator/StatusAnalyzer" type="diagnostic_aggregator::StatusAnalyzer" base_class_type="diagnostic_aggregator::Analyzer">
    <description>
      StatusAnalyzer is a diagnostic analyzer for a group of devices (sensors, actuators, power system).
    </description>
  </class>
</library>

In the include file (include/status_aggregator_ros/StatusAnalyzer.h) you should inherit the base class AnalyzerGroup and override the methods init() and report():

class StatusAnalyzer : public AnalyzerGroup {
 public:
  StatusAnalyzer();

  bool init(const std::string base_path, const ros::NodeHandle &n) override;
  std::vector<diagnostic_msgs::DiagnosticStatusPtr> report() override;

In the cpp file (src/status_aggregator_ros/StatusAnalyzer.cpp) change the methods accordingly your needs.


Last update: May 30, 2022
Back to top