low_pass_filter.h
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright 2016 Intelligent Industrial Robotics (IIROB) Group,
4  * Institute for Anthropomatics and Robotics (IAR) -
5  * Intelligent Process Control and Robotics (IPR),
6  * Karlsruhe Institute of Technology (KIT)
7  *
8  * Author: Denis Štogl, email: denis.stogl@kit.edu
9  *
10  * Date of creation: 2016
11  *
12  * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13  *
14  * Redistribution and use in source and binary forms,
15  * with or without modification, are permitted provided
16  * that the following conditions are met:
17  *
18  * * Redistributions of source code must retain the above copyright
19  * notice, this list of conditions and the following disclaimer.
20  * * Redistributions in binary form must reproduce the above copyright
21  * notice, this list of conditions and the following disclaimer in the
22  * documentation and/or other materials provided with the distribution.
23  * * Neither the name of the copyright holder nor the names of its
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * This package is free software: you can redistribute it and/or modify
28  * it under the terms of the GNU Lesser General Public License as published by
29  * the Free Software Foundation, either version 3 of the License, or
30  * (at your option) any later version.
31  *
32  * This package is distributed in the hope that it will be useful,
33  * but WITHOUT ANY WARRANTY; without even the implied warranty of
34  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35  * GNU Lesser General Public License for more details.
36  *
37  * You should have received a copy of the GNU Lesser General Public License
38  * along with this package. If not, see <http://www.gnu.org/licenses/>.
39 *****************************************************************************/
40 
41 #ifndef IIROB_FILTERS_LOW_PASS_FILTER_H
42 #define IIROB_FILTERS_LOW_PASS_FILTER_H
43 
44 #include <ros/ros.h>
45 #include <geometry_msgs/WrenchStamped.h>
47 #include <iirob_filters/LowPassFilterParameters.h>
48 #include <iirob_filters/LowPassFilterConfig.h>
49 #include <dynamic_reconfigure/server.h>
50 #include <filters/filter_base.h>
51 
52 #include <math.h>
53 
54 namespace iirob_filters{
55 template <typename T>
57 {
58 public:
59  LowPassFilter();
60 
62  virtual bool configure();
63  virtual bool update(const T& data_in, T& data_out);
64 
65 private:
66  // Parameters
70  int divider_;
71  std::map<std::string,std::string> map_param_;
72 
73  // Filter parameters
74  double b1;
75  double a1;
77  iirob_filters::LowPassFilterParameters params_;
79 
80  Eigen::Matrix<double,6,1> msg_filtered, msg_filtered_old, msg_old;
81 
82  dynamic_reconfigure::Server<iirob_filters::LowPassFilterConfig> reconfigCalibrationSrv_; // Dynamic reconfiguration service
83  void reconfigureConfigurationRequest(iirob_filters::LowPassFilterConfig& config, uint32_t level);
84 };
85 
86 
87 template <typename T>
88 LowPassFilter<T>::LowPassFilter():params_{ros::NodeHandle("~/LowPassFilter/params").getNamespace()}
89 {
90  reconfigCalibrationSrv_.setCallback(boost::bind(&LowPassFilter<T>::reconfigureConfigurationRequest, this, _1, _2));
91 }
92 
93 template <typename T>
95 {
96 }
97 
98 template <typename T>
100 {
101  params_.fromParamServer();
102  sampling_frequency_ = params_.SamplingFrequency;
103  damping_frequency_ = params_.DampingFrequency;
104  damping_intensity_ = params_.DampingIntensity;
105  divider_ = params_.divider;
106  if(sampling_frequency_ == 0)
107  ROS_ERROR("LowPassFilter did not find param SamplingFrequency");
108  if(damping_frequency_ == 0)
109  ROS_ERROR("LowPassFilter did not find param DampingFrequency");
110  if(damping_intensity_ == 0)
111  ROS_ERROR("LowPassFilter did not find param DampingIntensity");
112  if(divider_ == 0)
113  ROS_ERROR("Divider value not correct - cannot be 0. Check .param or .yaml files");
114 
115  ROS_INFO("Low Pass Filter Params: Sampling Frequency:%f, Damping Frequency:%f, Damping Intensity:%f; Divider: %d " ,
117 
118  a1 = exp(-1 / sampling_frequency_ * (2 * M_PI * damping_frequency_) / (pow(10, damping_intensity_ / -10.0)));
119  b1 = 1 - a1;
120 
121  divider_counter = 1;
122  // Initialize storage Vectors
124  for (int ii=0; ii<6; ii++)
125  {
126  msg_filtered(ii) = msg_filtered_old(ii) = msg_old(ii) = 0;
127  }
128  return true;
129 }
130 
131 template<>
132 inline bool LowPassFilter<geometry_msgs::WrenchStamped>::update(const geometry_msgs::WrenchStamped& data_in, geometry_msgs::WrenchStamped& data_out){
133  // IIR Filter
135  msg_filtered_old = msg_filtered;
136 
137  //TODO use wrenchMsgToEigen
138  msg_old[0] = data_in.wrench.force.x;
139  msg_old[1] = data_in.wrench.force.y;
140  msg_old[2] = data_in.wrench.force.z;
141  msg_old[3] = data_in.wrench.torque.x;
142  msg_old[4] = data_in.wrench.torque.y;
143  msg_old[5] = data_in.wrench.torque.z;
144 
145  data_out.wrench.force.x = msg_filtered[0];
146  data_out.wrench.force.y = msg_filtered[1];
147  data_out.wrench.force.z = msg_filtered[2];
148  data_out.wrench.torque.x = msg_filtered[3];
149  data_out.wrench.torque.y = msg_filtered[4];
150  data_out.wrench.torque.z = msg_filtered[5];
151  return true;
152 }
153 
154 template<typename T>
155 bool LowPassFilter<T>::update(const T& data_in, T& data_out)
156 {
157  data_out = b1 * old_value + a1 * filtered_old_value;
158  filtered_old_value = data_out;
159  old_value = data_in;
160 
161  return true;
162 }
163 
164 template <typename T>
165 void LowPassFilter<T>::reconfigureConfigurationRequest(iirob_filters::LowPassFilterConfig& config, uint32_t level)
166 {
167  //params_.fromConfig(config);
168  sampling_frequency_ = params_.SamplingFrequency;
169  damping_intensity_ = params_.DampingFrequency;
170  damping_intensity_ = params_.DampingIntensity;
171  divider_ = params_.divider;
172 };
173 
174 /* A lp filter which works on double arrays.
175  *
176  */
177 template <typename T>
179 {
180 public:
183 
187 
188  virtual bool configure();
189 
194  virtual bool update( const std::vector<T> & data_in, std::vector<T>& data_out);
195 
196 protected:
197 
201  int divider_;
202 
203  // Filter parametrs
205  double b1;
206  double a1;
207 
208  iirob_filters::LowPassFilterParameters params_;
210 
212 };
213 
214 
215 template <typename T>
217 {
218 }
219 
220 template <typename T>
222 {
223 }
224 
225 template <typename T>
227 {
228  params_.fromParamServer();
229  sampling_frequency_ = params_.SamplingFrequency;
230  damping_frequency_ = params_.DampingFrequency;
231  damping_intensity_ = params_.DampingIntensity;
232  divider_ = params_.divider;
233  if(sampling_frequency_ == 0)
234  ROS_ERROR("MultiChannelLowPassFilter did not find param SamplingFrequency");
235  if(damping_frequency_ == 0)
236  ROS_ERROR("MultiChannelLowPassFilter did not find param DampingFrequency");
237  if(damping_intensity_ == 0)
238  ROS_ERROR("MultiChannelLowPassFilter did not find param DampingIntensity");
239  if(divider_ == 0)
240  ROS_ERROR("Divider value not correct - cannot be 0. Check .param or .yaml files");
241 
242  ROS_INFO("Low Pass Filter Params: Sampling Frequency:%f, Damping Frequency:%f, Damping Intensity:%f; Divider: %d " ,
244 
245  a1 = exp(-1 / sampling_frequency_ * (2 * M_PI * damping_frequency_) / (pow(10, damping_intensity_ / -10.0)));
246  b1 = 1 - a1;
247  divider_counter = 1;
248 
249  // Initialize storage Vectors
250 
251  for (int ii=0; ii<number_of_channels_; ii++)
252  {
253  filtered_value[ii] = filtered_old_value[ii] = old_value[ii] = 0;
254  }
255  return true;
256 }
257 
258 template <typename T>
259 bool MultiChannelLowPassFilter<T>::update(const std::vector<T> & data_in, std::vector<T>& data_out)
260 {
261 
262  if (data_in.size() != number_of_channels_ || data_out.size() != number_of_channels_)
263  {
264  ROS_ERROR("Configured with wrong size config:%d in:%d out:%d", number_of_channels_, (int)data_in.size(), (int)data_out.size());
265  return false;
266  }
267  for (int i = 0; i<data_in.size();i++)
268  {
269  data_out[i] = b1 * old_value[i] + a1 * filtered_old_value[i];
270  filtered_old_value[i] = data_out[i];
271  }
272  old_value = data_in;
273  return true;
274 };
275 
276 }
277 #endif
Eigen::Matrix< double, 6, 1 > msg_filtered
Eigen::Matrix< double, 6, 1 > msg_old
~MultiChannelLowPassFilter()
Destructor to clean up.
iirob_filters::LowPassFilterParameters params_
std::map< std::string, std::string > map_param_
virtual bool update(const std::vector< T > &data_in, std::vector< T > &data_out)
Update the filter and return the data seperately.
void reconfigureConfigurationRequest(iirob_filters::LowPassFilterConfig &config, uint32_t level)
#define ROS_INFO(...)
iirob_filters::LowPassFilterParameters params_
dynamic_reconfigure::Server< iirob_filters::LowPassFilterConfig > reconfigCalibrationSrv_
MultiChannelLowPassFilter()
Construct the filter with the expected width and height.
Eigen::Matrix< double, 6, 1 > msg_filtered_old
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
virtual bool update(const T &data_in, T &data_out)
#define ROS_ERROR(...)


iirob_filters
Author(s): Denis Štogl
autogenerated on Fri Sep 18 2020 03:32:19