CreateMotionModel.h
Go to the documentation of this file.00001
00002 #ifndef _CreateMotionModel_h_
00003 #define _CreateMotionModel_h_
00004
00005 #include "Shared/RobotInfo.h"
00006
00007 #ifdef TGT_IS_CREATE
00008
00009 #include "Behaviors/BehaviorBase.h"
00010 #include "Shared/zignor.h"
00011 #include "Shared/Measures.h"
00012 #include "Shared/ParticleFilter.h"
00013 #include "Shared/WorldState.h"
00014
00015 template<class ParticleT>
00016 class CreateMotionModel : public BehaviorBase, public ParticleFilter<ParticleT>::MotionModel {
00017 private:
00018 float lastdist;
00019 AngTwoPi lastang;
00020
00021
00022 float dmean;
00023 AngTwoPi amean;
00024 float ddvar, davar, aavar, advar;
00025
00026 static const float minUpdateDistance;
00027 static const float minUpdateAngle;
00028
00029 public:
00030 bool wasUpdated;
00031
00032 typedef typename ParticleFilter<ParticleT>::MotionModel::particle_type particle_type;
00033 typedef typename ParticleFilter<ParticleT>::MotionModel::particle_collection particle_collection;
00034 typedef typename particle_collection::size_type index_t;
00035
00036
00037 CreateMotionModel(float dm=0.1f, float am=0.2f, float ddv=0.001f, float dav=0.001f, float aav=0.001f, float adv=0.000001f) :
00038 BehaviorBase("CreateMotionModel"), ParticleFilter<ParticleT>::MotionModel(),
00039 lastdist(state->sensors[EncoderDistanceOffset]),
00040 lastang(state->sensors[EncoderAngleOffset]/180*(float)M_PI),
00041 dmean(dm), amean(am), ddvar(ddv), davar(dav), aavar(aav), advar(adv),
00042 wasUpdated(false)
00043 {}
00044
00045 float sampleNormal(float mean, float var) {
00046
00047 return mean + (float)DRanNormalZig32()*std::sqrt(var);
00048 }
00049
00050 virtual void updateMotion(particle_collection& particles, particle_type& estimate) {
00051 float dist = state->sensors[EncoderDistanceOffset];
00052 AngTwoPi ang = state->sensors[EncoderAngleOffset]/180*(float)M_PI;
00053
00054 float dd = dist - lastdist;
00055 AngSignPi da = float(ang - lastang);
00056
00057
00058 if (fabs(dd) < minUpdateDistance && fabs(da) < minUpdateAngle) {
00059
00060 wasUpdated = false;
00061 return;
00062 }
00063
00064 lastdist = dist;
00065 lastang = ang;
00066
00067
00068 float dx, dy, dtheta;
00069 computeCreateMotion(dd, float(da), estimate.theta, dx, dy, dtheta);
00070 estimate.x += dx;
00071 estimate.y += dy;
00072 estimate.theta += dtheta;
00073
00074
00075 for(typename particle_collection::iterator it=particles.begin(); it!=particles.end(); ++it) {
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 float dnoise, anoise;
00093 dnoise = dmean * dd * sampleNormal(0, ddvar*dd*dd + davar*da*da);
00094 anoise = float(amean) * sampleNormal(0, aavar*da*da + advar*dd*dd);
00095 float ddn = dd + dnoise;
00096 AngSignPi dan = float(da) + anoise;
00097 computeCreateMotion(ddn, float(dan), float(it->theta), dx, dy, dtheta);
00098 it->x += dx;
00099 it->y += dy;
00100 it->theta += dtheta;
00101 }
00102
00103 wasUpdated = true;
00104 }
00105
00106
00107 private:
00108
00109
00110 virtual void computeCreateMotion(float len, float omega, float theta, float &dx, float &dy, float &dtheta) {
00111
00112 if ( omega == 0 ) {
00113 dx = len*std::cos(theta);
00114 dy = len*std::sin(theta);
00115 dtheta = 0;
00116 }
00117
00118 else {
00119
00120
00121
00122
00123 float r = len / omega;
00124
00125
00126
00127
00128
00129
00130
00131 dx = r*std::sin(theta + omega) - r*std::sin(theta);
00132 dy = -r*std::cos(theta + omega) + r*std::cos(theta);
00133 dtheta = omega;
00134 }
00135 }
00136
00137 };
00138
00139 template<class ParticleT> const float CreateMotionModel<ParticleT>::minUpdateDistance = 5.0f;
00140 template<class ParticleT> const float CreateMotionModel<ParticleT>::minUpdateAngle = 0.05f;
00141
00142 #endif
00143
00144 #endif
00145