Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ShapeSpacePlanner3DR.h

Go to the documentation of this file.
00001 #if defined(TGT_HAS_ARMS)
00002 
00003 //-*-c++-*-
00004 #ifndef _SHAPE_SPACE_PLANNER_3DR_H_
00005 #define _SHAPE_SPACE_PLANNER_3DR_H_
00006 
00007 #include "Motion/Kinematics.h"
00008 #include "Planners/RRT/ShapeSpacePlannerBase.h"
00009 
00010 //================ RRTNode3DR ================
00011 
00012 template <size_t N>
00013 class ShapeSpacePlanner3DR;
00014 
00015 template <size_t N>
00016 class RRTNode3DR : public RRTNodeBase {
00017  public:
00018   
00019   class NodeValueWrapper {
00020   private:
00021     AngSignPi angles[(N==0)?1:N]; // funny array size to help older compilers that error on zero-sized arrays
00022   public:
00023     NodeValueWrapper() : angles() {}
00024       AngSignPi& operator[](int i)       { return angles[i]; }
00025       AngSignPi  operator[](int i) const { return angles[i]; }
00026   };
00027   
00028   typedef NodeValueWrapper NodeValue_t;
00029   typedef typename GenericRRTBase::PlannerResult<3> PlannerResult;
00030   NodeValue_t q;
00031   
00032   //! Constructor
00033   RRTNode3DR(const NodeValue_t &_q, unsigned int _parent) : RRTNodeBase(_parent), q(_q) {};
00034   
00035     class CollisionChecker : public ShapeSpaceCollisionCheckerBase<3> {
00036   protected:
00037     KinematicJoint* rootJ;
00038   public:
00039     fmat::Transform worldT;
00040   protected:
00041     
00042     class JointObstacle {
00043     public:
00044       BoxObstacle obstacle;
00045       KinematicJoint* joint;
00046       bool valid;
00047       
00048       JointObstacle() : obstacle(), joint(), valid() {}
00049       
00050         JointObstacle(KinematicJoint* _joint) : obstacle(), joint(_joint), valid(false) {
00051     obstacle.name = joint->outputOffset.get();
00052   }
00053       
00054     JointObstacle(const BoxObstacle& _obstacle,
00055       KinematicJoint* _joint,
00056       bool _valid) : obstacle(_obstacle), joint(_joint), valid(_valid) {}
00057       
00058             virtual ~JointObstacle() {}
00059       
00060       JointObstacle(const JointObstacle& other) : obstacle(other.obstacle), joint(other.joint), valid(other.valid) {}
00061         JointObstacle& operator=(const JointObstacle& other) {
00062                 obstacle = other.obstacle;
00063                 joint = other.joint;
00064                 valid = other.valid;
00065                 return *this;
00066         }
00067       
00068         bool collides(const JointObstacle& other) const { if (!other.valid) return false; return false; }
00069         bool collides(const PlannerObstacle3D& obs) const { return obs.collides(obstacle); }
00070       
00071         virtual bool setObstacle(const fmat::Transform& t, bool own=false);
00072     };
00073     
00074     class LinkObstacle : public JointObstacle {
00075     public:
00076       LinkComponent* link;
00077       
00078       LinkObstacle() : JointObstacle(), link() {}
00079       
00080         LinkObstacle(const JointObstacle& jObs) : JointObstacle(jObs.joint), link() {
00081     this->obstacle.name += "Component";
00082   }
00083       
00084     virtual ~LinkObstacle() {}
00085       
00086     void setLink(LinkComponent* _link) { link = _link; }
00087       
00088     LinkObstacle(const LinkObstacle& other) : JointObstacle(other.obstacle, other.joint, other.valid), link(other.link) {}
00089             LinkObstacle& operator=(const LinkObstacle& other) {
00090         JointObstacle(other.obstacle, other.joint, other.valid);
00091         link = other.link;
00092         return *this;
00093             }
00094       
00095             virtual bool setObstacle(const fmat::Transform& t, bool own=false); 
00096     };
00097     
00098   public:
00099     CollisionChecker(DualCoding::ShapeSpace & shs,
00100                      const DualCoding::Shape<DualCoding::PolygonData> &_worldBounds,
00101                      float _inflation,
00102                      unsigned int effectorOffset) :
00103       ShapeSpaceCollisionCheckerBase<3>(shs, _worldBounds, _inflation, false), rootJ(), worldT() {
00104       rootJ = kine->getKinematicJoint(effectorOffset)->cloneBranch();
00105       for (unsigned int i = 0; i < N; i++)
00106   rootJ = rootJ->getNextMobileAncestor();
00107       
00108       /* For the 3D arm planner, we have an arm that
00109        * has the potential to go beneath the ground.
00110        * Therefore, we add an obstacle that models
00111        * a large cube, 5m in length, width, and height
00112        * directly beneath the robot's position.
00113        * This ensures that no link in the arm will travel underground,
00114        * and potentially cause the robot to lift
00115        * itself off of the ground, which can be problematic. */
00116       const int size = 2500;
00117       fmat::Column<3> pos = worldT.translation();
00118       pos[2] -= float(2500);
00119       fmat::Matrix<3,3> rot = worldT.rotation();
00120       BoxObstacle* bo = new BoxObstacle(pos, fmat::pack(size,size,size), rot);
00121       bo->name = "GroundObstacle";
00122       obstacles.push_back(bo);
00123     }
00124     
00125       CollisionChecker(const CollisionChecker& other) : rootJ(other.rootJ) {}
00126     
00127         CollisionChecker operator=(const CollisionChecker& other) {
00128     rootJ = other.rootJ;
00129     return *this;
00130         }
00131     
00132         virtual bool collides(const NodeValue_t &qnew, PlannerResult* result=NULL) const;
00133     
00134         template<class T, class U>
00135     static bool checkComponent(std::vector<T>& full, const U& newObs, T& collisionObs);
00136     
00137   };
00138   
00139   static const unsigned int maxInterpolations = 100; //!< Maximum number of interpolation steps in interpolate() when @a truncate is true
00140   
00141   virtual float distance(const NodeValue_t &target);
00142   static void generateSample(const NodeValue_t &lower, const NodeValue_t &upper, NodeValue_t &sample);
00143   static Interp_t interpolate(const NodeValue_t &start, const NodeValue_t &target, const NodeValue_t &interp, 
00144             bool truncate, CollisionChecker *cc, NodeValue_t &reached, bool fromOtherTree);
00145   
00146   virtual std::string toString() const;
00147 };
00148 
00149 template<size_t N>
00150 float RRTNode3DR<N>::distance(const NodeValue_t &target) {
00151   float result = 0;
00152   for (size_t i = 0; i < N; i++) {
00153     result += target[i]*target[i];
00154   }
00155   return result;
00156 }
00157 
00158 template<size_t N>
00159 void RRTNode3DR<N>::generateSample(const NodeValue_t &lower, 
00160                                    const NodeValue_t &upper,
00161                                    NodeValue_t &sample) {
00162   for (size_t i = 0; i < N; i++) {
00163     sample[i] = randRange(lower[i], upper[i]);
00164   }
00165 }
00166 
00167 template<size_t N>
00168 RRTNodeBase::Interp_t RRTNode3DR<N>::interpolate(const NodeValue_t &start, const NodeValue_t &target, const NodeValue_t &interp, 
00169                                                  bool truncate, CollisionChecker *cc, NodeValue_t &reached, bool fromOtherTree) {
00170   NodeValue_t delta;
00171   int numSteps = 0;
00172   for (size_t i = 0; i < N; i++) {
00173     int steps = int(fabs(target[i]-start[i])/interp[i]);
00174     if (steps > numSteps)
00175       numSteps = steps;
00176   }
00177   for (size_t i = 0; i < N; i++) {
00178     delta[i] = (target[i]-start[i])/float(numSteps);
00179   }
00180   
00181   bool truncated = (unsigned int)numSteps > maxInterpolations && truncate;
00182   if ( truncated )
00183     numSteps = maxInterpolations;
00184   
00185   // Interpolate along the path and check for collisions
00186   reached = start;
00187   for (int t = 0; t < numSteps; t++) {
00188     for (unsigned int i = 0; i < N; i++) {
00189       reached[i] += delta[i];
00190     }
00191     if ( cc->collides(reached) )
00192       return COLLISION;
00193   }
00194   
00195   if ( !truncated )
00196     return REACHED;
00197   else
00198     return APPROACHED;
00199 }
00200 
00201 template<size_t N>
00202 std::string RRTNode3DR<N>::toString() const {
00203   char buff[100];
00204   string result;
00205   for (size_t i = 0; i < N; i++) {
00206     sprintf(buff, "%7.2f ", float(q[i]));
00207     result.append(result);
00208   }
00209   return result;
00210 }
00211 
00212 template<size_t N>
00213 bool RRTNode3DR<N>::CollisionChecker::collides(const NodeValue_t &qnew, RRTNode3DR<N>::PlannerResult* result) const {
00214   // set joint angles to test the NodeValue
00215   KinematicJoint* joint = rootJ;
00216   for (unsigned int i = 0; i < N; i++) {
00217     if (!joint) { // just in case...
00218       std::cout << "*** ERROR: Collision checker cannot find arm joints. Assuming collision." << std::endl;
00219       return true;
00220     }
00221     
00222     joint->setQ(qnew[i]);
00223     joint = joint->nextJoint();
00224     while (joint != NULL && joint->isMobile() == false) joint = joint->nextJoint();
00225   }
00226   
00227   // for check component
00228   LinkObstacle collisionObs;
00229   
00230   // create and assign array of joints
00231   std::vector<JointObstacle> obs;
00232   for (joint = rootJ; joint != NULL; joint = joint->nextJoint()) {
00233     obs.push_back(JointObstacle(joint));
00234     for (KinematicJoint::branch_iterator it = joint->getBranches().begin(); it != joint->getBranches().end(); ++it) {
00235       obs.push_back(JointObstacle(*it));
00236     }
00237   }
00238   
00239   for (unsigned int i = 0; i < obs.size(); i++) {
00240     // if the joint has no boundingbox at all, skip it
00241     if (!obs[i].setObstacle(worldT))
00242       continue;
00243     
00244     // test if new joint obstacle collides with any other joint obstacle
00245     std::vector<int> collidingJObs; collidingJObs.reserve((i == 0) ? 0 : i-1);
00246     for (int j = 0; j < (int)i-1; j++) { // i-1 so that we don't check adjacent joint collision
00247       if (obs[j].valid && obs[i].collides(obs[j])) {
00248   collidingJObs.push_back(j);
00249       }
00250     }
00251     
00252     // test if new joint obstacle collides with any planner obstacle
00253     std::vector<PlannerObstacle3D*> collidingPObs; collidingPObs.reserve(obstacles.size());
00254     for (unsigned int k = 0; k < obstacles.size(); k++) {
00255       if ((i != 0 || !(obstacles[k]->isBodyObstacle())) && obs[i].collides(*(obstacles[k]))) {
00256   collidingPObs.push_back(obstacles[k]);
00257       }
00258     }
00259     
00260     // if there are no collisions at all, skip to the next joint
00261     if (collidingJObs.empty() && collidingPObs.empty())
00262       continue;
00263     
00264     /* Assuming there is any collision, we now test each LinkComponent,
00265      * so we need to assign a vector of components, including the
00266      * joint's own obstacle */
00267     JointObstacle jointOwnObs(obs[i].joint);
00268     jointOwnObs.setObstacle(worldT, true); // true flag specifies we're using the LinkComponent BB, (without children)
00269     
00270     std::vector<LinkObstacle> componentObs(obs[i].joint->components.size(), LinkObstacle(obs[i]));
00271     for (unsigned int c = 0; c < obs[i].joint->components.size(); c++) {
00272       componentObs[c].setLink(&(obs[i].joint->components[c]));
00273       componentObs[c].setObstacle(worldT, true);
00274     }
00275     
00276     // if there is a collision with a joint obstacle, check the sub-components to confirm
00277     for (unsigned int jObs = 0; jObs < collidingJObs.size(); jObs++) {
00278       unsigned int numComponents = obs[collidingJObs[jObs]].joint->components.size();
00279       
00280       // if there aren't any subcomponents in either, then there must be a collision
00281       if (componentObs.size() == 0 && numComponents == 0) {
00282   if (result) {
00283     result->movingObstacle = new BoxObstacle(obs[i].obstacle);
00284     result->collidingObstacle = new BoxObstacle(obs[collidingJObs[jObs]].obstacle);
00285   }
00286   return true;
00287       }
00288       
00289       // set the second joint's components
00290       // but whenever one is added, check for collision with previous
00291       JointObstacle collidingOwnObs(obs[collidingJObs[jObs]]);
00292       collidingOwnObs.setObstacle(worldT, true);
00293       
00294       // check if both joints' own obstacles collide
00295       if (collidingOwnObs.collides(jointOwnObs)) {
00296   if (result) {
00297     result->movingObstacle = new BoxObstacle(collidingOwnObs.obstacle);
00298     result->collidingObstacle = new BoxObstacle(jointOwnObs.obstacle);
00299   }
00300   return true;
00301       }
00302       // check if the colliding joint's own obstacle collides with joint's components
00303       if (checkComponent(componentObs, collidingOwnObs, collisionObs)) {
00304   if (result) {
00305     result->movingObstacle = new BoxObstacle(collidingOwnObs.obstacle);
00306     result->collidingObstacle = new BoxObstacle(collisionObs.obstacle);
00307   }
00308   return true;
00309       }
00310       
00311       // check if any of the colliding joint's components collides with the joint's own obstacle
00312       LinkObstacle componentOb(obs[collidingJObs[jObs]]);
00313       for (unsigned int c = 0; i < numComponents; c++) {
00314   componentOb.setLink(&(obs[collidingJObs[jObs]].joint->components[c]));
00315   componentOb.setObstacle(worldT, true);
00316   if (componentOb.collides(jointOwnObs)) {
00317     if (result) {
00318       result->movingObstacle = new BoxObstacle(componentOb.obstacle);
00319       result->collidingObstacle = new BoxObstacle(jointOwnObs.obstacle);
00320     }
00321     return true;
00322   }
00323         
00324   // check if any of both joints' components collide
00325   if (checkComponent(componentObs, componentOb, collisionObs)) {
00326     if (result) {
00327       result->movingObstacle = new BoxObstacle(componentOb.obstacle);
00328       result->collidingObstacle = new BoxObstacle(collisionObs.obstacle);
00329     }
00330     return true;
00331   }
00332       }
00333     }
00334     
00335     // if there is a collision with a planner obstacle, check the subcomponents to confirm
00336     for (unsigned int p = 0; p < collidingPObs.size(); p++) {
00337       if ((i != 0 || !(collidingPObs[p]->isBodyObstacle())) && jointOwnObs.collides(*(collidingPObs[p]))) {
00338   if (result) {
00339     result->movingObstacle = new BoxObstacle(jointOwnObs.obstacle);
00340     result->collidingObstacle = collidingPObs[p]->clone();
00341   }
00342   return true;
00343       }
00344       if ((i != 0 || !(collidingPObs[p]->isBodyObstacle())) && checkComponent(componentObs, *(collidingPObs[p]), collisionObs)) {
00345   if (result) {
00346     result->movingObstacle = new BoxObstacle(collisionObs.obstacle);
00347     result->collidingObstacle = collidingPObs[p]->clone();
00348   }
00349   return true;
00350       }
00351     }
00352   }
00353   
00354   // no collision detected
00355   return false;
00356 }
00357 
00358 template<size_t N>
00359 template<class T, class U>
00360   bool RRTNode3DR<N>::CollisionChecker::checkComponent(std::vector<T>& full, const U& newObs, T& collisionObs) {
00361   for (unsigned int i = 0; i < full.size(); i++) {
00362     if (full[i].collides(newObs)) {
00363       collisionObs = full[i];
00364       return true;
00365     }
00366   }
00367   return false;
00368 }
00369 
00370 template<size_t N>
00371 bool RRTNode3DR<N>::CollisionChecker::JointObstacle::setObstacle(const fmat::Transform& t, bool own) {
00372   if (joint == NULL) {
00373     std::cout << "***ERROR Joint value is null in CollisionChecker." << std::endl;
00374     valid = false;
00375   }
00376   else {
00377     if (own)
00378       valid = joint->getOwnBB3D(t * joint->getFullT(), obstacle);
00379     else
00380       valid = joint->getBB3D(t * joint->getFullT(), obstacle);
00381   }
00382   return valid;
00383 }
00384 
00385 template<size_t N>
00386 bool RRTNode3DR<N>::CollisionChecker::LinkObstacle::setObstacle(const fmat::Transform& t, bool own) {
00387   if (this->joint == NULL || link == NULL) {
00388     std::cout << "***ERROR Joint/link value is null in CollisionChecker." << std::endl;
00389     this->valid = false;
00390   }
00391   else {
00392     if (own)
00393       this->valid = link->getOwnBB3D(t * this->joint->getFullT(), this->obstacle);
00394     else
00395       this->valid = link->getBB3D(t * this->joint->getFullT(), this->obstacle);
00396   }
00397   return this->valid;
00398 }
00399 
00400 //================ ShapeSpacePlanner3DR ================
00401 
00402 //! Plans a path in a n-dimensional angular space, uses forward kinematics for collision testing
00403 template <size_t N>
00404 class ShapeSpacePlanner3DR : public GenericRRT<RRTNode3DR<N>, 3> {
00405  public:
00406   typedef RRTNode3DR<N> NodeType_t;
00407   typedef typename NodeType_t::NodeValue_t NodeValue_t;
00408   typedef typename GenericRRTBase::PlannerResult<3> PlannerResult;
00409   
00410   ShapeSpacePlanner3DR(DualCoding::ShapeSpace &shs,
00411            const DualCoding::Shape<DualCoding::PolygonData> &worldBounds,
00412            float inflation,
00413            unsigned int effectorOffset,
00414            AdmissibilityPredicate<NodeType_t> *predicate=NULL);
00415   
00416   ShapeSpacePlanner3DR(const ShapeSpacePlanner3DR& other) {
00417     for (size_t i = 0; i < N; i++)
00418       joints[i] = other.joints[i];
00419   }
00420   
00421   ShapeSpacePlanner3DR operator=(const ShapeSpacePlanner3DR& other) {
00422     for (size_t i = 0; i < N; i++)
00423       joints[i] = other.joints[i];
00424     return *this;
00425   }
00426   
00427   KinematicJoint* joints[N];
00428   fmat::Transform worldT;
00429   
00430   virtual ~ShapeSpacePlanner3DR() {}
00431   
00432   using GenericRRT<NodeType_t, 3>::planPath;
00433   PlannerResult
00434     planPath(NodeValue_t start,
00435        NodeValue_t end,
00436        NodeValue_t interpolationStep,
00437        const fmat::Transform& _worldT,
00438        unsigned int _maxIterations=40000,
00439        std::vector<NodeValue_t> *pathResult=NULL,
00440        std::vector<NodeType_t> *treeStartResult=NULL,
00441        std::vector<NodeType_t> *treeEndResult=NULL);
00442   
00443   //! Populates a Shape<GraphicsData> with BoundingBoxes
00444   void plotTree(const std::vector<NodeType_t> &tree,
00445     Shape<GraphicsData> &graphics,
00446     rgb color=rgb(255,0,0));
00447   
00448   //! Populates a Shape<GraphicsData> with BoundingBoxes
00449   void plotPath(const std::vector<NodeValue_t> &tree,
00450     Shape<GraphicsData> &graphics,
00451     rgb color=rgb(255,0,0));
00452   
00453   //! Returns BoundingBox of each link, for plotTree()
00454   void getBoxes(std::vector<std::vector<std::pair<float,float> > >& boxes, const KinematicJoint& joint);
00455   
00456 };
00457 
00458 template<size_t N>
00459 ShapeSpacePlanner3DR<N>::ShapeSpacePlanner3DR(DualCoding::ShapeSpace &shs,
00460                                               const DualCoding::Shape<DualCoding::PolygonData> &worldBounds,
00461                                               float inflation,
00462                                               unsigned int effectorOffset,
00463                                               AdmissibilityPredicate<NodeType_t> *_predicate) :
00464   GenericRRT<NodeType_t, 3>::GenericRRT(new typename NodeType_t::CollisionChecker(shs, worldBounds, inflation, effectorOffset), _predicate),
00465   worldT() {
00466   KinematicJoint* joint = kine->getKinematicJoint(effectorOffset)->cloneBranch();
00467   if (joint->isMobile() == false) joint = joint->getNextMobileAncestor();
00468   NodeValue_t lower, upper;
00469   
00470   for (int i = (int)N-1; i >= 0; i--) {
00471     lower[i] = joint->qmin;
00472     upper[i] = joint->qmax;
00473     joints[i] = joint;
00474     joint = joint->getNextMobileAncestor();
00475   }
00476   
00477   this->setLimits(lower, upper);
00478 }
00479 
00480 template<size_t N>
00481 typename ShapeSpacePlanner3DR<N>::PlannerResult
00482 ShapeSpacePlanner3DR<N>::planPath(NodeValue_t start,
00483                                   NodeValue_t end,
00484                                   NodeValue_t interpolationStep,
00485                                   const fmat::Transform& _worldT,
00486                                   unsigned int maxIterations,
00487                                   std::vector<NodeValue_t> *pathResult,
00488                                   std::vector<NodeType_t> *treeStartResult,
00489                                   std::vector<NodeType_t> *treeEndResult) {
00490   this->setInterpolation(interpolationStep);
00491   this->worldT = _worldT;
00492   this->cc->worldT = _worldT;
00493   return GenericRRT<NodeType_t, 3>::planPath(start, end, maxIterations,
00494                pathResult, treeStartResult, treeEndResult);
00495 }
00496 
00497 template<size_t N>
00498 void ShapeSpacePlanner3DR<N>::plotTree(const std::vector<NodeType_t> &tree,
00499                                        Shape<GraphicsData> &graphics,
00500                                        rgb color) {
00501   for ( unsigned int i = 0; i < tree.size(); i++ ) {
00502     // set joint values
00503     for (size_t j = 0; j < N; j++)
00504       joints[j]->setQ(tree[i].q[j]);
00505     
00506     // for now, just plot the location of the Gripper
00507     KinematicJoint* j = joints[N-1];
00508     
00509     while (j->nextJoint() != NULL) {
00510       j = j->nextJoint();
00511     }
00512     
00513     fmat::Column<3> pos = j->getWorldPosition();
00514     
00515     graphics->add(new GraphicsData::CircleElement("start", DualCoding::GraphicsData::xyPair(pos[0],pos[1]), 5, true, color));
00516     
00517     /*// get bounding box of every link
00518       std::vector<std::vector<std::pair<float,float> > > boxes;
00519       getBoxes(boxes, *joints[0]);*/
00520     
00521     /*// add to element
00522       for (size_t b = 0; b < boxes.size(); b++) {
00523       graphics->add(new GraphicsData::PolygonElement(boxes[b], true, color));
00524       }*/
00525   }
00526 }
00527 
00528 template<size_t N>
00529 void ShapeSpacePlanner3DR<N>::plotPath(const std::vector<NodeValue_t> &path,
00530                                        Shape<GraphicsData> &graphics,
00531                                        rgb color) {
00532   for ( unsigned int i = 0; i < path.size(); i++ ) {
00533     // set joint values
00534     for (size_t j = 0; j < N; j++)
00535       joints[j]->setQ(path[i][j]);
00536     
00537     // set robot transformation in WorldSpace (converts from BaseFrame -> "WorldFrame")
00538     DualCoding::Point p = VRmixin::theAgent->getCentroid();
00539     worldT.translation() = -fmat::pack(p.coordX(),p.coordY(),p.coordZ());
00540     worldT.rotation() = fmat::rotationZ(-VRmixin::theAgent->getOrientation());
00541     
00542     // set first and last to different colors
00543     rgb theColor;
00544     if (i == 0) theColor = rgb(255,0,0);
00545     else if (i == path.size()-1) theColor = rgb(0,255,0);
00546     else theColor = color;
00547         
00548     KinematicJoint * j = joints[0];
00549 
00550     // testing method: boundingbox using the width, height, length values of the BoxObstacle object of each joint and their components
00551         
00552     while (j->nextJoint() != NULL)
00553       {
00554   BoxObstacle bo;
00555   float w, h, l;
00556   fmat::Quaternion q;
00557   fmat::Column<3> centroid;
00558   j->getOwnBB3D(worldT * j->getFullT(), bo);
00559   if (bo.getExtents() != fmat::Column<3>()) {
00560     // set points
00561     centroid = bo.getCenter();
00562     w = bo.getWidth();
00563     h = bo.getHeight();
00564     l = bo.getLength();
00565     q = fmat::Quaternion::fromMatrix(bo.getOrientation());
00566     graphics->add(new GraphicsData::BoundingBoxElement(j->outputOffset.get(), q, centroid, l, w, h));
00567                 
00568     BoxObstacle boc;
00569     float cw, ch, cl;
00570     fmat::Quaternion cq;
00571     fmat::Column<3> ccentroid;
00572     for (KinematicJoint::component_iterator it = j->components.begin(); it != j->components.end(); ++it) {
00573       (*it)->getOwnBB3D(worldT * j->getFullT(), boc);
00574       ccentroid = boc.getCenter();
00575       cw = boc.getWidth();
00576       ch = boc.getHeight();
00577       cl = boc.getLength()/2;
00578       cq = fmat::Quaternion::fromMatrix(boc.getOrientation());
00579       graphics->add(new GraphicsData::BoundingBoxElement("component", cq, ccentroid, cl, cw, ch));
00580     }
00581   }
00582   j = j->nextJoint();
00583       }
00584     // Previous method: for now, just plot the location of the Gripper
00585     /* KinematicJoint* j = joints[N-1]; */
00586     
00587     /* while (j->nextJoint() != NULL) { */
00588     /*     j = j->nextJoint(); */
00589     /* } */
00590     
00591     /* fmat::Column<3> pos = j->getWorldPosition(); */
00592     
00593     /* graphics->add(new GraphicsData::CircleElement(DualCoding::GraphicsData::xyPair(pos[0],pos[1]), 5, true, theColor)); */
00594     
00595     /*// get bounding box of every link
00596       std::vector<std::vector<std::pair<float,float> > > boxes;
00597       getBoxes(boxes, *joints[0]);*/
00598     
00599     /*// add to element
00600       for (size_t b = 0; b < boxes.size(); b++) {
00601       graphics->add(new GraphicsData::PolygonElement(boxes[b], true, theColor));
00602       }*/
00603   }
00604 }
00605 template<size_t N>
00606 void ShapeSpacePlanner3DR<N>::getBoxes(std::vector<std::vector<std::pair<float,float> > >& boxes, const KinematicJoint& joint) {
00607   // we don't have to go through all branches, because we already cloned the branch
00608   if (joint.nextJoint() != NULL)
00609     getBoxes(boxes, *joint.nextJoint());
00610   
00611   // get the joint's BB (in obstacle format)
00612   std::vector<std::pair<float,float> > points(BoxObstacle::NUM_CORNERS);
00613   BoxObstacle bo;
00614   joint.getOwnBB3D(worldT * joint.getFullT(), bo);
00615   
00616   if (bo.getExtents() != fmat::Column<3>()) {
00617     // set points
00618     for (int p = 0; p < BoxObstacle::NUM_CORNERS; p++) {
00619       fmat::Column<3> corner = bo.getCorner(static_cast<BoxObstacle::CornerOrder>(p));
00620       points[p] = std::pair<float,float>(corner[0], corner[1]);
00621     }
00622     boxes.push_back(points);
00623   }
00624   
00625   // do the same for each link
00626   for (KinematicJoint::component_iterator it = joint.components.begin(); it != joint.components.end(); ++it) {
00627     // set points
00628     (*it)->getOwnBB3D(worldT * joint.getFullT(), bo);
00629     for (int p = 0; p < BoxObstacle::NUM_CORNERS; p++) {
00630       fmat::Column<3> corner = bo.getCorner(static_cast<BoxObstacle::CornerOrder>(p));
00631       points[p] = std::pair<float,float>(corner[0], corner[1]);
00632     }
00633     boxes.push_back(points);
00634   }
00635 }
00636 
00637 #endif
00638 
00639 #endif // TGT_HAS_ARMS

Tekkotsu v5.1CVS
Generated Sat May 4 06:33:01 2013 by Doxygen 1.6.3