wiki:Plugins/laser-filter
Last modified 5 years ago Last modified on 29.01.2014 00:05:14

Laser Distance Data Filter Cascade Plugin

This plugins takes distance data from 2D laser range finders (LRF) and pipes it through filter cascades. A cascade is a sequence of processing steps that filter out, modify, or merge data sources. Examples are limiting laser data a certain angle or distance range, projecting laser data in one coordinate frame into another, or simply reversing the ordering of the beams.

Filtering laser data has several important applications. It can be used to filter out false readings or to combine multiple data sources into one.

Each cascade (see terminology below) is executed in its own thread, therefore all cascades are executed in parallel, with an important exception. If one cascade uses the output of another cascade as its input, the two cascades are synchronized and executed in the proper order.

Terminology

filter
A filter is a single data processor which takes one or more input sources, processes the data, and writes its output to exactly one output source.
cascade
A cascade is a sequence of filters which are executed in a strictly linear fashion.
cascade synchronization
If the output of one cascade is the input of another, the two cascades are executed in sequence one after another by synchronizing them.

Supported Filters

Here we first give an overview of the supported filters and their purpose. Below you can find the respective configuration parameters.

720to360
Downsample a !Laser720Interface to a !Laser360Interface by dropping every second value.
reverse
Reverse the angle ordering in the interface. This has been added for compatibility with other software frameworks, in particular our own old framework (not released to the public). It should only be used to create Fawkes-compatible angle ordering and avoided if possible.
max_circle
All distances longer than a given maximum are set to said maximum.
min_circle
All distances shorter than a given minimum are set to zero (invalid).
circle_sector
Filter out all distance values which are not in a particular parameterized circle sector (given by start and end angle). The removed values are set to zero on the output, all others are copied from he input.
deadspots
Remove certain angle ranges which do not produce valid data. For example, for a 360° laser scanner there might be rods for mounting additional equipment levels above the laser. The filter would then be used to filter out short/erroneous values at these rods.
min_merge
Merge data of any number of input interfaces by setting each distance value to the shortest value of any of the input interfaces.
projection
Project data of a laser in one coordinate frame into a laser plane in another coordinate frame. For example, when having one horizontal laser plane and another vertical or angled plane, data from the latter plane might be projected into the horizontal plane. We use this to detect obstacles like tables, otherwise virtually invisible to the horizontal laser, and by projecting them into the horizontal plane we can use this as input data for our collision avoidance component without modifying that component.

This first transforms the laser values into the target frame, and then projects it into the X-Y plane (which is assumed to be the laser plane of another (virtual) laser. Additionally some sanity filtering in all three axes is applied after the transformation, but before the projection.

Configuration

The configuration is flexible and allows for any number of cascades consisting of an arbitrary number of filters. A cascades input can have multiple input interfaces, in which case the first filter of the cascade must support multiple inputs (see below). The principle items of a cascade entry are: input interface(s), output interface, filters. Filters can have specific parameterization. Each cascade has the following layout:

plugins/laser-filter:
  cascade-name:
    in:
      in_name1: Laser360Interface::Interface ID
      # optional:
      in_name2: Laser360Interface::Another Interface
    out:
      out_name: Laser360Interface::Cascade X Output
    filters:
      # Downscale
      1-filter-name: filter-type
      1-filter-name/param: parameter-value
      # optional any number of additional filters, like
      2-filter-name: filter-type

Here, the following place holders need to be changed:

cascade-name
An arbitrary string without spaces identifying this cascade
in_nameN
An arbitrary string without spaces identifying an input interface
out_name
An arbitrary string without spaces identifying the output interface
filter-name
An arbitrary string without spaces identifying a filtering step. The filters are ordered alphabetically. Therefore we recommend to prefix the filter name with a number to have a predictive ordering.
filter-type
One of the filter types mentioned above.
param
A filter-type specific parameter name and its value.

The specific parameters for the supported filter types are:

720to360

  • average (bool): if true average two adjacent values into one for downscaling.
max_circle
  • radius (float): the maximum value for distance data, longer distances are set to the maximum value.
min_circle
  • radius (float): the minimum value for distance data, shorter distances are set to zero.
circle_sector
  • from (unsigned int): index in input data where to start copying
  • to (unsigned int): index in input data to which to copy data The filter supports having smaller to than from indexes, in which case it will use the data across the discontinuity at 0°/360°.
deadspots
Any number of dead spots given as an arbitrary identifier and start and end angles like so:
    filters:
      1-deadspots: deadspots
        1-deadspots/spot1/start: 5
        1-deadspots/spot1/end: 10
        1-deadspots/spot2/start: 50
        1-deadspots/spot3/end: 60
This example will filter out two spots, one from 5° to 10°, the other one from 50° to 60°.
projection
  • target_frame (string): coordinate frame ID into which to project
  • not_from_x (float): Lower X bound in target frame for ignored values, i.e. robot rectangle
  • not_to_x (float): Upper X bound in target frame for ignored values, i.e. robot rectangle
  • not_from_y (float): Lower Y bound in target frame for ignored values, i.e. robot rectangle
  • not_to_y (float): Upper Y bound in target frame for ignored values, i.e. robot rectangle
  • only_from_z (float): Minimum Z value in target frame, use to sort out ground and ground noise
  • only_to_z (float): Maximum Z value in target frame, use to filter out too high values, e.g. obstacles under which the robot can pass and especially ceiling Example:
          4-projection: projection
          4-projection/target_frame: !frame /base_laser
          4-projection/not_from_x: -0.07
          4-projection/not_to_x: 0.31
          4-projection/not_from_y: -0.2
          4-projection/not_to_y: 0.2
          4-projection/only_from_z: -0.2
          4-projection/only_to_z: 1.5
    

BlackBoard Interfaces

The blackboard interfaces depend on the particular cascade configuration. Any input interface will be opened for reading, any output interface will be opened for writing. If an output interface of one cascade is the input of another cascade it will be opened for both, writing and reading.

Compilation and Runtime Requirements

  • Laser plugin for laser input
  • Optional: LaserGUI for visualization
  • Optional: ros, ros-tf, ros-laserscan, rviz for visualization in rviz

Usage Instructions

After compiling the plugin setup a minimal configuration, e.g. for a maximum filtering of the data like this:

plugins/laser-filter:
  urg:
    in:
      urg: Laser360Interface::Laser urg
    out:
      filtered: Laser360Interface::Laser urg max
    filters:
      1-max: max_circle
      # Radius of minimum length. m
      1-max/radius: 1.3

Run this filter on some input data gathered from your sensor or simulation and observe the output in the LaserGUI?, rviz, or in the blackboard via webview. Try different radii and observe the changed output. Then step by step add some more filters to the cascade, e.g. add a min_filter to filter out short values. Then split these filters into two dependent cascades.