00001 /** 00002 * @file PfieldDatatypes.h 00003 * 00004 * Definition of several datatypes used by the potential fields 00005 * 00006 * @author <a href="mailto:timlaue@informatik.uni-bremen.de">Tim Laue</a> 00007 */ 00008 00009 #ifndef PFIELD_DATATYPES_H_ 00010 #define PFIELD_DATATYPES_H_ 00011 00012 00013 #include "PfieldConfig.h" 00014 #include <cmath> 00015 #include <vector> 00016 00017 /** A minimum value for floating point comparisons*/ 00018 const double EPSILON=0.00000001; 00019 00020 00021 /** 00022 * @class PfVec 00023 * A simple vector with two double components 00024 */ 00025 class PfVec 00026 { 00027 public: 00028 /** The x-component*/ 00029 double x; 00030 /** The y-component*/ 00031 double y; 00032 00033 /** Constructor */ 00034 PfVec() 00035 { 00036 x = 0.0; 00037 y = 0.0; 00038 } 00039 00040 /** Constructor 00041 * @param x The x component 00042 * @param y The y component 00043 */ 00044 PfVec(double x, double y) 00045 { 00046 this->x = x; 00047 this->y = y; 00048 } 00049 00050 /** Copy-Constructor 00051 * @param p Another vector 00052 */ 00053 PfVec(const PfVec& p) 00054 { 00055 (*this) = p; 00056 } 00057 00058 /** Distance to another vector 00059 * @param v The other vector 00060 * @return The distance 00061 */ 00062 double distanceTo(const PfVec& v) const 00063 { 00064 double dx = v.x - x; 00065 double dy = v.y - y; 00066 return sqrt(dx*dx + dy*dy); 00067 } 00068 00069 /** Rotates around an angle 00070 * @param angle The angle 00071 */ 00072 void rotate(double angle) 00073 { 00074 double ca = cos(angle); 00075 double sa = sin(angle); 00076 double newX = x*ca - y*sa; 00077 y = y*ca + x*sa; 00078 x = newX; 00079 } 00080 00081 /** Normalizes the vector to length==1*/ 00082 void normalize() 00083 { 00084 double len = length(); 00085 if(len != 0.0) 00086 { 00087 x /= len; 00088 y /= len; 00089 } 00090 } 00091 00092 /** Returns the length of the vector 00093 * @return The length 00094 */ 00095 double length() const 00096 { 00097 return sqrt(x*x + y*y); 00098 } 00099 00100 /** Returns the squared length of the vector 00101 * @return The squared length 00102 */ 00103 double squareLength() const 00104 { 00105 return (x*x + y*y); 00106 } 00107 00108 /** Assigns another vector 00109 * @param v The other vector 00110 */ 00111 void operator =(const PfVec& v) 00112 { 00113 x = v.x; 00114 y = v.y; 00115 } 00116 00117 /** Adds another vector 00118 * @param v The other vector 00119 * @return The resulting vector 00120 */ 00121 PfVec operator +(const PfVec& v) const 00122 { 00123 PfVec result(x,y); 00124 result.x += v.x; 00125 result.y += v.y; 00126 return result; 00127 } 00128 00129 /** Substracts another vector 00130 * @param v The other vector 00131 * @return The resulting vector 00132 */ 00133 PfVec operator -(const PfVec& v) const 00134 { 00135 PfVec result(x,y); 00136 result.x -= v.x; 00137 result.y -= v.y; 00138 return result; 00139 } 00140 00141 /** Scales the vector 00142 * @param n The scalar 00143 */ 00144 void operator *= (const double& n) 00145 { 00146 x*=n; 00147 y*=n; 00148 } 00149 00150 /** Returns a scaled vector 00151 * @param n The scalar 00152 * @return The resulting vector 00153 */ 00154 PfVec operator * (const double& n) const 00155 { 00156 PfVec newVec(x,y); 00157 newVec *= n; 00158 return newVec; 00159 } 00160 00161 /** Adds another vector 00162 * @param p The other vector 00163 */ 00164 void operator += (const PfVec& p) 00165 { 00166 x+=p.x; 00167 y+=p.y; 00168 } 00169 00170 /** Substracts another vector 00171 * @param p The other vector 00172 */ 00173 void operator -= (const PfVec& p) 00174 { 00175 x-=p.x; 00176 y-=p.y; 00177 } 00178 00179 /** Multiplies with another vector 00180 * @param p The other vector 00181 * @return The inner product 00182 */ 00183 double scalarProduct(const PfVec& p) const 00184 { 00185 return (x*p.x + y*p.y); 00186 } 00187 00188 /** Computes the angle of the vector 00189 * @return The angle 00190 */ 00191 double getAngle() const 00192 { 00193 return atan2(y,x); 00194 } 00195 }; 00196 00197 00198 /** 00199 * @class PfPose 00200 * A class to describe the pose of an object in a potential field 00201 */ 00202 class PfPose 00203 { 00204 public: 00205 /** The position of the pose*/ 00206 PfVec pos; 00207 /** The rotation of the pose*/ 00208 double rotation; 00209 /** The current speed*/ 00210 double speed; 00211 /** The probability of the pose*/ 00212 double probability; 00213 /** Flag: true, if this pose consists of several poses*/ 00214 bool hasProbabilityDistribution; 00215 /** A set of poses*/ 00216 std::vector<PfPose> probabilityDistribution; 00217 00218 /** Constructor */ 00219 PfPose () 00220 { 00221 pos.x=0.0; 00222 pos.y=0.0; 00223 rotation=0.0; 00224 speed=0.0; 00225 probability=1.0; 00226 hasProbabilityDistribution=false; 00227 } 00228 00229 /** Destructor */ 00230 ~PfPose() 00231 { 00232 probabilityDistribution.clear(); 00233 } 00234 00235 /** Copy-Constructor 00236 * @param p Another pose 00237 */ 00238 PfPose (const PfPose& p) 00239 { 00240 pos = p.pos; 00241 rotation = p.rotation; 00242 speed = p.speed; 00243 probability = p.probability; 00244 hasProbabilityDistribution = p.hasProbabilityDistribution; 00245 if(hasProbabilityDistribution) 00246 { 00247 probabilityDistribution = p.probabilityDistribution; 00248 } 00249 else 00250 { 00251 probabilityDistribution.clear(); 00252 } 00253 } 00254 00255 /** Resets all values*/ 00256 void init() 00257 { 00258 pos.x=0.0; 00259 pos.y=0.0; 00260 rotation=0.0; 00261 speed=0.0; 00262 probability=1.0; 00263 hasProbabilityDistribution=false; 00264 probabilityDistribution.clear(); 00265 } 00266 00267 /** Computes a relative vector to a position 00268 * @param p The position 00269 * @return The vector 00270 */ 00271 PfVec getRelativeVectorTo(const PfVec& p) const 00272 { 00273 PfVec rel = (p-pos); 00274 rel.rotate(-rotation); 00275 return rel; 00276 } 00277 00278 /** Computes the relative angle to a position 00279 * @param p The position 00280 * @return The angle 00281 */ 00282 double getAngleTo(const PfVec& p) const 00283 { 00284 PfVec relVec(p - pos); 00285 relVec.rotate(-rotation); 00286 return relVec.getAngle(); 00287 } 00288 00289 /** Adds a vector to the pose 00290 * @param vec The vector 00291 */ 00292 void addVector(const PfVec& vec) 00293 { 00294 PfVec relVec(vec); 00295 relVec.rotate(rotation); 00296 pos += relVec; 00297 if(hasProbabilityDistribution) 00298 { 00299 for(unsigned int i=0; i<probabilityDistribution.size(); i++) 00300 probabilityDistribution[i].addVector(vec); 00301 } 00302 } 00303 00304 /** Adds a vector to the pose not considering the rotation 00305 * @param vec The vector 00306 */ 00307 void addAbsVector(const PfVec& vec) 00308 { 00309 pos += vec; 00310 if(hasProbabilityDistribution) 00311 { 00312 for(unsigned int i=0; i<probabilityDistribution.size(); i++) 00313 probabilityDistribution[i].addAbsVector(vec); 00314 } 00315 } 00316 00317 /** Rotates the pose around a position 00318 * @param position The position to rotate around 00319 * @param angle The angle to rotate 00320 */ 00321 void rotateAround(const PfVec& position, double angle) 00322 { 00323 pos -= position; 00324 pos.rotate(angle); 00325 pos += position; 00326 rotation += angle; 00327 normRotation(); 00328 if(hasProbabilityDistribution) 00329 { 00330 for(unsigned int i=0; i<probabilityDistribution.size(); i++) 00331 { 00332 probabilityDistribution[i].rotateAround(position, angle); 00333 } 00334 } 00335 } 00336 00337 /** Copies data from another pose 00338 * @param p The pose 00339 */ 00340 void operator = (const PfPose& p) 00341 { 00342 pos = p.pos; 00343 rotation = p.rotation; 00344 speed = p.speed; 00345 probability = p.probability; 00346 hasProbabilityDistribution = p.hasProbabilityDistribution; 00347 if(hasProbabilityDistribution) 00348 { 00349 probabilityDistribution = p.probabilityDistribution; 00350 } 00351 else 00352 { 00353 probabilityDistribution.clear(); 00354 } 00355 } 00356 00357 /** 00358 * Norms the rotation to the interval [-pi,..,pi] 00359 */ 00360 void normRotation() 00361 { 00362 while(rotation>pi) 00363 { 00364 rotation -= (pi2); 00365 } 00366 while(rotation<-pi) 00367 { 00368 rotation += (pi2); 00369 } 00370 } 00371 00372 /** Sets the pose from the sample with the highest probability 00373 */ 00374 void setPoseFromSamples() 00375 { 00376 double bestProbability(0.0); 00377 for(unsigned int i=0; i<probabilityDistribution.size(); i++) 00378 { 00379 if(probabilityDistribution[i].probability > bestProbability) 00380 { 00381 pos = probabilityDistribution[i].pos; 00382 rotation = probabilityDistribution[i].rotation; 00383 bestProbability = probabilityDistribution[i].probability; 00384 } 00385 } 00386 } 00387 }; 00388 00389 00390 #endif //PFIELD_DATATYPES_H_
1.3.6