Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ShapeSpacePlanner3DR.h

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

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:51 2016 by Doxygen 1.6.3