Skip to content

ARSControl/filters_c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Filters

[Ars Control Lab page] [Andrea Pupa] [Italo Almirante]

This repo implements several signals/commands filters as c++ classes, under the same namespace.

Installation

To install the library, follow the instructions below (jump the workspace command line if you already have it):

mdkir -p your_catkin_ws/src
cd your_catkin_ws/src
git clone git@github.com:ARSControl/filters_c.git
cd ..
catkin_build

Alternatively, you can compile using the command

catkin_make

How to use

The available filters are:

butterworth_filter
hystheresis
mobile_average_filter    
rc_filter

Filters theory details

  1. Buttherworth Filter:

    It's a low pass filter which implements the following formulas:

     low_pass_filter_coeff = 2;                              // default value
     scale_term_     = 1.0 / (1.0 + low_pass_filter_coeff);  // averages all measurements
     feedback_term_  = 1.0 - low_pass_filter_coeff;          // weight of previous filter
    
     x_f[k] = scale_term_*{x[k] + x[k-1] - f*x_f[k-1]};
    

    where x_f[k] is the filtered measurement at the instant k, x_f[k-1] is the filtered measurement at the instant k-1, x[k] is the measurement at the instant k and x[k-1] is the measurement at the instant k-1.

    The bigger the coefficient, the more you consider the last filtered signal(s). The lower it is, the more you consider the last not-filtered signal(s).

  2. Hysteresis:

    It's a filter which nulls one of the dimensions of the signal when it overcomes a given threshold. If such a signal is over the value for a certain number of times, the hysteresis is turned off.

  3. Mobile Average Filter:

    It's a low pass filter which implements the following formulas:

     X[i]            = X[i+1] for i = 0 ... window_size - 1;
     X[window_size]  = x[k];
     x_f[k]          = X*c    for i = 0 ... window_size;
    

    where x_f[k] is the filtered signal at instant k, x[k] is the measurement at instant k, X is the matrices with the last "window_size" measurements (the windows are on the rows and the dimensions on the columns), and "c" is a vector of coefficients which weights the importance given to the last "window_size" measurements (by default, they are set all as equally important, and they sum to 1 to grant the correct averaging computation).

  4. RC Filter:

    It's the standard implementation of the low-pass RC filter. It depends on params "fs" (cut off frequency) and "ts" (sampling time of the filter's calculations). Two options are implemented to give the chance to make a faster (and approximate) formula or a slower (and more accurate) one. See "Use a filter" section for details. The two aforementioned formulas deal with the factor "alpha" which regulates the filter, here below explained:

     alpha = 1 - std::exp(-2 * M_PI * fs * ts);                  // Simplified version
    
     alpha = (2 * M_PI * ts * fs) / ( 2 * M_PI * ts* fs + 1);    // Extended   version
    

    After the above parameters are set, the filtering occurs as below:

     x_f[k] = x_f[k-1] +  (x[k] - x_f[k-1]) * alpha;
    

    where x_f[k] is the filtered signal at instant k, x_f[k-1] is the filtered signal at instant k-1 and x[k] is the new signal measured.

Include the libary in your project

To include the library, write the following line in your "package.xml" file within your personal package

<depend>filters</depend>

and the following line in your "CMakeLists.txt" file within your personal package.

find_package(filters)

Call a filter

To create and use a filter within your code, you can find their corresponding attributes in the "src" and "include" folders. The instantiation of a filter object should be done in your header file with the following lines:

#include <filters/RCFilter.h>
filters::RCFilter *filter_;

To use the variable "filter_" in your source file, call:

filter_ = new filters::RCFilter(<attribute_1>, <attribute_2>, ...);

Use a filter

  1. Buttherworth Filter:

     ButterworthFilter(int dim, double low_pass_filter_coeff);
    

    Use the above line to call a Butterworth filter were "dim" is the dimension of the data to filter (e.g. if you have a state described as [x,y], your dimension is 2) and "low_pass_filter_coeff" is the coefficient which implements the filter. Its default (and suggested) value is 2.

    To apply the filter in your code, apply the following code:

     filter_ = new filters::ButterworthFilter(your_dim, your_coeff);
     /*
         Get your measurement
     */
     Eigen::VectorXd          measurement = get_your_measurement();
     Eigen::VectorXd filtered_measurement = filter_.filter(measurement);
    

    To reset the filter:

     Eigen::VectorXd reset_data = Eigen::VectorXd::Zero(dim); 
     filter_->reset(reset_data);
    
  2. Hysteresis:

     Hysteresis(int dim, double          onThreshold, int offWindow);
     Hysteresis(int dim, Eigen::VectorXd onThreshold, Eigen::VectorXd offWindow);
    

    Use the above line to call a Hysteresis filter were "dim" is the dimension of the data to filter (e.g. if you have a state described as [x,y], your dimension is 2) "onThreshold" is the threshold to activate the filter and "offWindow" is the number of samples required to turn off hysteresis.

    To apply the filter in your code, apply the following code:

     filter_ = new filters::Hysteresis(your_dim, your_onThreshold, your_offWindow);
     /*
         Get your measurement
     */
     Eigen::VectorXd          measurement = get_your_measurement();
     Eigen::VectorXd filtered_measurement = filter_.apply(measurement);
    

    To reset the filter:

     Eigen::VectorXd reset_data = Eigen::VectorXd::Zero(dim); 
     filter_->reset(reset_data);
    
  3. Mobile Average Filter:

     MobileAverageFilter(int dim, int window, Eigen::VectorXd coefficients);
    

    Use the above line to call a Mobile Average filter were "dim" is the dimension of the data to filter (e.g. if you have a state described as [x,y], your dimension is 2), "window" is the number of last measurements to filter, and "coefficients" are the weight to average such measurements.

    To apply the filter in your code, apply the following code:

     filter_ = new filters::MobileAverageFilter(your_dim, your_window_size, your_coeff);
     /*
         Get your measurement
     */
     Eigen::VectorXd          measurement = get_your_measurement();
     Eigen::VectorXd filtered_measurement = filter_.filter(measurement);
    

    To reset the filter:

     Eigen::VectorXd reset_data = Eigen::VectorXd::Zero(dim); 
     filter_->reset(reset_data);
    
  4. RC Filter:

     RCFilter(int dim, double cut_off_frequency, double sampling_time, bool simplified = false);
    

    Use the above line to call a RCFilter filter were "dim" is the dimension of the data to filter (e.g. if you have a state described as [x,y], your dimension is 2), "cut_off_frequency" is the upper frequency of the filter and "sampling_time" is its time sample for calculations. The attribute "simplified" is done to have the possibility to implement a faster approximated formula.

    To apply the filter in your code, apply the following code:

     filter_ = new filters::RCFilter(your_dim, your_freq, your_ts);
     /*
         Get your measurement
     */
     Eigen::VectorXd          measurement = get_your_measurement();
     Eigen::VectorXd filtered_measurement = filter_.filter(measurement);
    

    To reset the filter:

     Eigen::VectorXd reset_data = Eigen::VectorXd::Zero(dim); 
     filter_->reset(reset_data);
    

Optimized compiler

If you want to speed your code running performances, you can add the following lines to the "CMakeLists".txt of this package:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")

Or alternatively:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")

Your code should run faster, despite the longer compiler time needed. By default, O3 is set. You can maually comment it, but it's strongly suggested to use it.

Issues

Please if you have any issue in compiling the nodes or using it, you can open an issue on git or send me an email at my email address: andrea.pupa@unimore.it.

About

This repo implements several signals/commands filters as c++ classes, under the same namespace.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors