00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef POTENTIAL_FUNCTIONS_H_
00010 #define POTENTIAL_FUNCTIONS_H_
00011
00012
00013 #include <cmath>
00014 #include <cassert>
00015
00016 class PfPose;
00017 class PfVec;
00018 class Sector;
00019 class Polygon;
00020 class PfieldGeometricObject;
00021
00022
00023
00024 enum ObjectType {ATTRACTIVE, REPULSIVE};
00025
00026
00027 enum FunctionType {NO_FUNCTION, LINEAR_FUNCTION, PARABOLIC_FUNCTION, ASYMPTOTIC_FUNCTION};
00028
00029
00030 enum FieldType {POINT_FIELD, SHAPE_FIELD, SECTOR_FIELD};
00031
00032
00033
00034
00035
00036
00037
00038 class PotentialfieldFunction
00039 {
00040 public:
00041
00042
00043
00044
00045
00046
00047 virtual double computeValue(double x, bool smooth=true);
00048
00049
00050
00051
00052
00053
00054
00055 virtual double computeDerivativeValue(double x, bool smooth=false);
00056
00057
00058
00059
00060 virtual PotentialfieldFunction* clone() = 0;
00061
00062
00063
00064
00065 double getRange()
00066 { return range;}
00067
00068
00069
00070
00071
00072 void setParameters(double atZero, double range)
00073 {
00074 this->atZero = atZero;
00075 this->range = range;
00076 smoothingAtObjectPosition = smoothingAtObjectPercentage*range;
00077 smoothingAtBorderPosition = range - smoothingAtBorderPercentage*range;
00078 init();
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 void setSmoothingParameters(double smoothingAtObject,
00089 double smoothingAtBorder,
00090 double gradientAtObject,
00091 double gradientAtBorder)
00092 {
00093 this->gradientAtObject = gradientAtObject;
00094 this->gradientAtBorder = gradientAtBorder;
00095 smoothingAtObjectPercentage = smoothingAtObject;
00096 smoothingAtBorderPercentage = smoothingAtBorder;
00097 smoothingAtObjectPosition = smoothingAtObject*range;
00098 smoothingAtBorderPosition = range - smoothingAtBorder*range;
00099 }
00100
00101 protected:
00102
00103 double smoothingAtObjectPosition;
00104
00105 double smoothingAtBorderPosition;
00106
00107 double gradientAtObject;
00108
00109 double gradientAtBorder;
00110
00111 double smoothingAtObjectPercentage;
00112
00113 double smoothingAtBorderPercentage;
00114
00115 double atZero;
00116
00117 double range;
00118
00119 double a;
00120
00121 double b;
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 double computeSmoothedValue(double x1, double fx1, double dx1,
00135 double x2, double fx2, double dx2,
00136 double x);
00137
00138
00139
00140
00141
00142 virtual double f(double x) const
00143 { return 0.0;}
00144
00145
00146
00147
00148
00149 virtual double d(double x) const
00150 { return 0.0;}
00151
00152
00153
00154
00155
00156 virtual double dd(double x) const
00157 { return 0.0;}
00158
00159
00160 virtual void init() {}
00161
00162
00163
00164
00165 void getStandardParameters(PotentialfieldFunction* other)
00166 { this->smoothingAtObjectPosition = other->smoothingAtObjectPosition;
00167 this->smoothingAtBorderPosition = other->smoothingAtBorderPosition;
00168 this->gradientAtObject = other->gradientAtObject;
00169 this->gradientAtBorder = other->gradientAtBorder;
00170 this->smoothingAtObjectPercentage = other->smoothingAtObjectPercentage;
00171 this->smoothingAtBorderPercentage = other->smoothingAtBorderPercentage;}
00172 };
00173
00174
00175
00176
00177
00178
00179
00180
00181 class LinearFunction: public PotentialfieldFunction
00182 {
00183 public:
00184
00185
00186
00187
00188
00189 LinearFunction(double range, double atZero)
00190 {
00191 this->atZero = atZero;
00192 this->range = range;
00193 init();
00194 }
00195
00196
00197
00198
00199 virtual PotentialfieldFunction* clone()
00200 {
00201 LinearFunction* newFunction = new LinearFunction(range,atZero);
00202 newFunction->getStandardParameters(this);
00203 return newFunction;
00204 }
00205
00206 protected:
00207
00208
00209
00210
00211 double f(double x) const
00212 {
00213 return (a*x + b);
00214 }
00215
00216
00217
00218
00219
00220 double d(double x) const
00221 {
00222 return a;
00223 }
00224
00225
00226
00227
00228
00229 virtual double dd(double x) const
00230 {
00231 return 0.0;
00232 }
00233
00234
00235 virtual void init()
00236 {
00237 assert(range != 0.0);
00238 a = -atZero/range;
00239 b = atZero;
00240 }
00241 };
00242
00243
00244
00245
00246
00247
00248
00249
00250 class ParabolicFunction: public PotentialfieldFunction
00251 {
00252 public:
00253
00254
00255
00256
00257
00258 ParabolicFunction(double range, double atZero)
00259 {
00260 this->atZero = atZero;
00261 this->range = range;
00262 init();
00263 }
00264
00265
00266
00267
00268 virtual PotentialfieldFunction* clone()
00269 {
00270 ParabolicFunction* newFunction = new ParabolicFunction(range,atZero);
00271 newFunction->getStandardParameters(this);
00272 return newFunction;
00273 }
00274
00275 protected:
00276
00277
00278
00279
00280 double f(double x) const
00281 {
00282 return (a*x*x + b);
00283 }
00284
00285
00286
00287
00288
00289 double d(double x) const
00290 {
00291 return (2.0*a*x);
00292 }
00293
00294
00295
00296
00297
00298 virtual double dd(double x) const
00299 {
00300 return (2.0*a);
00301 }
00302
00303
00304 virtual void init()
00305 {
00306 assert(range != 0.0);
00307 a = -atZero/(range*range);
00308 b = atZero;
00309 }
00310 };
00311
00312
00313
00314
00315
00316
00317
00318
00319 class AsymptoticFunction: public PotentialfieldFunction
00320 {
00321 public:
00322
00323
00324
00325
00326
00327
00328 AsymptoticFunction(double range, double atZero, double solidCenter)
00329 {
00330 this->atZero = atZero;
00331 this->range = range;
00332 this->solidCenter = solidCenter;
00333 init();
00334 }
00335
00336
00337
00338
00339 virtual PotentialfieldFunction* clone()
00340 {
00341 AsymptoticFunction* newFunction = new AsymptoticFunction(range,atZero,solidCenter);
00342 newFunction->getStandardParameters(this);
00343 return newFunction;
00344 }
00345
00346 protected:
00347
00348 double solidCenter;
00349
00350
00351
00352
00353
00354 double f(double x) const
00355 {
00356 if(x <= solidCenter)
00357 {
00358 return atZero;
00359 }
00360 else
00361 {
00362 return (a/x + b);
00363 }
00364 }
00365
00366
00367
00368
00369
00370 double d(double x) const
00371 {
00372 if(x <= solidCenter)
00373 {
00374 return (-a/solidCenter*solidCenter);
00375 }
00376 else
00377 {
00378 return (-a/(x*x));
00379 }
00380 }
00381
00382
00383
00384
00385
00386 virtual double dd(double x) const
00387 {
00388 return (2.0*a/(x*x*x));
00389 }
00390
00391
00392 virtual void init()
00393 {
00394 assert((range != 0.0) && (solidCenter != 0.0) && (range != solidCenter));
00395 a = atZero/(1.0/solidCenter - 1.0/range);
00396 b = -a/range;
00397 }
00398 };
00399
00400
00401
00402
00403
00404
00405
00406 class SocialFunction: public PotentialfieldFunction
00407 {
00408 public:
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 SocialFunction(double repC, double repOm, double attC, double attOm,
00419 double epsilon, double k)
00420 {
00421 this->repC = repC;
00422 this->repOm = repOm;
00423 this->attC = attC;
00424 this->attOm = attOm;
00425 this->epsilon = epsilon;
00426 this->k = k;
00427 }
00428
00429
00430
00431
00432
00433
00434 virtual double computeValue(double x, bool smooth=true)
00435 {
00436 if(x < epsilon)
00437 {
00438 x = epsilon;
00439 }
00440 double repValue;
00441 double attValue;
00442 if(repOm == 1.0)
00443 {
00444 repValue = repC * log(x);
00445 }
00446 else
00447 {
00448 repValue = (repC / (-repOm + 1.0)) * pow(x, -repOm+1.0);
00449 }
00450 if(attOm == 1.0)
00451 {
00452 attValue = attC * log(x);
00453 }
00454 else
00455 {
00456 attValue = (attC / (-attOm + 1.0)) * pow(x, -attOm+1.0);
00457 }
00458 return (-repValue + attValue + k);
00459 }
00460
00461
00462
00463
00464
00465
00466 double computeDerivativeValue(double x, bool smooth=false)
00467 {
00468 if(x < epsilon)
00469 {
00470 x = epsilon;
00471 }
00472 return ((-repC/pow(x,repOm))+(attC/pow(x,attOm)));
00473 }
00474
00475
00476
00477
00478 virtual PotentialfieldFunction* clone()
00479 {
00480 SocialFunction* newFunction = new SocialFunction(repC,repOm,attC,attOm, epsilon, k);
00481 newFunction->getStandardParameters(this);
00482 return newFunction;
00483 }
00484
00485 private:
00486
00487 double repC;
00488
00489 double repOm;
00490
00491 double attC;
00492
00493 double attOm;
00494
00495 double epsilon;
00496
00497 double k;
00498 };
00499
00500
00501
00502
00503
00504
00505
00506 class NoFunction: public PotentialfieldFunction
00507 {
00508 public:
00509
00510
00511
00512
00513
00514 double computeValue(double x, bool smooth=true)
00515 {
00516 return 0.0;
00517 }
00518
00519
00520
00521
00522
00523
00524 double computeDerivativeValue(double x, bool smooth=false)
00525 {
00526 return 0.0;
00527 }
00528
00529
00530
00531
00532 virtual PotentialfieldFunction* clone()
00533 {
00534 NoFunction* newFunction = new NoFunction();
00535 return newFunction;
00536 }
00537 };
00538
00539
00540
00541
00542
00543
00544
00545
00546 double computeChargeForPointfield(const PfPose& objectPose, const PfPose& testedPose,
00547 PotentialfieldFunction* function);
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 double computeChargeForShapefield(const PfPose& objectPose, const PfPose& testedPose,
00558 PotentialfieldFunction* function,
00559 PfieldGeometricObject* geometry);
00560
00561
00562
00563
00564
00565
00566
00567
00568 double computeChargeForSectorfield(const PfPose& objectPose, const PfPose& testedPose,
00569 PotentialfieldFunction* function,
00570 const Sector& sector);
00571
00572
00573
00574
00575
00576
00577
00578 PfVec computeGradientForPointfield(const PfPose& objectPose, const PfPose& testedPose,
00579 PotentialfieldFunction* function);
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 PfVec computeGradientForShapefield(const PfPose& objectPose, const PfPose& testedPose,
00590 PotentialfieldFunction* function,
00591 PfieldGeometricObject* geometry,
00592 ObjectType objectType);
00593
00594
00595
00596
00597
00598
00599
00600
00601 PfVec computeGradientForSectorfield(const PfPose& objectPose, const PfPose& testedPose,
00602 PotentialfieldFunction* function,
00603 const Sector& sector);
00604
00605
00606 #endif //POTENTIAL_FUNCTIONS_H_