00001 00026 #ifndef _SR_DEADBAND_HPP_ 00027 #define _SR_DEADBAND_HPP_ 00028 00029 #include <sr_utilities/sr_math_utils.hpp> 00030 #include <deque> 00031 00032 namespace sr_deadband 00033 { 00044 template <class T> 00045 static inline bool simple_deadband (T value, T deadband) 00046 { 00047 return ( fabs(value) > deadband ); 00048 } 00049 00050 template <class T> 00051 class HysteresisDeadband 00052 { 00053 public: 00060 HysteresisDeadband() : 00061 last_demand(static_cast<T>(0.0)), entered_small_deadband(false) 00062 { 00063 }; 00064 00065 ~HysteresisDeadband() 00066 {}; 00067 00082 bool is_in_deadband(T demand, T error, T deadband, double deadband_multiplicator = 5.0, unsigned int nb_errors_for_avg = 50) 00083 { 00084 bool is_in_deadband = false; 00085 00086 last_errors.push_back( error ); 00087 double avg_error = 0.0; 00088 for( unsigned int i = 0 ; i < last_errors.size(); ++i ) 00089 { 00090 avg_error += last_errors[i]; 00091 } 00092 avg_error /= last_errors.size(); 00093 00094 // Received a new command: 00095 if( last_demand != demand ) 00096 { 00097 entered_small_deadband = false; 00098 last_demand = demand; 00099 } 00100 else 00101 { 00102 //check if we entered the small deadband 00103 if( !entered_small_deadband ) 00104 { 00105 entered_small_deadband = fabs(avg_error) < deadband; 00106 } 00107 00108 //we always compute the error if we haven't entered the small deadband 00109 if (!entered_small_deadband) 00110 is_in_deadband = false; 00111 else 00112 { 00113 if( fabs(avg_error) > deadband_multiplicator*deadband ) //we're outside of the big deadband -> compute the error 00114 { 00115 is_in_deadband = false; 00116 //when we leave the big deadband we wait until we're back in the small deadband before stopping the motor 00117 entered_small_deadband = false; 00118 } 00119 else //we're in the big deadband -> send a force demand of 0.0 00120 is_in_deadband = true; 00121 } 00122 } 00123 00124 if( last_errors.size() > nb_errors_for_avg ) 00125 last_errors.pop_front(); 00126 00127 return is_in_deadband; 00128 }; 00129 00130 private: 00131 T deadband; 00132 T last_demand; 00133 std::deque<T> last_errors; 00134 bool entered_small_deadband; 00135 }; 00136 00137 } 00138 00139 /* For the emacs weenies in the crowd. 00140 Local Variables: 00141 c-basic-offset: 2 00142 End: 00143 */ 00144 00145 #endif