The Reporting Component

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation, with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of this license can be found at http://www.fsf.org/copyleft/fdl.html.


Table of Contents

1. Introduction
1.1. Principle
2. Setup Procedure
2.1. Property Configuration File
2.2. ReportData section
2.3. Reading the configuration file
2.4. Scripting commands

1. Introduction

This document describes the Orocos OCL::ReportingComponent for monitoring and capturing data exchanged between Orocos components.

1.1. Principle

Each Orocos component can have one or more data ports. One can configure the reporting components such that one or more ports are captured of one or more peer components. The sample rate and the file format can be selected.

A common usage scenario of the OCL::ReportingComponent goes as follows. An Orocos application is created which contains a reporting component and various other components. The reporting component is peer-connected to all components which must be monitored. An XML file or script command defines which data ports to log. When the reporting component is started, it reads the ports and writes the exchanged data to a file at a given sample rate.

Figure 1. Component Reporting Example

Component Reporting Example


One can not use the OCL::ReportingComponent directly but must use a derived component which implements the method of writing out the data. There exists two variants: OCL::FileReporting for writing data to a file and OCL::ConsoleReporting which prints the data directly to the screen. These two examples can aid you in writing your own data format or to transfer data over a network connection.

2. Setup Procedure

The OCL::ReportingComponent is configured using a single XML file which sets the component's properties and describes which components and ports to monitor.

In order to report data of other components, they must be added as a Peer to the reporting component. The following C++ setup code does this for the example above (Figure 1, “Component Reporting Example”):

  #include <ocl/FileReporting.hpp>

  // ...
  OCL::FileReporting reporter("Reporter");
  Controller controller("Controller");
  Plant      plant("Plant");
  Camera     cam0("Camera");

  reporter.addPeer( &controller );
  reporter.addPeer( &camera );
  controller.addPeer( &plant );

Alternatively, if you use the Deployer, you might add this listing to your application XML file, instead of using the hard-coded C++ setup above:

   <simple name="Import" type="string"><value>/usr/lib/liborocos-reporting</value></simple>

  <struct name="Reporter" type="OCL::FileReporting">
    <struct name="Activity" type="PeriodicActivity">
      <simple name="Period" type="double"><value>0.01</value></simple>
      <simple name="Priority" type="short"><value>0</value></simple>
      <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple>
    </struct>
    <simple name="AutoConf" type="boolean"><value>1</value></simple>
    <simple name="AutoStart" type="boolean"><value>0</value></simple>
    <simple name="AutoSave" type="boolean"><value>1</value></simple>
    <simple name="LoadProperties" type="string"><value>reporting.cpf</value></simple>
    <!-- List all peers (uni-directional) -->
    <struct name="Peers" type="PropertyBag">
      <simple type="string"><value>Controller</value></simple>
      <simple type="string"><value>Camera</value></simple>
    </struct>

Note that the AutoSave flag is turned on (this is optional) to save the settings when the Reporter component is cleaned up by the Deployer.

2.1. Property Configuration File

This is an example property file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "cpf.dtd">
<properties>
  <simple name="AutoTrigger" type="boolean"><description>When set to 1, the data is taken upon each update(), otherwise, the data is only taken when the user invokes 'snapshot()'.</description><value>1</value></simple>
  <simple name="WriteHeader" type="boolean"><description>Set to true to start each report with a header.</description><value>1</value></simple>
  <simple name="Decompose" type="boolean"><description>Set to true to decompose data ports.</description><value>1</value></simple>
  <simple name="ReportFile" type="string"><description>Location on disc to store the reports.</description><value>reports.dat</value></simple>
  <simple name="Synchronize" type="boolean"><description>Set to true if the timestamp should be synchronized with the logging</description><value>0</value></simple>

  <struct name="ReportData" type="PropertyBag">
     <description>A PropertyBag which defines which ports or components to report.</description>
     <simple name="Component" type="string"><value>Camera</value></simple>

     <simple name="Port" type="string"><value>Controller.SensorValues</value></simple>
     <simple name="Port" type="string"><value>Controller.SteeringSignals</value></simple>
  </struct>
</properties>

The AutoTrigger property toggles if the data is captured at the time a new line is written to file or at a user determined time. If AutoTrigger is set to false, a data snapshot is taken when the user invokes the snapshot() method of the ReportingComponent.

If WriteHeader is set to true, a header will be written describing the file format layout.

If Decompose is set to true, complex data on ports will be decomposed into separate table columns. Otherwise, each port appears as one column.

2.2. ReportData section

The ReportData struct describes the ports to monitor. As the example shows (see also Figure 1, “Component Reporting Example”), a complete component can be monitored (Camera) or specific ports of a peer component can be monitored. The reporting component can monitor any data type as long as it is known in the Orocos type system. Extending the type system is explained in the Plugin Manual of the Real-Time Toolkit.

2.3. Reading the configuration file

The property file of the reporting component must be read with the loadProperties script method:

  marshalling.loadProperties("reporting.cpf")

You can not use readProperties() because only loadProperties loads your ReportData struct into the ReportingComponent.

With

  marshalling.writeProperties("reporting.cpf")

, the current configuration can be written to disk again.

2.4. Scripting commands

The scripting commands of the reporting components can be listed using the this command on the TaskBrowser. Below is a snippet of the output:

  Method     : bool reportComponent( string const& Component )
   Add a Component for reporting. Only works if Component is connected.
   Component : Name of the Component
  Method     : bool reportData( string const& Component, string const& DataObject )
   Add a Component's DataSource for reporting. Only works if DataObject exists and Component is connected.
   Component : Name of the Component
   DataObject : Name of the DataObject. For example, a property or attribute.
  Method     : bool reportPort( string const& Component, string const& Port )
   Add a Component's Connection or Port for reporting.
   Component : Name of the Component
   Port : Name of the Port to the connection.
  Method     : bool screenComponent( string const& Component )
   Display the variables and ports of a Component.
   Component : Name of the Component
  Method     : void snapshot( )
   Take a new shapshot of the data and set the timestamp.
  Method     : bool unreportComponent( string const& Component )
   Remove a Component from reporting.
   Component : Name of the Component
  Method     : bool unreportData( string const& Component, string const& DataObject )
   Remove a DataObject from reporting.
   Component : Name of the Component
   DataObject : Name of the DataObject.
  Method     : bool unreportPort( string const& Component, string const& Port )
   Remove a Connection for reporting.
   Component : Name of the Component
   Port : Name of the Port to the connection.