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_
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641