00001 #include "LocalizationParticle.h" 00002 #include <vector> 00003 00004 LocalizationParticle::LocalizationParticle() 00005 { 00006 // 00007 } 00008 00009 LocalizationParticle::LocalizationParticle(State p_mState) 00010 { 00011 mState = p_mState; 00012 } 00013 00014 LocalizationParticle::LocalizationParticle(const LocalizationParticle &p) 00015 { 00016 mState = p.mState; 00017 } 00018 00019 void LocalizationParticle::updatePosition(float m, float a) 00020 { 00021 mState.mPoint.i += m * cos(D_DEGREE * a); 00022 mState.mPoint.j += m * sin(D_DEGREE * a); 00023 //mState.mAngle = a; 00024 } 00025 00026 void LocalizationParticle::updatePosition(Point2D<float> p, float a) 00027 { 00028 mState.mPoint.i += p.i; 00029 mState.mPoint.j += p.j; 00030 mState.mAngle = a; 00031 } 00032 00033 void LocalizationParticle::Print() 00034 { 00035 cout << "[" << mState.mAngle << "," << mState.mPoint.i << "," << mState.mPoint.j << "]; w=" << mState.mWeight << endl; 00036 } 00037 00038 // Updates the position 00039 void LocalizationParticle::drift_position(float stdDev, float vel, float dt, ParamData pd) 00040 { 00041 //simple fix; randomDoubleFromNormal() needs to be scaled; before it was just 1 ie 1 foot/s velocity 00042 00043 //1.5 in/second max sustained velocity due to drift 00044 float randomDriftDistanceX = (vel + pd["trans_drift"]) * randomDoubleFromNormal(stdDev) * dt; 00045 float randomDriftDistanceY = (vel + pd["trans_drift"]) * randomDoubleFromNormal(stdDev) * dt; 00046 updatePosition(Point2D<float>(randomDriftDistanceX, randomDriftDistanceY), mState.mAngle); 00047 } 00048 00049 void LocalizationParticle::drift_angle(float stdDev, float vel, float dt, ParamData pd) 00050 { 00051 //[vel] degrees/second max sustained angular velocity due to drift 00052 float randomDriftAngle = (vel + pd["ang_drift"]) * randomDoubleFromNormal(stdDev) * dt; 00053 updatePosition(Point2D<float>(0.0, 0.0), mState.mAngle + randomDriftAngle); 00054 } 00055 00056 //amt of time it takes to go 1 ft at p% thrusters 00057 float LocalizationParticle::getTime(float p, ParamData pd) //static 00058 { 00059 //time it takes to go 8 feet 00060 //return 5.53 / p; 00061 00062 //time it takes to go 1 foot 00063 return pd["speed_scalar"] / abs(p); 00064 } 00065 00066 float LocalizationParticle::getVelocity(float p, ParamData pd) //static 00067 { 00068 //sub goes 1 foot in t(p) seconds 00069 //return 1.0 / getTime(p); 00070 return abs(p) / pd["speed_scalar"]; 00071 } 00072 00073 float LocalizationParticle::getDistance(float p, float dt, ParamData pd) //static 00074 { 00075 return getVelocity(p, pd) * dt; 00076 } 00077 00078 float LocalizationParticle::getStdDev(float p) 00079 { 00080 //samples: 00081 //[0] : 6.48 00082 //[1] : 0.2592 00083 return 6.48 * std::pow((double)0.04, (double)abs(p)); 00084 } 00085 00086 float LocalizationParticle::getChangeInRotation(float p, float dt, ParamData pd) //static 00087 { 00088 //t(p) = amt of time it takes to turn 90 degrees at motor value p 00089 //90.0 * dt / t(p) 00090 // 360 / (pi * D) [D = 1.5 ft = distance between thrusters] 00091 static const float FT_TO_DEG = -360 / (acos(-1.0) * pd["rotate_scalar"]); //degrees rotated when thrusters move one foot 00092 float scale = 1.0; 00093 if(p < 0) 00094 { 00095 scale = -1.0; 00096 } 00097 float theResult = getDistance(p, dt, pd) * FT_TO_DEG; 00098 return scale * theResult; 00099 } 00100 00101 vector<LocalizationParticle> LocalizationParticle::stepParticles(vector<LocalizationParticle> p, float dt, int i_pX, int i_pY, int i_angle, ParamData pd) //static 00102 { 00103 float pX = (float)i_pX / 100.0; 00104 float pY = (float)i_pY / 100.0; 00105 00106 float distance = getDistance(pY, dt, pd); 00107 float angle = getChangeInRotation(pX, dt, pd); 00108 float t_vel = getVelocity(pY, pd); 00109 float a_vel = getVelocity(pX, pd); 00110 float dist_stdDev = getStdDev(pY); 00111 float ang_stdDev = getStdDev(pX); 00112 00113 for (unsigned int i = 0; i < p.size(); i++) 00114 { 00115 //new idea: move to the position, then apply the drift that may have occurred over that time 00116 00117 p[i].updatePosition(distance, p[i].mState.mAngle + angle + i_angle); 00118 p[i].mState.mAngle += angle; 00119 00120 p[i].drift_angle(ang_stdDev, a_vel, dt, pd); 00121 p[i].drift_position(dist_stdDev, t_vel, dt, pd); 00122 //p[i].mState.mAngle = normalizeAngle(p[i].mState.mAngle); 00123 } 00124 return p; 00125 } 00126 00127 float LocalizationParticle::normalizeAngle(float a) 00128 { 00129 while(a < 0) 00130 { 00131 a += 360; 00132 } 00133 while(a >= 360) 00134 { 00135 a -= 360; 00136 } 00137 return a; 00138 }