TorqueFilter/IIRFilter.cpp
Go to the documentation of this file.
1 #include "IIRFilter.h"
2 #include <numeric>
3 
4 IIRFilter::IIRFilter(unsigned int dim, std::vector<double>& fb_coeffs, std::vector<double>& ff_coeffs, const std::string& error_prefix)
5 {
6  std::cerr << "This IIRFilter constructure is obsolated method." << std::endl;
7  m_dimension = dim;
8  m_error_prefix = error_prefix;
9 
10  // init coefficients
11  if(fb_coeffs.size() != dim + 1|| ff_coeffs.size() != dim + 1){
12  std::cout << "[" << m_error_prefix << "]" << "IIRFilter coefficients size error" << std::endl;
13  return;
14  }
15  for(std::vector<double>::iterator it = fb_coeffs.begin(); it != fb_coeffs.end(); it++){
16  m_fb_coefficients.push_back(*it);
17  }
18  for(std::vector<double>::iterator it = ff_coeffs.begin(); it != ff_coeffs.end(); it++){
19  m_ff_coefficients.push_back(*it);
20  }
21 
22  // init previous values
23  m_previous_values.assign(dim, 0.0);
24  m_initialized = true;
25  return;
26 }
27 
28 IIRFilter::IIRFilter(const std::string& error_prefix) :
29  m_initialized(false) {
30  m_error_prefix = error_prefix;
31 }
32 
33 bool IIRFilter::setParameter(int dim, std::vector<double>& A, std::vector<double>& B) {
34  m_dimension = dim;
35 
36  // init coefficients
37  if((A.size() != dim && A.size() != dim + 1) || B.size() != dim + 1) {
38  std::cout << "[" << m_error_prefix << "]" << "IIRFilter coefficients size error" << std::endl;
39  return false;
40  }
41 
42  // clear previous coefficients
43  m_fb_coefficients.clear();
44  m_ff_coefficients.clear();
45 
46  if (A.size() == dim) {
47  m_fb_coefficients.push_back(1.0);
48  }
49  for(std::vector<double>::iterator it = A.begin(); it != A.end(); it++){
50  if (it == A.begin()) {
51  if( *it != 1.0 ) {
52  std::cout << "[" << m_error_prefix << "]" << "IIRFilter : parameter A[0] is not 1.0 !!!" << std::endl;
53  }
54  m_fb_coefficients.push_back(*it);
55  } else {
56  m_fb_coefficients.push_back(- *it);
57  }
58  }
59  for(std::vector<double>::iterator it = B.begin(); it != B.end(); it++){
60  m_ff_coefficients.push_back(*it);
61  }
62 
63  // init previous values
64  m_previous_values.assign(dim, 0.0);
65  m_initialized = true;
66  return true;
67 }
68 
69 bool IIRFilter::setParameterAsBiquad(const double f_cutoff, const double Q, const double hz){
70  std::vector<double> fb_coeffs(3), ff_coeffs(3);
71  const double omega = 2 * 3.14159265 * f_cutoff / hz;
72  const double alpha = std::sin(omega) / (2 * Q);
73  const double denom = 1 + alpha;
74  fb_coeffs[0] = 1;
75  fb_coeffs[1] = -2 * std::cos(omega) / denom;
76  fb_coeffs[2] = (1 - alpha) / denom;
77  ff_coeffs[0] = (1 - std::cos(omega)) / 2 / denom;
78  ff_coeffs[1] = (1 - std::cos(omega)) / denom;
79  ff_coeffs[2] = (1 - std::cos(omega)) / 2 / denom;
80  return this->setParameter(2, fb_coeffs, ff_coeffs);
81 };
82 
83 
84 void IIRFilter::getParameter(int &dim, std::vector<double>& A, std::vector<double>& B)
85 {
86  dim = m_dimension;
87  B.resize(m_ff_coefficients.size());
88  std::copy(m_ff_coefficients.begin(), m_ff_coefficients.end(), B.begin());
89  A.resize(0);
90  for(std::vector<double>::iterator it = m_fb_coefficients.begin();
91  it != m_fb_coefficients.end(); it++) {
92  if (it == m_fb_coefficients.begin()) {
93  A.push_back(*it);
94  } else {
95  A.push_back(- *it);
96  }
97  }
98 }
99 
100 void IIRFilter::reset(double initial_input)
101 {
102  // y[n] = b[0]*w[n] + b[1]*w[n-1] + ... + b[m]*w[n-m] in DirectForm-II.
103  // When n->inf, y[n]->initial_input and w[n], w[n-1], ..., w[n-m] -> w,
104  // m_previous_values should preserve w
105  double sum_ff_coeffs = std::accumulate(m_ff_coefficients.begin(), m_ff_coefficients.end(), 0.0);
106  double reset_val = initial_input / sum_ff_coeffs;
107  m_previous_values.assign(m_dimension, reset_val);
108 }
109 
110 double IIRFilter::passFilter(double input)
111 {
112  // IIRFilter implementation based on DirectForm-II.
113  // Cf. https://en.wikipedia.org/wiki/Digital_filter
114  if (! m_initialized) {
115  return 0.0;
116  }
117  double feedback, filtered;
118  // calcurate retval
119  feedback = m_fb_coefficients[0] * input;
120  for (int i = 0; i < m_dimension; i++) {
121  feedback += m_fb_coefficients[i + 1] * m_previous_values[i];
122  }
123  filtered = m_ff_coefficients[0] * feedback;
124  for(int i = 0; i < m_dimension; i++) {
125  filtered += m_ff_coefficients[i + 1] * m_previous_values[i];
126  }
127  // update previous values
128  m_previous_values.push_front(feedback);
129  m_previous_values.pop_back();
130 
131  return filtered;
132 }
bool setParameterAsBiquad(const double f_cutoff, const double Q, const double hz)
Simple user interface of setParameter.
std::vector< double > m_ff_coefficients
png_uint_32 i
std::string m_error_prefix
double passFilter(double input)
passFilter
bool setParameter(int dim, std::vector< double > &A, std::vector< double > &B)
Set parameters Y[n] = B[0] * X[n] + B[1] * X[n-1] + ... + B[dim] * X[n-dim] - A[1] * Y[n-1] ...
void reset(double initial_input=0.0)
std::vector< double > m_fb_coefficients
void getParameter(int &dim, std::vector< double > &A, std::vector< double > &B)
IIRFilter(const std::string &error_prefix="")
Constructor.
std::deque< double > m_previous_values


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:50