00001 /* 00002 * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA) 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 00018 #ifndef COB_TWIST_CONTROLLER_UTILS_MOVING_AVERAGE_H 00019 #define COB_TWIST_CONTROLLER_UTILS_MOVING_AVERAGE_H 00020 00021 #include <stdint.h> 00022 #include <ros/ros.h> 00023 #include <deque> 00024 00025 template 00026 <typename T> 00027 class MovingAverageBase 00028 { 00029 public: 00030 explicit MovingAverageBase() 00031 {} 00032 00033 virtual void reset() = 0; 00034 virtual void addElement(T element) = 0; 00035 virtual bool calcMovingAverage(T& average) const = 0; 00036 }; 00037 00038 template 00039 <typename T> 00040 class MovingAverageSimple : public MovingAverageBase<T> 00041 { 00042 public: 00043 explicit MovingAverageSimple(uint16_t size) 00044 : MovingAverageBase<T>(), 00045 size_(size) 00046 { 00047 weighting_.assign(size_, 1.0); 00048 } 00049 00050 virtual void reset() 00051 { 00052 s_.clear(); 00053 } 00054 00055 virtual void addElement(T element) 00056 { 00057 if (s_.size() < size_) 00058 { 00059 s_.push_front(element); 00060 } 00061 else 00062 { 00063 s_.pop_back(); 00064 s_.push_front(element); 00065 } 00066 } 00067 00068 virtual bool calcMovingAverage(T& average) const 00069 { 00070 if (!s_.empty()) 00071 { 00072 T sum; 00073 T diff; 00074 for (uint16_t i = 0; i < s_.size(); ++i) 00075 { 00076 sum += s_[i] * weighting_[i]; 00077 diff += weighting_[i]; 00078 } 00079 average = sum / diff; 00080 return true; 00081 } 00082 else 00083 { 00084 // no element available 00085 return false; 00086 } 00087 } 00088 00089 protected: 00090 uint16_t size_; 00091 std::deque<T> s_; 00092 std::deque<double> weighting_; 00093 }; 00094 00095 template 00096 <typename T> 00097 class MovingAverageWeighted : public MovingAverageSimple<T> 00098 { 00099 public: 00100 explicit MovingAverageWeighted(uint16_t size) 00101 : MovingAverageSimple<T>(size) 00102 { 00103 this->weighting_.clear(); 00104 for (uint16_t i = 0; i < this->size_; i++) 00105 { 00106 this->weighting_.push_front(triangle(i)); 00107 } 00108 } 00109 00110 private: 00111 double triangle(uint16_t n) 00112 { 00113 if (n == 0) 00114 { 00115 return 0.0; 00116 } 00117 else 00118 { 00119 return static_cast<double>(n)*(static_cast<double>(n)+1.0)/2.0; 00120 } 00121 } 00122 }; 00123 00124 template 00125 <typename T> 00126 class MovingAverageExponential : public MovingAverageBase<T> 00127 { 00128 public: 00129 explicit MovingAverageExponential(double factor) 00130 : MovingAverageBase<T>(), 00131 factor_(factor) 00132 { 00133 empty_ = true; 00134 } 00135 00136 virtual void reset() 00137 { 00138 average_ = T(); 00139 empty_ = true; 00140 } 00141 00142 void addElement(T element) 00143 { 00144 if (empty_) 00145 { 00146 average_ = element; 00147 empty_ = false; 00148 } 00149 else 00150 { 00151 average_ = factor_ * element + (1.0 - factor_) * average_; 00152 } 00153 } 00154 00155 bool calcMovingAverage(T& average) const 00156 { 00157 if (!empty_) 00158 { 00159 average = average_; 00160 return true; 00161 } 00162 else 00163 { 00164 // no element available 00165 return false; 00166 } 00167 } 00168 00169 private: 00170 bool empty_; 00171 double factor_; 00172 T average_; 00173 }; 00174 00175 00176 typedef MovingAverageBase<double> MovingAvgBase_double_t; 00177 typedef MovingAverageSimple<double> MovingAvgSimple_double_t; 00178 typedef MovingAverageWeighted<double> MovingAvgWeighted_double_t; 00179 typedef MovingAverageExponential<double> MovingAvgExponential_double_t; 00180 00181 #endif // COB_TWIST_CONTROLLER_UTILS_MOVING_AVERAGE_H