00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef HECTOR_GAZEBO_PLUGINS_SENSOR_MODEL_H
00030 #define HECTOR_GAZEBO_PLUGINS_SENSOR_MODEL_H
00031
00032 #include <gazebo/sdf/sdf.hh>
00033
00034 namespace gazebo {
00035
00036 template <typename T>
00037 class SensorModel_ {
00038 public:
00039 SensorModel_();
00040 virtual ~SensorModel_();
00041
00042 virtual void Load(sdf::ElementPtr _sdf, const std::string& prefix = std::string());
00043
00044 virtual T operator()(const T& value) const { return value + current_error_; }
00045 virtual T operator()(const T& value, double dt) { return value + update(dt); }
00046
00047 virtual T update(double dt);
00048 virtual void reset(const T& value = T());
00049
00050 virtual const T& getCurrentError() const { return current_error_; }
00051 virtual const T& getCurrentDrift() const { return current_drift_; }
00052
00053 virtual void setCurrentDrift(const T& new_drift) { current_drift_ = new_drift; }
00054
00055 private:
00056 virtual bool LoadImpl(sdf::ElementPtr _element, T& _value);
00057
00058 public:
00059 T offset;
00060 T drift;
00061 T drift_frequency;
00062 T gaussian_noise;
00063
00064 private:
00065 T current_drift_;
00066 T current_error_;
00067 };
00068
00069 template <typename T>
00070 SensorModel_<T>::SensorModel_()
00071 : offset()
00072 , drift()
00073 , drift_frequency()
00074 , gaussian_noise()
00075 {
00076 drift_frequency = 1.0/3600.0;
00077 reset();
00078 }
00079
00080 template <typename T>
00081 SensorModel_<T>::~SensorModel_()
00082 {
00083 }
00084
00085 template <typename T>
00086 void SensorModel_<T>::Load(sdf::ElementPtr _sdf, const std::string& prefix)
00087 {
00088 std::string _offset, _drift, _drift_frequency, _gaussian_noise;
00089
00090 if (prefix.empty()) {
00091 _offset = "offset";
00092 _drift = "drift";
00093 _drift_frequency = "driftFrequency";
00094 _gaussian_noise = "gaussianNoise";
00095 } else {
00096 _offset = prefix + "Offset";
00097 _drift = prefix + "Drift";
00098 _drift_frequency = prefix + "DriftFrequency";
00099 _gaussian_noise = prefix + "GaussianNoise";
00100 }
00101
00102 if (_sdf->HasElement(_offset)) LoadImpl(_sdf->GetElement(_offset), offset);
00103 if (_sdf->HasElement(_drift)) LoadImpl(_sdf->GetElement(_drift), drift);
00104 if (_sdf->HasElement(_drift_frequency)) LoadImpl(_sdf->GetElement(_drift_frequency), drift_frequency);
00105 if (_sdf->HasElement(_gaussian_noise)) LoadImpl(_sdf->GetElement(_gaussian_noise), gaussian_noise);
00106 }
00107
00108 template <typename T>
00109 bool SensorModel_<T>::LoadImpl(sdf::ElementPtr _element, T& _value) {
00110 if (!_element->GetValue()) return false;
00111 if (_element->GetValue()->IsStr()) {
00112 try {
00113 _value = boost::lexical_cast<T>(_element->GetValue()->GetAsString());
00114 return true;
00115 } catch(boost::bad_lexical_cast&) {
00116 return false;
00117 }
00118 }
00119 return _element->GetValue()->Get(_value);
00120 }
00121
00122 namespace {
00123 template <typename T>
00124 static inline T SensorModelGaussianKernel(T mu, T sigma)
00125 {
00126
00127
00128 T U = (T)rand()/(T)RAND_MAX;
00129 T V = (T)rand()/(T)RAND_MAX;
00130 T X = sqrt(-2.0 * ::log(U)) * cos( 2.0*M_PI * V);
00131 X = sigma * X + mu;
00132 return X;
00133 }
00134
00135 template <typename T>
00136 static inline T SensorModelInternalUpdate(T& current_drift, T drift, T drift_frequency, T offset, T gaussian_noise, double dt)
00137 {
00138 current_drift = current_drift - dt * (current_drift * drift_frequency + SensorModelGaussianKernel(T(), sqrt(2*drift_frequency)*drift));
00139 return offset + current_drift + SensorModelGaussianKernel(T(), gaussian_noise);
00140 }
00141 }
00142
00143 template <typename T>
00144 T SensorModel_<T>::update(double dt)
00145 {
00146 for(std::size_t i = 0; i < current_error_.size(); ++i) current_error_[i] = current_error_ = SensorModelInternalUpdate(current_drift_[i], drift[i], drift_frequency[i], offset[i], gaussian_noise[i], dt);
00147 return current_error_;
00148 }
00149
00150 template <>
00151 double SensorModel_<double>::update(double dt)
00152 {
00153 current_error_ = SensorModelInternalUpdate(current_drift_, drift, drift_frequency, offset, gaussian_noise, dt);
00154 return current_error_;
00155 }
00156
00157 template <>
00158 math::Vector3 SensorModel_<math::Vector3>::update(double dt)
00159 {
00160 current_error_.x = SensorModelInternalUpdate(current_drift_.x, drift.x, drift_frequency.x, offset.x, gaussian_noise.x, dt);
00161 current_error_.y = SensorModelInternalUpdate(current_drift_.y, drift.y, drift_frequency.y, offset.y, gaussian_noise.y, dt);
00162 current_error_.z = SensorModelInternalUpdate(current_drift_.z, drift.z, drift_frequency.z, offset.z, gaussian_noise.z, dt);
00163 return current_error_;
00164 }
00165
00166 template <typename T>
00167 void SensorModel_<T>::reset(const T& value)
00168 {
00169 current_drift_ = T();
00170 current_error_ = value;
00171 }
00172
00173 typedef SensorModel_<double> SensorModel;
00174 typedef SensorModel_<math::Vector3> SensorModel3;
00175
00176 }
00177
00178 #endif // HECTOR_GAZEBO_PLUGINS_SENSOR_MODEL_H