00001 #include "Util/MathFunctions.H" 00002 #include "Image/PixelsTypes.H" 00003 #include "Image/Point2D.H" 00004 #include "Image/Point3D.H" 00005 #include "XBox360RemoteControlI.H" 00006 #include <map> 00007 #include <fstream> 00008 #include <sstream> 00009 00010 #ifndef LOCALIZATIONUTIL_H_ 00011 #define LOCALIZATIONUTIL_H_ 00012 00013 using namespace std; 00014 00015 class ParamData 00016 { 00017 public: 00018 unsigned int numParams; 00019 map<std::string, float> mData; 00020 map<int, std::string> keys; 00021 00022 ParamData() 00023 { 00024 // 00025 } 00026 00027 ParamData(unsigned int numParams, map<std::string, float> data) 00028 { 00029 this->numParams = numParams; 00030 mData = data; 00031 00032 map<std::string, float>::iterator it; 00033 unsigned int i = 0; 00034 for(it = mData.begin(); i < numParams && it != mData.end(); it ++, i ++) 00035 { 00036 keys[i] = it->first; 00037 } 00038 } 00039 00040 float operator[](std::string s) 00041 { 00042 if(mData.find(s) == mData.end()) 00043 { 00044 return 0.0f; 00045 } 00046 return mData[s]; 00047 } 00048 00049 float operator[](int i) 00050 { 00051 return operator[](keys[i]); 00052 } 00053 }; 00054 00055 struct Camera 00056 { 00057 Point2D<float> mCenter; 00058 float mZoomExp; 00059 float mScale; 00060 00061 void offsetZoom(float s) 00062 { 00063 setZoom(mZoomExp + s); 00064 } 00065 00066 void setZoom(float s) 00067 { 00068 mZoomExp = s; 00069 refreshZoom(); 00070 } 00071 00072 void refreshZoom() 00073 { 00074 mScale = pow(1.015f, mZoomExp); 00075 } 00076 }; 00077 00078 struct ColorSpectrum 00079 { 00080 float spectrum; 00081 float minValue; 00082 float maxValue; 00083 00084 ColorSpectrum() 00085 { 00086 spectrum = 1.0; 00087 minValue = 0.0; 00088 } 00089 00090 void setSpectrum(float s) 00091 { 00092 if (s == 0) 00093 { 00094 s = 0.00001; 00095 } 00096 spectrum = s; 00097 } 00098 }; 00099 00100 class LocalizationUtil 00101 { 00102 public: 00103 static ParamData getDefaultParamData(XBox360RemoteControlI * controller) 00104 { 00105 map<std::string, float> theData; 00106 theData["ang_drift"] = 2.5; 00107 theData["trans_drift"] = 0.125; 00108 theData["num_particles"] = 750; 00109 theData["speed_scalar"] = 0.69125; 00110 theData["rotate_scalar"] = 1.5; 00111 theData["display_width"] = 1000; 00112 theData["display_height"] = 800; 00113 theData["cam_center_x"] = 0.0; 00114 theData["cam_center_y"] = 0.0; 00115 theData["cam_zoom"] = 150.0; 00116 theData["startingstate_x"] = -30.0; 00117 theData["startingstate_y"] = -30.0; 00118 theData["startingstate_angle"] = 90; 00119 theData["pool_dim_x"] = 75.0; 00120 theData["pool_dim_y"] = 75.0; 00121 00122 if(controller) 00123 { 00124 theData["jsvals_l_x"] = controller->itsAxisIndices[XBox360RemoteControl::Keys::Actions::STRAFE]; //get the axis number currently mapped to this action 00125 theData["jsvals_l_y"] = controller->itsAxisIndices[XBox360RemoteControl::Keys::Actions::SPEED]; 00126 theData["jsvals_r_x"] = controller->itsAxisIndices[XBox360RemoteControl::Keys::Actions::HEADING]; 00127 } 00128 else 00129 { 00130 theData["jsvals_l_x"] = 0; 00131 theData["jsvals_l_y"] = 1; 00132 theData["jsvals_r_x"] = 3; 00133 } 00134 00135 theData["jsvals_r_y"] = 4; 00136 theData["jsvals_trigger"] = 5; 00137 theData["jsvals_dpad_x"] = 6; 00138 theData["jsvals_dpad_y"] = 7; 00139 theData["bvals_l_bumper"] = 4; 00140 theData["bvals_r_bumper"] = 5; 00141 theData["bvals_rjs_click"] = 9; 00142 theData["bvals_y"] = 3; 00143 theData["bvals_b"] = 1; 00144 theData["bvals_x"] = 2; 00145 theData["bvals_a"] = 0; 00146 theData["bvals_start"] = 6; 00147 theData["bvals_back"] = 10; 00148 ParamData pd(31, theData); 00149 return pd; 00150 } 00151 00152 static bool readConfigFile(string uri, ParamData &pd) 00153 { 00154 //////////[ Read in params ]////////// 00155 00156 ifstream ifs(uri.c_str(), ifstream::in); 00157 cout << "Trying to read config file in " << uri << "..." << endl; 00158 if (!ifs.good()) 00159 { 00160 cout << "Couldn't find config file." << endl; 00161 return false; 00162 } 00163 else 00164 { 00165 cout << "Config file opened..." << endl; 00166 map<std::string, float> theParams; 00167 int numParams = 0; 00168 00169 bool go = ifs.good(); 00170 int pos2 = 0; 00171 int pos3 = -1; 00172 00173 while (go) 00174 { 00175 float theValue; 00176 string theTag; 00177 stringstream ss; 00178 string s; 00179 ifs >> s; 00180 if (ifs.good()) 00181 { 00182 int pos1 = pos3 + 1; 00183 pos2 = s.find("=", pos1); 00184 pos3 = s.find("\n", pos2); 00185 theTag = s.substr(pos1, pos2 - pos1); 00186 pos2 ++; 00187 ss << s.substr(pos2, pos3 - pos2); 00188 ss >> theValue; 00189 theParams[theTag] = theValue; 00190 numParams ++; 00191 } 00192 else 00193 { 00194 go = false; 00195 } 00196 } 00197 00198 ifs.close(); 00199 00200 ParamData theResult(numParams, theParams); 00201 pd = theResult; 00202 00203 cout << "Config file read." << endl; 00204 } 00205 return true; 00206 00207 //////////////////// 00208 } 00209 00210 static bool writeConfigFile(string uri, ParamData pd) //returns success/failure 00211 { 00212 cout << "Trying to write config file to " << uri << "..." << endl; 00213 ofstream ofs(uri.c_str()); 00214 if (ofs.good()) 00215 { 00216 cout << "Config file opened for writing..." << endl; 00217 map<std::string, float>::iterator it; 00218 for(it = pd.mData.begin(); it != pd.mData.end(); it ++) 00219 { 00220 ofs << it->first << "=" << it->second << endl; 00221 } 00222 } 00223 else 00224 { 00225 cout << "Couldn't write config file." << endl; 00226 return false; 00227 } 00228 ofs.close(); 00229 cout << "Config file written." << endl; 00230 return true; 00231 } 00232 00233 static float polarToEuler(float a) //degrees people. USE IT! 00234 { 00235 float result = a - 90; // conventional -> euler 00236 if(result < 0) 00237 { 00238 result += 360; 00239 } 00240 return result; 00241 } 00242 00243 static float eulerToPolar(float a) 00244 { 00245 float result = a + 90; 00246 if(result < 0) 00247 { 00248 result += 360; 00249 } 00250 return result; 00251 } 00252 00253 static float degToRad(float n) 00254 { 00255 return n * D_PI / 180; 00256 } 00257 00258 static float radToDeg(float n) 00259 { 00260 return n * 180 / D_PI; 00261 } 00262 00263 static float ProbabilityDistribution(float u, float s, float x) 00264 { 00265 return exp(-pow(x - u, 2) / (2 * pow(s, 2))) / sqrt(2 * D_PI 00266 * pow(s, 2)); 00267 } 00268 00269 static float floatMod(float f, float m) 00270 { 00271 //cout << "->floatMod" << endl; 00272 int a = (int) (f / m); 00273 00274 if (a < 0) 00275 { 00276 f -= (float) (m * (a - 1)); 00277 } 00278 else 00279 { 00280 f -= (float) (m * a); 00281 } 00282 00283 //cout << "<-floatMod" << endl; 00284 return f; 00285 } 00286 00287 static PixRGB<byte> RGBFromHSV(float H, float S, float V) 00288 { 00289 //cout << "->(" << H << "," << S << "," << V << ")RGBFromHSV" << endl; 00290 double R = 0, G = 0, B = 0; 00291 00292 if (V == 0) 00293 { 00294 R = 0; 00295 G = 0; 00296 B = 0; 00297 } 00298 else if (S == 0) 00299 { 00300 R = V; 00301 G = R; 00302 B = R; 00303 } 00304 else 00305 { 00306 const double hf = H / 60.0; 00307 const int i = (int) floor(hf); 00308 const double f = hf - i; 00309 const double pv = V * (1 - S); 00310 const double qv = V * (1 - S * f); 00311 const double tv = V * (1 - S * (1 - f)); 00312 switch (i) 00313 { 00314 case 0: 00315 R = V; 00316 G = tv; 00317 B = pv; 00318 break; 00319 case 1: 00320 R = qv; 00321 G = V; 00322 B = pv; 00323 break; 00324 case 2: 00325 R = pv; 00326 G = V; 00327 B = tv; 00328 break; 00329 case 3: 00330 R = pv; 00331 G = qv; 00332 B = V; 00333 break; 00334 case 4: 00335 R = tv; 00336 G = pv; 00337 B = V; 00338 break; 00339 case 5: 00340 R = V; 00341 G = pv; 00342 B = qv; 00343 break; 00344 case 6: 00345 R = V; 00346 G = tv; 00347 B = pv; 00348 break; 00349 case -1: 00350 R = V; 00351 G = pv; 00352 B = qv; 00353 break; 00354 default: 00355 break; 00356 } 00357 } 00358 00359 R *= 255; 00360 G *= 255; 00361 B *= 255; 00362 00363 //cout << "<-(" << R << "," << G << "," << B << ")RGBFromHSV" << endl; 00364 return PixRGB<byte> ((int) R, (int) G, (int) B); 00365 } 00366 00367 static Point2D<float> vectorTo(Point2D<float> p1, Point2D<float> p2) 00368 { 00369 //cout << "->vectorTo" << endl; 00370 Point2D<float> p(p2.i - p1.i, p2.j - p1.j); 00371 float dist = sqrt(pow(p.i, 2) + pow(p.j, 2)); 00372 float angle = 0.0; 00373 if (p.i == 0) 00374 { 00375 if (p.j >= 0) 00376 { 00377 angle = 90; 00378 } 00379 else 00380 { 00381 angle = 270; 00382 } 00383 } 00384 else 00385 { 00386 angle = abs(atan(p.j / p.i) / D_DEGREE); 00387 if (p.i >= 0 && p.j >= 0) 00388 { 00389 // 00390 } 00391 else if (p.i < 0 && p.j >= 0) 00392 { 00393 angle = (90 - angle) + 90; 00394 } 00395 else if (p.i < 0 && p.j < 0) 00396 { 00397 angle += 180; 00398 } 00399 else 00400 { 00401 angle = (90 - angle) + 270; 00402 } 00403 } 00404 angle = floatMod(angle, 360.0); 00405 //cout << "<-vectorTo" << endl; 00406 return Point2D<float> (dist, angle); 00407 } 00408 00409 //calculates the ratio of difference between a1 and a2 such that angleRatio(x, x+180) = 1 and angleRatio(x, x) = 0 00410 static float linearAngleDiffRatio(float a1, float a2) 00411 { 00412 //cout << "->angleDiffRatio" << endl; 00413 float theAngle = abs(a1 - a2); 00414 while(theAngle > 360) 00415 { 00416 theAngle -= 360; 00417 } 00418 while(theAngle < 0) 00419 { 00420 theAngle += 360; 00421 } 00422 if(theAngle > 180) 00423 { 00424 theAngle = 360.0f - theAngle; 00425 } 00426 theAngle /= 180.0f; 00427 00428 //cout << "<-angleDiffRatio" << endl; 00429 return theAngle; 00430 } 00431 00432 static float trigAngleDiffRatio(float a1, float a2) 00433 { 00434 float d = sqrt(pow(cos(D_DEGREE * a1) - cos(D_DEGREE * a2), 2) + pow(sin(D_DEGREE * a1) - sin(D_DEGREE * a2), 2)); 00435 return d / 2.0f; 00436 } 00437 }; 00438 00439 #endif /* LOCALIZATIONUTIL_H_ */