00001
00002 #ifndef INCLUDED_PlannerObstacles_H
00003 #define INCLUDED_PlannerObstacles_H
00004
00005 #include <ostream>
00006
00007 #include "Shared/fmat.h"
00008 #include "Shared/plist.h"
00009 #include "Shared/FamilyFactory.h"
00010 #include "Shared/BoundingBox.h"
00011 #include <vector>
00012
00013 template<size_t N>
00014 class PlannerObstacle;
00015 typedef PlannerObstacle<2> PlannerObstacle2D;
00016 typedef PlannerObstacle<3> PlannerObstacle3D;
00017
00018 class RectangularObstacle;
00019 class CircularObstacle;
00020 class EllipticalObstacle;
00021 class ConvexPolyObstacle;
00022 class HierarchicalObstacle;
00023 class BoxObstacle;
00024 class CylindricalObstacle;
00025 class SphericalObstacle;
00026 class EllipsoidObstacle;
00027
00028 namespace plist {
00029
00030 template<> PlannerObstacle2D* loadXML(xmlNode* node);
00031 template<> PlannerObstacle3D* loadXML(xmlNode* node);
00032
00033 template<> inline PlannerObstacle2D* allocate() {
00034 throw std::runtime_error("cannot plist::allocate generic instances (PlannerObstacle2D)");
00035 }
00036 template<> inline PlannerObstacle3D* allocate() {
00037 throw std::runtime_error("cannot plist::allocate generic instances (PlannerObstacle3D)");
00038 }
00039 template<> void inline assign<PlannerObstacle2D>(PlannerObstacle2D&, PlannerObstacle2D const&) { throw std::runtime_error("cannot assign"); }
00040 template<> void inline assign<PlannerObstacle3D>(PlannerObstacle3D&, PlannerObstacle3D const&) { throw std::runtime_error("cannot assign"); }
00041 }
00042
00043 namespace DualCoding {
00044 class ShapeRoot;
00045 }
00046
00047
00048
00049
00050 template <size_t N>
00051 class PlannerObstacle : public plist::Dictionary {
00052 public:
00053
00054 enum ObstacleGeometry {
00055 RECTANGULAR_OBS=2,
00056 CIRCULAR_OBS=3,
00057 ELLIPTICAL_OBS=5,
00058 CONVEX_POLY_OBS=7,
00059 HIERARCHICAL_OBS=11,
00060 BOX_OBS=13,
00061 CYLINDRICAL_OBS=17,
00062 SPHERICAL_OBS=19,
00063 ELLIPSOID_OBS=23
00064 };
00065
00066
00067 explicit PlannerObstacle(ObstacleGeometry geom, const std::string& t) : plist::Dictionary(), name(), type(t), geometry(geom), shapeId(-1) { init(); }
00068
00069
00070 virtual ~PlannerObstacle() {}
00071
00072
00073 template <typename T>
00074 static int sgn(T x) { return x < 0 ? -1 : 1; }
00075
00076
00077 plist::Primitive<std::string> name;
00078
00079 static void convertShapeToPlannerObstacle(const DualCoding::ShapeRoot& shape,
00080 float inflation,
00081 std::vector<PlannerObstacle*> &obstacles);
00082
00083
00084
00085
00086
00087
00088
00089
00090 virtual void updatePosition(const fmat::SubVector<N,const fmat::fmatReal>& newPos) = 0;
00091
00092
00093 virtual void rotate(const fmat::SubVector<N,const fmat::fmatReal>& origin,
00094 const fmat::SubMatrix<N,N,const fmat::fmatReal>& rot) = 0;
00095
00096
00097 void rotate(const fmat::SubMatrix<N,N,const fmat::fmatReal>& rot) { rotate(getCenter(), rot); }
00098
00099
00100 virtual fmat::Column<N> getCenter() const = 0;
00101
00102
00103 virtual BoundingBox<N> getBoundingBox() const = 0;
00104
00105
00106 bool collides(const PlannerObstacle<N>& other) const;
00107
00108
00109 virtual bool collides(const fmat::SubVector<N,const fmat::fmatReal>& point) const = 0;
00110
00111
00112
00113 virtual fmat::Column<N> getSupport(const fmat::SubVector<N,const fmat::fmatReal>& direction) const = 0;
00114
00115
00116 virtual fmat::Column<N> gradient(const fmat::SubVector<N,const fmat::fmatReal>& pt) const = 0;
00117
00118 virtual std::string toString() const;
00119 friend std::ostream& operator<<(std::ostream& os, const PlannerObstacle& po) { return os << po.toString(); }
00120
00121 ObstacleGeometry getObstacleGeometry() const { return geometry; }
00122
00123 int getShapeId() const { return shapeId; }
00124 void setShapeId(int id) { shapeId = id; }
00125
00126 const std::string& getTypeName() const { return type; }
00127
00128 typedef FamilyFactory<PlannerObstacle,std::string> registry_t;
00129 static registry_t& getRegistry() { static registry_t registry; return registry; }
00130
00131 PLIST_CLONE_FWD(PlannerObstacle);
00132
00133 protected:
00134
00135 PlannerObstacle(const PlannerObstacle& o) : plist::Dictionary(), name(o.name),
00136 type(o.type), geometry(o.geometry), shapeId(o.shapeId) { init(); }
00137
00138 PlannerObstacle& operator=(const PlannerObstacle& o) {
00139 name = o.name;
00140 type = o.type;
00141 geometry = o.geometry;
00142 init();
00143 return *this;
00144 }
00145
00146 void init() {
00147 addEntry("Name",name,"Human readable name for debugging, display");
00148 addEntry(".type",type,"Allows polymorphic load/save, must match known class name");
00149 setLoadSavePolicy(FIXED,SYNC);
00150 }
00151
00152 plist::Primitive<std::string> type;
00153 ObstacleGeometry geometry;
00154 int shapeId;
00155 };
00156
00157 template<size_t N>
00158 std::string PlannerObstacle<N>::toString() const {
00159 std::ostringstream os;
00160 os << "PlannerObstacle[type=" << type << ",name=" << name << "]";
00161 return os.str();
00162 }
00163
00164
00165 class RectangularObstacle: public PlannerObstacle2D {
00166 protected:
00167 friend class ConvexPolyObstacle;
00168
00169
00170 static const std::string autoRegisterName;
00171
00172
00173 fmat::Column<2> center;
00174
00175
00176 fmat::Column<2> minEx;
00177
00178 fmat::Column<2> maxEx;
00179
00180
00181 BoundingBox2D bBox;
00182
00183
00184 fmat::Matrix<2,2> unrot;
00185
00186
00187
00188
00189
00190
00191 fmat::Matrix<4,2> points;
00192
00193 public:
00194
00195 RectangularObstacle(): PlannerObstacle2D(RECTANGULAR_OBS,autoRegisterName), center(), minEx(), maxEx(), bBox(), unrot(fmat::Matrix<2,2>::identity()), points() {}
00196
00197
00198 RectangularObstacle(const fmat::SubVector<2,const fmat::fmatReal>& centerPoint,
00199 const fmat::SubVector<2,const fmat::fmatReal>& extents,
00200 fmat::fmatReal orient)
00201 : PlannerObstacle2D(RECTANGULAR_OBS,autoRegisterName), center(), minEx(), maxEx(), bBox(), unrot(), points()
00202 {
00203 reset(centerPoint,extents,orient);
00204 }
00205
00206
00207 RectangularObstacle(const BoundingBox2D& bb, const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot, const fmat::SubVector<2,const fmat::fmatReal>& off)
00208 : PlannerObstacle2D(RECTANGULAR_OBS,autoRegisterName), center(), minEx(), maxEx(), bBox(), unrot(), points()
00209 {
00210 fmat::Column<2> c(bb.getCenter()), d(bb.getDimensions());
00211 reset(rot*c+off, d/2, rot);
00212 }
00213
00214
00215 RectangularObstacle& operator=(const RectangularObstacle& o) {
00216 PlannerObstacle2D::operator=(o);
00217 center=o.center;
00218 minEx=o.minEx;
00219 maxEx=o.maxEx;
00220 bBox=o.bBox;
00221 unrot=o.unrot;
00222 points=o.points;
00223 return *this;
00224 }
00225
00226 using PlannerObstacle2D::collides;
00227
00228
00229 virtual bool collides(const fmat::SubVector<2,const fmat::fmatReal>& point) const;
00230
00231 bool collides(const RectangularObstacle& other) const;
00232 bool collides(const CircularObstacle& other) const;
00233 bool collides(const EllipticalObstacle& other) const;
00234
00235 virtual fmat::Column<2> getSupport(const fmat::SubVector<2,const fmat::fmatReal>& direction) const;
00236
00237
00238 virtual void reset(const fmat::Column<2>& centerPoint, const fmat::Column<2>& extents, fmat::fmatReal orient) {
00239 reset(centerPoint,extents,fmat::rotation2D(orient));
00240 }
00241
00242
00243 virtual void reset(fmat::Column<2> centerPoint,
00244 const fmat::SubVector<2,const fmat::fmatReal>& extents,
00245 const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot);
00246
00247 virtual void updatePosition(const fmat::SubVector<2, const fmat::fmatReal>& newPos);
00248
00249 using PlannerObstacle2D::rotate;
00250 virtual void rotate(const fmat::SubVector<2,const fmat::fmatReal>& origin,
00251 const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot);
00252
00253
00254 virtual BoundingBox2D getBoundingBox() const { return bBox; }
00255
00256 virtual fmat::Column<2> gradient(const fmat::SubVector<2,const fmat::fmatReal>& pt) const;
00257
00258 virtual std::string toString() const;
00259
00260
00261 virtual fmat::Column<2> getCenter() const { return center; }
00262
00263
00264 float getWidth() const { return maxEx[0] - minEx[0]; }
00265
00266 float getHeight() const { return maxEx[1] - minEx[1]; }
00267
00268 fmat::Column<2> getExtents() const { return (maxEx-minEx)/2; }
00269
00270 float getOrientation() const;
00271
00272 enum CornerOrder {
00273 TOP_RIGHT,
00274 TOP_LEFT,
00275 BOTTOM_LEFT,
00276 BOTTOM_RIGHT,
00277 NUM_CORNERS
00278 };
00279
00280
00281 fmat::Column<2> getCorner(size_t i) const { return fmat::pack(points(i,0),points(i,1)); }
00282
00283
00284 virtual void bloat(float amount);
00285
00286
00287 virtual void contract(float amount);
00288
00289 virtual void loadXML(xmlNode* node);
00290 virtual void saveXML(xmlNode * node) const;
00291 using plist::DictionaryBase::saveXML;
00292
00293
00294 PLIST_CLONE_DEF(RectangularObstacle,new RectangularObstacle(*this));
00295 };
00296
00297
00298 class CircularObstacle : public PlannerObstacle2D {
00299 protected:
00300
00301 static const std::string autoRegisterName;
00302
00303
00304 fmat::Column<2> center;
00305
00306
00307 fmat::fmatReal radius;
00308
00309 public:
00310
00311 CircularObstacle() : PlannerObstacle2D(CIRCULAR_OBS,autoRegisterName),
00312 center(), radius(0) {}
00313
00314
00315 CircularObstacle(fmat::fmatReal x, fmat::fmatReal y, fmat::fmatReal r) : PlannerObstacle2D(CIRCULAR_OBS,autoRegisterName),
00316 center(fmat::pack(x,y)), radius(r) {}
00317
00318
00319 CircularObstacle(const fmat::Column<2>& c, fmat::fmatReal r) : PlannerObstacle2D(CIRCULAR_OBS,autoRegisterName),
00320 center(c), radius(r) {}
00321
00322
00323 CircularObstacle& operator=(const CircularObstacle& o) {
00324 PlannerObstacle2D::operator=(o);
00325 center=o.center;
00326 radius=o.radius;
00327 return *this;
00328 }
00329
00330 using PlannerObstacle2D::collides;
00331
00332
00333 virtual bool collides(const fmat::SubVector<2,const fmat::fmatReal>& point) const {
00334 return (point - center).sumSq() < radius*radius;
00335 }
00336
00337 bool collides(const CircularObstacle& other) const;
00338
00339 virtual fmat::Column<2> getSupport(const fmat::SubVector<2,const fmat::fmatReal>& direction) const;
00340
00341 virtual fmat::Column<2> getCenter() const { return center; }
00342 virtual fmat::fmatReal getRadius() const { return radius; }
00343 virtual void setRadius(fmat::fmatReal r) { radius = r; }
00344
00345 virtual void updatePosition(const fmat::SubVector<2, const fmat::fmatReal>& newPos) { center = newPos; }
00346
00347 using PlannerObstacle2D::rotate;
00348 virtual void rotate(const fmat::SubVector<2,const fmat::fmatReal>& origin,
00349 const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot) {
00350 updatePosition(rot * (getCenter()-origin) + origin);
00351 }
00352
00353 virtual BoundingBox2D getBoundingBox() const {
00354 return BoundingBox2D(center - radius, center + radius);
00355 }
00356
00357 virtual fmat::Column<2> gradient(const fmat::SubVector<2,const fmat::fmatReal>& pt) const;
00358
00359 virtual std::string toString() const;
00360
00361
00362 virtual void bloat(float amount) { radius += amount; }
00363
00364 virtual void contract(float amount) { radius += amount; }
00365
00366 virtual void loadXML(xmlNode* node);
00367 virtual void saveXML(xmlNode * node) const;
00368 using plist::DictionaryBase::saveXML;
00369
00370
00371 PLIST_CLONE_DEF(CircularObstacle,new CircularObstacle(*this));
00372 };
00373
00374
00375 class EllipticalObstacle : public PlannerObstacle2D {
00376 protected:
00377
00378 static const std::string autoRegisterName;
00379
00380 public:
00381
00382 fmat::Column<2> focus1;
00383
00384
00385 fmat::Column<2> focus2;
00386
00387
00388 fmat::Column<2> center;
00389
00390
00391 fmat::fmatReal semimajor;
00392
00393
00394 fmat::fmatReal semiminor;
00395
00396
00397 EllipticalObstacle() : PlannerObstacle2D(ELLIPTICAL_OBS,autoRegisterName),
00398 focus1(), focus2(), center(), semimajor(), semiminor() {}
00399
00400
00401
00402 EllipticalObstacle(const fmat::Column<2>& c, fmat::fmatReal _semimajor, fmat::fmatReal _semiminor, fmat::fmatReal orientation) : PlannerObstacle2D(ELLIPTICAL_OBS,autoRegisterName),
00403 focus1(), focus2(), center(c), semimajor(_semimajor), semiminor(_semiminor) { reset(c, _semimajor, _semiminor, orientation); }
00404
00405
00406 EllipticalObstacle(const fmat::Column<2>& c, fmat::fmatReal r) : PlannerObstacle2D(ELLIPTICAL_OBS,autoRegisterName),
00407 focus1(c), focus2(c), center(c), semimajor(r), semiminor(r) {}
00408
00409
00410 EllipticalObstacle& operator=(const EllipticalObstacle& o) {
00411 PlannerObstacle2D::operator=(o);
00412 focus1=o.focus1;
00413 focus2=o.focus2;
00414 center=o.center;
00415 semimajor=o.semimajor;
00416 semiminor=o.semiminor;
00417 return *this;
00418 }
00419
00420
00421
00422 void reset(const fmat::Column<2>& f1, const fmat::Column<2>& f2, fmat::fmatReal s);
00423
00424
00425
00426 void reset(const fmat::Column<2>& c, fmat::fmatReal smajor, fmat::fmatReal sminor, fmat::fmatReal ori);
00427
00428
00429 void reset(const fmat::Column<2>& c, fmat::fmatReal radius) {
00430 focus1 = focus2 = center = c;
00431 semimajor = semiminor = std::abs(radius);
00432 }
00433
00434 using PlannerObstacle2D::collides;
00435
00436
00437 virtual bool collides(const fmat::SubVector<2,const fmat::fmatReal>& point) const {
00438 return (point - focus1).norm() + (point - focus2).norm() < 2*semimajor;
00439 }
00440
00441 virtual fmat::Column<2> getSupport(const fmat::SubVector<2,const fmat::fmatReal>& direction) const;
00442
00443 virtual fmat::Column<2> getCenter() const { return center; }
00444
00445 virtual void updatePosition(const fmat::SubVector<2, const fmat::fmatReal>& newPos);
00446
00447 using PlannerObstacle2D::rotate;
00448 virtual void rotate(const fmat::SubVector<2,const fmat::fmatReal>& origin,
00449 const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot);
00450
00451
00452 float getOrientation() const { return std::atan2(focus1[1] - focus2[1], focus1[0] - focus2[0]); }
00453
00454
00455 fmat::Matrix<2,2> getRotation() const;
00456
00457
00458
00459
00460 fmat::Column<2> getPointOnEdge(fmat::fmatReal theta) const {
00461 return getPointOnEdge(fmat::pack(std::cos(theta),std::sin(theta)));
00462 }
00463
00464
00465
00466 fmat::Column<2> getPointOnEdge(const fmat::Column<2>& direction) const;
00467
00468 virtual BoundingBox2D getBoundingBox() const;
00469
00470
00471
00472 virtual fmat::Column<2> gradient(const fmat::SubVector<2,const fmat::fmatReal>& pt) const;
00473
00474 virtual std::string toString() const;
00475
00476
00477 virtual void bloat(float amount) { reset(center, semimajor+amount, semiminor+amount, getOrientation()); }
00478
00479 virtual void contract(float amount) { reset(center, semimajor-amount, semiminor-amount, getOrientation()); }
00480
00481 virtual void loadXML(xmlNode* node);
00482 virtual void saveXML(xmlNode* node) const;
00483 using plist::DictionaryBase::saveXML;
00484
00485
00486 PLIST_CLONE_DEF(EllipticalObstacle,new EllipticalObstacle(*this));
00487 };
00488
00489
00490
00491 class ConvexPolyObstacle : public PlannerObstacle2D {
00492 protected:
00493
00494 static const std::string autoRegisterName;
00495
00496 std::vector<fmat::Column<2> > points;
00497 std::vector<fmat::Column<2> > normals;
00498
00499 public:
00500
00501 ConvexPolyObstacle() : PlannerObstacle2D(CONVEX_POLY_OBS,autoRegisterName), points(), normals() {}
00502
00503
00504 ConvexPolyObstacle& operator=(const ConvexPolyObstacle& o) {
00505 PlannerObstacle2D::operator=(o);
00506 points = o.points;
00507 normals = o.normals;
00508 return *this;
00509 }
00510
00511
00512 const std::vector<fmat::Column<2> >& getPoints() const { return points; }
00513
00514
00515 const std::vector<fmat::Column<2> >& getNormals() const { return normals; }
00516
00517
00518
00519
00520
00521
00522
00523 void hull(const std::set<fmat::Column<2> >& p);
00524
00525
00526 void clear() { points.clear(); normals.clear(); }
00527
00528
00529 void addPoint(const fmat::Column<2>& p);
00530
00531
00532 void close();
00533
00534 using PlannerObstacle2D::collides;
00535
00536 virtual bool collides(const fmat::SubVector<2,const fmat::fmatReal>& point) const;
00537
00538 bool collides(const RectangularObstacle& other) const;
00539
00540 bool collides(const CircularObstacle& other) const;
00541
00542 bool collides(const ConvexPolyObstacle& other) const;
00543
00544 virtual fmat::Column<2> getSupport(const fmat::SubVector<2,const fmat::fmatReal>& direction) const;
00545
00546 virtual fmat::Column<2> getCenter() const;
00547 virtual void updatePosition(const fmat::SubVector<2, const fmat::fmatReal>& newPos) { offset(newPos-getCenter()); }
00548
00549 using PlannerObstacle2D::rotate;
00550 virtual void rotate(const fmat::SubVector<2,const fmat::fmatReal>& origin,
00551 const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot);
00552 virtual BoundingBox2D getBoundingBox() const;
00553
00554 virtual void offset(const fmat::Column<2>& off);
00555 virtual fmat::Column<2> gradient(const fmat::SubVector<2,const fmat::fmatReal>& pt) const;
00556
00557 virtual std::string toString() const;
00558
00559 virtual void loadXML(xmlNode* node);
00560 virtual void saveXML(xmlNode * node) const;
00561 using plist::DictionaryBase::saveXML;
00562
00563
00564 PLIST_CLONE_DEF(ConvexPolyObstacle,new ConvexPolyObstacle(*this));
00565 };
00566
00567
00568 class HierarchicalObstacle : public PlannerObstacle2D {
00569 protected:
00570
00571 static const std::string autoRegisterName;
00572
00573
00574 void recalculateBoundingBox();
00575
00576
00577 void expandBoundingBox(PlannerObstacle2D& other);
00578
00579 std::vector<PlannerObstacle2D*> obstacles;
00580
00581 BoundingBox2D aabb;
00582
00583 fmat::Column<2> center;
00584 fmat::Matrix<2,2> rotation;
00585
00586 public:
00587
00588 HierarchicalObstacle()
00589 : PlannerObstacle2D(HIERARCHICAL_OBS,autoRegisterName), obstacles(), aabb(), center(), rotation(fmat::Matrix<2,2>::identity()) {}
00590
00591
00592 HierarchicalObstacle(const HierarchicalObstacle& ho)
00593 : PlannerObstacle2D(ho), obstacles(), aabb(ho.aabb), center(ho.center), rotation(ho.rotation)
00594 {
00595 obstacles.reserve(ho.obstacles.size());
00596 for(std::vector<PlannerObstacle2D*>::const_iterator it=ho.obstacles.begin(); it!=ho.obstacles.end(); ++it) {
00597 obstacles.push_back(dynamic_cast<PlannerObstacle2D*>((*it)->clone()));
00598 }
00599 }
00600
00601
00602 HierarchicalObstacle& operator=(const HierarchicalObstacle& o) {
00603 PlannerObstacle2D::operator=(o);
00604 clear();
00605 obstacles.reserve(o.obstacles.size());
00606 for(std::vector<PlannerObstacle2D*>::const_iterator it=o.obstacles.begin(); it!=o.obstacles.end(); ++it) {
00607 obstacles.push_back(dynamic_cast<PlannerObstacle2D*>((*it)->clone()));
00608 }
00609 aabb=o.aabb;
00610 center=o.center;
00611 rotation=o.rotation;
00612 return *this;
00613 }
00614
00615
00616 virtual ~HierarchicalObstacle() { clear(); }
00617
00618
00619 template <class T>
00620 void getObstacles(std::vector<T> &obs) const;
00621
00622 const std::vector<PlannerObstacle2D*>& getObstacles() const { return obstacles; }
00623
00624 using PlannerObstacle2D::collides;
00625
00626 virtual bool collides(const fmat::SubVector<2,const fmat::fmatReal>& point) const;
00627
00628 virtual fmat::Column<2> getSupport(const fmat::SubVector<2,const fmat::fmatReal>& direction) const;
00629
00630 virtual BoundingBox2D getBoundingBox() const { return aabb; }
00631
00632 virtual fmat::Column<2> getCenter() const { return center; }
00633 virtual fmat::Matrix<2,2> getRotation() const { return rotation; }
00634
00635 virtual void updatePosition(const fmat::SubVector<2, const fmat::fmatReal>& newPos);
00636
00637
00638 virtual void updateRotation(const fmat::Matrix<2,2>& rot) { rotation = rot; }
00639
00640 using PlannerObstacle2D::rotate;
00641 virtual void rotate(const fmat::SubVector<2,const fmat::fmatReal>& origin,
00642 const fmat::SubMatrix<2,2,const fmat::fmatReal>& rot);
00643
00644 virtual fmat::Column<2> gradient(const fmat::SubVector<2,const fmat::fmatReal>& pt) const;
00645
00646 virtual std::string toString() const;
00647
00648
00649 void clear() {
00650 for (unsigned int i = 0; i < obstacles.size(); i++)
00651 delete obstacles[i];
00652 obstacles.clear(); recalculateBoundingBox();
00653 }
00654
00655
00656
00657 void add(PlannerObstacle2D* o) { obstacles.push_back(o); expandBoundingBox(*o); }
00658
00659
00660 PLIST_CLONE_DEF(HierarchicalObstacle,new HierarchicalObstacle(*this));
00661 };
00662
00663 template <class T>
00664 void HierarchicalObstacle::getObstacles(std::vector<T> &obs) const {
00665 for (unsigned int i = 0; i < obstacles.size(); i++) {
00666 T t = dynamic_cast<T>(obstacles[i]);
00667 if (t)
00668 obs.push_back(t);
00669 }
00670 }
00671
00672 class BoxObstacle : public PlannerObstacle3D {
00673 protected:
00674
00675 static const std::string autoRegisterName;
00676
00677
00678 fmat::Column<3> center;
00679
00680
00681 fmat::Column<3> minEx;
00682
00683 fmat::Column<3> maxEx;
00684
00685
00686 BoundingBox3D bBox;
00687
00688
00689 fmat::Matrix<3,3> unrot;
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 fmat::Matrix<8,3> points;
00703
00704 public:
00705
00706 BoxObstacle() : PlannerObstacle3D(BOX_OBS,autoRegisterName),
00707 center(), minEx(), maxEx(), bBox(), unrot(fmat::Matrix<3,3>::identity()), points() {}
00708
00709
00710 BoxObstacle(const fmat::SubVector<3,const fmat::fmatReal>& centerPoint,
00711 const fmat::SubVector<3,const fmat::fmatReal>& extents,
00712 const fmat::SubMatrix<3,3,const fmat::fmatReal>& orient)
00713 : PlannerObstacle3D(BOX_OBS,autoRegisterName), center(), minEx(), maxEx(), bBox(), unrot(), points()
00714 {
00715 reset(centerPoint,extents,orient);
00716 }
00717
00718
00719 BoxObstacle(const BoundingBox3D& bb,
00720 const fmat::SubMatrix<3,3,const fmat::fmatReal>& rot,
00721 const fmat::SubVector<3,const fmat::fmatReal>& off)
00722 : PlannerObstacle3D(BOX_OBS,autoRegisterName), center(), minEx(), maxEx(), bBox(), unrot(), points()
00723 {
00724 fmat::Column<3> c(bb.getCenter()), d(bb.getDimensions());
00725 reset(rot*c+off, d/2, rot);
00726 }
00727
00728
00729 BoxObstacle& operator=(const BoxObstacle& o) {
00730 PlannerObstacle3D::operator=(o);
00731 center=o.center;
00732 minEx=o.minEx;
00733 maxEx=o.maxEx;
00734 bBox=o.bBox;
00735 unrot=o.unrot;
00736 points=o.points;
00737 return *this;
00738 }
00739
00740
00741 virtual void reset(fmat::Column<3> centerPoint,
00742 const fmat::SubVector<3,const fmat::fmatReal>& extents,
00743 const fmat::SubMatrix<3,3,const fmat::fmatReal>& rot);
00744
00745 virtual void updatePosition(const fmat::SubVector<3, const fmat::fmatReal>& newPos);
00746
00747 using PlannerObstacle3D::rotate;
00748 virtual void rotate(const fmat::SubVector<3,const fmat::fmatReal>& origin,
00749 const fmat::SubMatrix<3,3,const fmat::fmatReal>& rot);
00750
00751 virtual std::string toString() const;
00752
00753 virtual fmat::Column<3> getCenter() const { return center; }
00754 virtual BoundingBox3D getBoundingBox() const { return bBox; }
00755
00756 using PlannerObstacle3D::collides;
00757 virtual bool collides(const fmat::SubVector<3,const fmat::fmatReal>& point) const;
00758
00759 virtual fmat::Column<3> getSupport(const fmat::SubVector<3,const fmat::fmatReal>& direction) const;
00760
00761 virtual fmat::Column<3> gradient(const fmat::SubVector<3,const fmat::fmatReal>& pt) const;
00762
00763
00764 float getLength() const { return maxEx[0] - minEx[0]; }
00765
00766 float getWidth() const { return maxEx[1] - minEx[1]; }
00767
00768 float getHeight() const { return maxEx[2] - minEx[2]; }
00769
00770 fmat::Column<3> getExtents() const { return (maxEx-minEx)/2; }
00771
00772 enum CornerOrder {
00773 TOP_UPPER_RIGHT,
00774 TOP_LOWER_RIGHT,
00775 TOP_LOWER_LEFT,
00776 TOP_UPPER_LEFT,
00777 BOTTOM_UPPER_RIGHT,
00778 BOTTOM_LOWER_RIGHT,
00779 BOTTOM_LOWER_LEFT,
00780 BOTTOM_UPPER_LEFT,
00781 NUM_CORNERS
00782 };
00783
00784
00785 fmat::Column<3> getCorner(size_t i) const { return fmat::pack(points(i,0),points(i,1),points(i,2)); }
00786
00787
00788 virtual void bloat(float amount);
00789
00790
00791 virtual void contract(float amount);
00792
00793 virtual void loadXML(xmlNode* node);
00794 virtual void saveXML(xmlNode * node) const;
00795 using plist::DictionaryBase::saveXML;
00796
00797
00798 PLIST_CLONE_DEF(BoxObstacle,new BoxObstacle(*this));
00799 };
00800
00801
00802 class CylindricalObstacle : public PlannerObstacle3D {
00803 protected:
00804
00805 static const std::string autoRegisterName;
00806
00807
00808 fmat::Column<3> center;
00809
00810
00811 fmat::Matrix<3,3> orientation;
00812
00813
00814 fmat::fmatReal radius;
00815
00816
00817 fmat::fmatReal halfHeight;
00818
00819 public:
00820
00821 CylindricalObstacle() : PlannerObstacle3D(CYLINDRICAL_OBS,autoRegisterName),
00822 center(), orientation(), radius(0), halfHeight(0) {}
00823
00824 CylindricalObstacle(const fmat::SubVector<3,const fmat::fmatReal>& c,
00825 const fmat::SubMatrix<3,3,const fmat::fmatReal>& o,
00826 fmat::fmatReal r,
00827 fmat::fmatReal hh) :
00828 PlannerObstacle3D(CYLINDRICAL_OBS,autoRegisterName), center(c), orientation(o), radius(r), halfHeight(hh) {}
00829
00830
00831 CylindricalObstacle& operator=(const CylindricalObstacle& o) {
00832 PlannerObstacle3D::operator=(o);
00833 center=o.center;
00834 orientation=o.orientation;
00835 radius=o.radius;
00836 halfHeight=o.halfHeight;
00837 return *this;
00838 }
00839
00840 virtual void updatePosition(const fmat::SubVector<3, const fmat::fmatReal>& newPos) { center = newPos; }
00841 virtual void rotate(const fmat::SubVector<3,const fmat::fmatReal>& origin,
00842 const fmat::SubMatrix<3,3,const fmat::fmatReal>& rot) {
00843 center = rot * (center - origin) + origin;
00844 orientation = rot * orientation;
00845 }
00846 virtual fmat::Column<3> getCenter() const { return center; }
00847 virtual BoundingBox3D getBoundingBox() const;
00848
00849 using PlannerObstacle3D::collides;
00850 virtual bool collides(const fmat::SubVector<3,const fmat::fmatReal>& point) const;
00851
00852 virtual fmat::Column<3> getSupport(const fmat::SubVector<3,const fmat::fmatReal>& direction) const;
00853
00854 virtual fmat::Column<3> gradient(const fmat::SubVector<3,const fmat::fmatReal>& pt) const;
00855
00856 virtual void loadXML(xmlNode* node);
00857 virtual void saveXML(xmlNode* node) const;
00858 using plist::DictionaryBase::saveXML;
00859
00860
00861 PLIST_CLONE_DEF(CylindricalObstacle,new CylindricalObstacle(*this));
00862 };
00863
00864
00865 class SphericalObstacle : public PlannerObstacle3D {
00866 protected:
00867
00868 static const std::string autoRegisterName;
00869
00870
00871 fmat::Column<3> center;
00872
00873
00874 fmat::fmatReal radius;
00875
00876 public:
00877
00878 SphericalObstacle() : PlannerObstacle3D(SPHERICAL_OBS,autoRegisterName),
00879 center(), radius(0) {}
00880
00881
00882 SphericalObstacle(fmat::fmatReal x, fmat::fmatReal y, fmat::fmatReal z, fmat::fmatReal r) : PlannerObstacle3D(CIRCULAR_OBS,autoRegisterName),
00883 center(fmat::pack(x,y,z)), radius(r) {}
00884
00885
00886 SphericalObstacle(const fmat::Column<3>& c, fmat::fmatReal r) : PlannerObstacle3D(CIRCULAR_OBS,autoRegisterName),
00887 center(c), radius(r) {}
00888
00889
00890 SphericalObstacle& operator=(const SphericalObstacle& o) {
00891 PlannerObstacle3D::operator=(o);
00892 center=o.center;
00893 radius=o.radius;
00894 return *this;
00895 }
00896
00897 virtual void updatePosition(const fmat::SubVector<3, const fmat::fmatReal>& newPos) { center = newPos; }
00898
00899 virtual void rotate(const fmat::SubVector<3,const fmat::fmatReal>& origin,
00900 const fmat::SubMatrix<3,3,const fmat::fmatReal>& rot) { center = rot * (center - origin) + origin; }
00901
00902 virtual fmat::Column<3> getCenter() const { return center; }
00903 virtual fmat::fmatReal getRadius() const { return radius; }
00904 virtual BoundingBox3D getBoundingBox() const {
00905 return BoundingBox3D(center - radius, center + radius);
00906 }
00907
00908 using PlannerObstacle3D::collides;
00909
00910 virtual bool collides(const fmat::SubVector<3,const fmat::fmatReal>& point) const;
00911
00912 bool collides(const SphericalObstacle& other) const;
00913
00914 virtual fmat::Column<3> getSupport(const fmat::SubVector<3,const fmat::fmatReal>& direction) const;
00915
00916 virtual fmat::Column<3> gradient(const fmat::SubVector<3,const fmat::fmatReal>& pt) const;
00917
00918 virtual void loadXML(xmlNode* node);
00919 virtual void saveXML(xmlNode* node) const;
00920 using plist::DictionaryBase::saveXML;
00921
00922
00923 PLIST_CLONE_DEF(SphericalObstacle,new SphericalObstacle(*this));
00924 };
00925
00926 class EllipsoidObstacle : public PlannerObstacle3D {
00927 protected:
00928
00929 static const std::string autoRegisterName;
00930
00931
00932 fmat::Column<3> center;
00933
00934
00935 fmat::Matrix<3,3> orientation;
00936
00937
00938 fmat::Column<3> extents;
00939
00940 public:
00941
00942 EllipsoidObstacle() :
00943 PlannerObstacle3D(ELLIPSOID_OBS,autoRegisterName), center(), orientation(), extents() {}
00944
00945 EllipsoidObstacle(const fmat::SubVector<3, const fmat::fmatReal>& c,
00946 const fmat::SubMatrix<3,3, const fmat::fmatReal>& o,
00947 const fmat::SubVector<3, const fmat::fmatReal>& e) :
00948 PlannerObstacle3D(ELLIPSOID_OBS,autoRegisterName), center(c), orientation(o), extents(e) {}
00949
00950
00951 EllipsoidObstacle& operator=(const EllipsoidObstacle& o) {
00952 PlannerObstacle3D::operator=(o);
00953 center=o.center;
00954 orientation=o.orientation;
00955 extents=o.extents;
00956 return *this;
00957 }
00958
00959 virtual void updatePosition(const fmat::SubVector<3, const fmat::fmatReal>& newPos) { center = newPos; }
00960 virtual void rotate(const fmat::SubVector<3,const fmat::fmatReal>& origin,
00961 const fmat::SubMatrix<3,3,const fmat::fmatReal>& rot) {
00962 center = rot * (center - origin) + origin;
00963 orientation = rot * orientation;
00964 }
00965 virtual fmat::Column<3> getCenter() const { return center; }
00966 virtual BoundingBox3D getBoundingBox() const;
00967
00968 using PlannerObstacle3D::collides;
00969 virtual bool collides(const fmat::SubVector<3,const fmat::fmatReal>& point) const;
00970
00971 virtual fmat::Column<3> getSupport(const fmat::SubVector<3,const fmat::fmatReal>& direction) const;
00972
00973
00974 virtual fmat::Column<2> get2Support(const fmat::SubVector<2,const fmat::fmatReal>& direction) const;
00975
00976 virtual fmat::Column<3> gradient(const fmat::SubVector<3,const fmat::fmatReal>& pt) const;
00977
00978 virtual void loadXML(xmlNode* node);
00979 virtual void saveXML(xmlNode* node) const;
00980 using plist::DictionaryBase::saveXML;
00981
00982
00983 PLIST_CLONE_DEF(EllipsoidObstacle,new EllipsoidObstacle(*this));
00984 };
00985
00986 #endif