Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Kinematics.cc

Go to the documentation of this file.
00001 #include "Kinematics.h"
00002 #include "Shared/Config.h"
00003 #include "Shared/WorldState.h"
00004 #include "Events/VisionObjectEvent.h"
00005 #include "Shared/string_util.h"
00006 #include <sstream>
00007 #include <iostream>
00008 #include <limits>
00009 #include <cmath>
00010 
00011 #ifdef PLATFORM_APERIOS
00012 //! this is normally defined in <math.h>, but the OPEN-R cross-compiler isn't configured right
00013 template<typename T> static inline int signbit(T x) { return x<0; }
00014 #endif
00015 
00016 using namespace std;
00017 
00018 Kinematics * kine = NULL;
00019 Kinematics::InterestPointMap Kinematics::ips;
00020 bool Kinematics::staticsInited=false;
00021 
00022 void
00023 Kinematics::init() {
00024   checkStatics();
00025   for(unsigned int i=0; i<NumReferenceFrames; ++i)
00026     jointMaps[i]=NULL;
00027   if(!root.loadFile(config->makePath(config->motion.kinematics).c_str())) {
00028     std::cerr << "Could not load " << config->motion.makePath(config->motion.kinematics) << ", forward and inverse kinematics unavailable." << std::endl;
00029     return;
00030   }
00031   root.buildChildMap(jointMaps,0,NumReferenceFrames);
00032 }
00033 
00034 void Kinematics::initStatics() {
00035   if(!staticsInited) {
00036     staticsInited=true;
00037   }
00038 }
00039 
00040 Kinematics::~Kinematics() {
00041 }
00042 
00043 fmat::Transform
00044 Kinematics::baseToLocal(const PlaneEquation& plane) {
00045   std::cout << "plane " << plane.getDirection() << ' ' << plane.getDisplacement() << std::endl;
00046   fmat::Column<3> p = plane.getDirection() / plane.getDirection().norm();
00047   float s = hypotf(p[0],p[1]); // |cross(p,[0 0 -1])| = sin(an)
00048   if(std::abs(s)<std::numeric_limits<float>::epsilon()*100) 
00049     return fmat::Transform::IDENTITY;
00050   
00051   // cross(p,[0 0 -1]) : 
00052   float x = -p[1]/s;
00053   float y = p[0]/s;
00054   // float z=0
00055   
00056   float d = -plane.getDisplacement();
00057   
00058   float c = -p[2]; // dot(p,[0 0 -1]) = cos(an) = p[2]
00059   float t = 1 - c;
00060   //std::cout << "axis " << x << ' ' << y << " angle " << std::asin(s) << ' ' << std::acos(c) << std::endl;
00061   float v[fmat::Transform::CAP] = { t*x*x + c, t*x*y, -y*s, t*x*y, t*y*y + c, x*s, y*s, -x*s, c, p[0]*d, p[1]*d, p[2]*d };
00062   //std::cout << fmat::Transform(v) << std::endl;
00063   return fmat::Transform(v);
00064 }
00065 
00066 void 
00067 Kinematics::getInterestPoint(const std::string& name, unsigned int& link, fmat::Column<3>& ip, bool convertToJoint/*=false*/) {
00068   link=-1U;
00069   ip=fmat::Column<3>();
00070   for(unsigned int i=0; i<NumReferenceFrames; ++i) {
00071     if(strcmp(outputNames[i],name.c_str())==0) {
00072       link = i;
00073       ip=pack(0,0,0);
00074     }
00075   }
00076   if(convertToJoint && NumOutputs<=link && link<NumReferenceFrames) {
00077     KinematicJoint * kj = jointMaps[link];
00078     while(kj!=NULL) {
00079       if(kj->outputOffset < NumOutputs) {
00080         ip = jointMaps[link]->getT(*kj) * ip;
00081         link = kj->outputOffset;
00082         return;
00083       }
00084     }
00085   }
00086 }
00087 
00088 fmat::Column<3>
00089 Kinematics::getInterestPoint(unsigned int link, const std::string& name) {
00090   vector<string> ipNames = string_util::tokenize(name,",");
00091   fmat::Column<3> ans = pack(0,0,0);
00092   unsigned int cnt=0;
00093   for(vector<string>::const_iterator it=ipNames.begin(); it!=ipNames.end(); ++it) {
00094     string srcName = string_util::trim(*it);
00095     if(srcName.size()==0)
00096       continue;
00097     unsigned int srcLink=-1U;
00098     fmat::Column<3> srcPos;
00099     getInterestPoint(srcName,srcLink,srcPos);
00100     if(srcLink==-1U)
00101       throw std::runtime_error(std::string("Kinematics::getLinkInterestPoint: interest point unknown ").append(name));
00102     if(link!=srcLink)
00103       srcPos = linkToLink(srcLink,link)*srcPos;
00104     ans+=srcPos;
00105     ++cnt;
00106   }
00107   if(cnt==0)
00108     throw std::runtime_error(std::string("Kinematics::getLinkInterestPoint called with empty string"));
00109   return ans/cnt;
00110 }
00111 
00112 
00113 #if defined(TGT_HAS_LEGS) && !defined(TGT_IS_MANTIS) 
00114 void
00115 Kinematics::calcLegHeights(const fmat::Column<3>& down, float heights[NumLegs]) {
00116   update();
00117   //initialize to the height of the ball of the foot
00118   for(unsigned int i=0; i<NumLegs; i++) {
00119     if(jointMaps[FootFrameOffset+i]==NULL) {
00120       heights[i]=std::numeric_limits<typeof(heights[0])>::max();
00121     } else {
00122       fmat::Column<3> ip_b=jointMaps[FootFrameOffset+i]->getWorldPosition();
00123       float h = -fmat::dotProduct(ip_b,down);
00124       h-=BallOfFootRadius; //add the ball's radius
00125       heights[i]=h;
00126     }
00127   }
00128   //see if any interest points are lower
00129   for(InterestPointMap::const_iterator it=ips.begin(); it!=ips.end(); ++it) {
00130     unsigned int leg;
00131     if(jointMaps[it->second.output]==NULL)
00132       continue;
00133     else if(it->second.output>=LegOffset || it->second.output<LegOffset+NumLegJoints)
00134       leg = (it->second.output - LegOffset) / JointsPerLeg;
00135     else if(it->second.output>=FootFrameOffset || it->second.output<FootFrameOffset+NumLegs)
00136       leg = (it->second.output - FootFrameOffset);
00137     else
00138       continue;
00139     fmat::Column<3> ip_b=jointMaps[it->second.output]->getFullT() * it->second.p;
00140     float h = -fmat::dotProduct(ip_b,down);
00141     if(h<heights[leg])
00142       heights[leg]=h;
00143   }
00144 }
00145 
00146 LegOrder_t
00147 Kinematics::findUnusedLeg(const fmat::Column<3>& down) {
00148   float heights[NumLegs];
00149   calcLegHeights(down,heights);
00150   //Find the highest foot
00151   unsigned int highleg=0;
00152   for(unsigned int i=1; i<NumLegs; i++)
00153     if(heights[i]>heights[highleg])
00154       highleg=i;
00155   //cout << "High: " << highleg << endl;
00156   return static_cast<LegOrder_t>(highleg);
00157 }
00158 
00159 PlaneEquation Kinematics::calculateGroundPlane() {
00160 #ifdef TGT_HAS_ACCELEROMETERS
00161   fmat::Column<3> down=fmat::pack(state->sensors[BAccelOffset],-state->sensors[LAccelOffset],state->sensors[DAccelOffset]);
00162   if(down.sumSq()<0.01)
00163     down=fmat::pack(0,0,-1); //default to a down vector if sensors don't give a significant indication of gravity
00164   return calculateGroundPlane(down);
00165 #else
00166   return calculateGroundPlane(fmat::pack(0,0,-1));
00167 #endif
00168 }
00169 
00170 // TODO comment out name tracking (and this following #include) once we're sure it's working
00171 #include "PostureEngine.h"
00172 PlaneEquation
00173 Kinematics::calculateGroundPlane(const fmat::Column<3>& down) {
00174   update();
00175   fmat::Matrix<3,3> lowip; //3 points define a plane
00176   float heights[3];
00177   unsigned int legs[3];
00178   std::string names[3];
00179   //initialize to max float
00180   for(unsigned int i=0; i<3; i++) {
00181     heights[i]=std::numeric_limits<typeof(heights[0])>::max();;
00182     legs[i]=-1U;
00183   }
00184   //Check the balls of the foot
00185   for(unsigned int i=0; i<NumLegs; i++) {
00186     if(jointMaps[FootFrameOffset+i]==NULL)
00187       continue;
00188     fmat::Column<3> ip_b=jointMaps[FootFrameOffset+i]->getWorldPosition();
00189     float h = -fmat::dotProduct(ip_b,down);
00190     h-=BallOfFootRadius; //add the ball's radius
00191     if(h<heights[0]) {
00192       if(h<heights[1]) {
00193         heights[0]=heights[1];
00194         lowip.column(0)=lowip.column(1);
00195         legs[0]=legs[1];
00196         names[0]=names[1];
00197         if(h<heights[2]) {
00198           heights[1]=heights[2];
00199           lowip.column(1)=lowip.column(2);
00200           legs[1]=legs[2];
00201           names[1]=names[2];
00202           
00203           heights[2]=h;
00204           lowip.column(2)=ip_b;
00205           legs[2]=i;
00206           names[2]="paw"; names[2]+=(char)('0'+i);
00207         } else {
00208           heights[1]=h;
00209           lowip.column(1)=ip_b;
00210           legs[1]=i;
00211           names[1]="paw"; names[1]+=(char)('0'+i);
00212         }
00213       } else {
00214         heights[0]=h;
00215         lowip.column(0)=ip_b;
00216         legs[0]=i;
00217         names[0]="paw"; names[0]+=(char)('0'+i);
00218       }
00219     }
00220   }
00221   //cout << "Ground plane initial: " << names[0] <<" ("<<heights[0]<<") " << names[1] << " ("<<heights[1]<<") " << names[2] << " ("<<heights[2]<<")"<< endl;
00222   
00223   //now check interest points
00224   for(InterestPointMap::const_iterator it=ips.begin(); it!=ips.end(); ++it) {
00225 #ifdef TGT_IS_AIBO
00226     if(it->first.substr(0,3)=="Toe")
00227       continue;
00228 #endif
00229     if(jointMaps[it->second.output]==NULL)
00230       continue;
00231     fmat::Column<3> ip_b=jointMaps[it->second.output]->getFullT() * it->second.p;
00232     float h = -fmat::dotProduct(ip_b,down);
00233     if(h<heights[0]) {
00234       unsigned int leg;
00235       if(it->second.output>=LegOffset && it->second.output<LegOffset+NumLegJoints)
00236         leg = (it->second.output - LegOffset) / JointsPerLeg;
00237       else if(it->second.output>=FootFrameOffset && it->second.output<FootFrameOffset+NumLegs)
00238         leg = (it->second.output - FootFrameOffset);
00239       else
00240         leg=-1U;
00241       
00242       if(h<heights[1]) {
00243         if(h<heights[2]) {
00244           if(leg==-1U || (legs[1]!=leg && legs[2]!=leg)) {
00245             heights[0]=heights[1];
00246             lowip.column(0)=lowip.column(1);
00247             legs[0]=legs[1];
00248             names[0]=names[1];
00249           }
00250           if(leg==-1U || legs[2]!=leg) {
00251             heights[1]=heights[2];
00252             lowip.column(1)=lowip.column(2);
00253             if(legs[2]!=leg)
00254               legs[1]=legs[2];
00255             names[1]=names[2];
00256           }
00257           
00258           heights[2]=h;
00259           lowip.column(2)=ip_b;
00260           legs[2]=leg;
00261           names[2]=(*it).first;
00262         } else {
00263           if(leg!=-1U && legs[2]==leg)
00264             continue;
00265           if(leg==-1U || legs[1]!=leg) {
00266             heights[0]=heights[1];
00267             lowip.column(0)=lowip.column(1);
00268             legs[0]=legs[1];
00269             names[0]=names[1];
00270           }
00271           heights[1]=h;
00272           lowip.column(1)=ip_b;
00273           legs[1]=leg;
00274           names[1]=(*it).first;
00275         }
00276       } else {
00277         if(leg!=-1U && (legs[1]==leg || legs[2]==leg))
00278           continue;
00279         heights[0]=h;
00280         lowip.column(0)=ip_b;
00281         legs[0]=leg;
00282         names[0]=(*it).first;
00283       }
00284     }
00285   }
00286   
00287   //Fit a plane to the remaining 3 feet
00288   fmat::Column<3> ones(1.f);
00289   fmat::Column<3> dir;
00290   try {
00291     dir = invert(lowip.transpose())*ones;
00292   } catch(...) {
00293     std::cout << "Exception during ground plane processing, saving current posture..." << std::flush;
00294     if(PostureEngine * tpose=dynamic_cast<PostureEngine*>(this)) {
00295       tpose->setSaveFormat(true,state);
00296       tpose->saveFile("/error.pos");
00297     } else {
00298       PostureEngine pose;
00299       pose.takeSnapshot();
00300       pose.setWeights(1);
00301       pose.setSaveFormat(true,state);
00302       pose.saveFile("/error.pos");
00303     }
00304     std::cout << "Wrote current sensor info \"error.pos\" on memstick" << std::endl;
00305     cout << "Ground plane was using " << names[0] <<" ("<<heights[0]<<") " << names[1] << " ("<<heights[1]<<") " << names[2] << " ("<<heights[2]<<")"<< endl;
00306     cout << lowip;
00307     throw;
00308   }
00309   // todo this doesn't handle plane through the origin, what if plane is z=0 (e.g. [0,0,1,0])
00310   return PlaneEquation(dir, 1);
00311 }
00312 
00313 #elif defined(TGT_IS_MANTIS)
00314 // If the model is Mantis
00315 
00316 PlaneEquation Kinematics::calculateGroundPlane() {
00317 #ifdef TGT_HAS_ACCELEROMETERS
00318         fmat::Column<3> down=fmat::pack(state->sensors[BAccelOffset],-state->sensors[LAccelOffset],state->sensors[DAccelOffset]);
00319         if(down.sumSq()<0.01)
00320                 down=fmat::pack(0,0,-1); //default to a down vector if sensors don't give a significant indication of gravity
00321         return calculateGroundPlane(down);
00322 #else
00323         return calculateGroundPlane(fmat::pack(0,0,-1));
00324 #endif
00325 }
00326 
00327 #include "PostureEngine.h"
00328 #include <utility>
00329 PlaneEquation
00330 Kinematics::calculateGroundPlane(const fmat::Column<3>& down) {
00331         update();
00332         fmat::Matrix<3,3> lowip; //3 points define a plane
00333         float heights[3];float arr[6];
00334         unsigned int idx[NumLegs];
00335         for (unsigned int i=0; i<NumLegs; i++) {  idx[i] = i; }
00336         unsigned int legs[3];
00337         std::string names[3];
00338         for(unsigned int i=0; i<NumLegs; i++) {
00339                 if(jointMaps[FootFrameOffset+i]==NULL)
00340                         continue;
00341                 fmat::Column<3> ip_b=jointMaps[FootFrameOffset+i]->getWorldPosition();
00342                 float h = -fmat::dotProduct(ip_b,down);
00343                 h-=BallOfFootRadius; //add the ball's radius
00344                 arr[i]=h;
00345                 //cout<<"arr["<<i<<"] = "<<arr[i]<<endl<<ip_b << endl;
00346         }
00347         for(unsigned int i=0; i<NumLegs; i++) {
00348                  for(unsigned int j=i+1; j<NumLegs; j++) {
00349                         if (arr[idx[i]] > arr[idx[j]])
00350                         {
00351                            std::swap(idx[i], idx[j]);
00352                         }
00353                }
00354         }
00355         for(unsigned int i=0; i<3; i++) {
00356                 legs[i] = idx[i];
00357                 heights[i] = arr[idx[i]];
00358                 lowip.column(i) = jointMaps[FootFrameOffset+idx[i]]->getWorldPosition();
00359                 names[i]="paw"; names[i]+=(char)('0'+idx[i]);
00360                 //cout<<"heights["<<i<<"] = "<<heights[i]<< endl << lowip.column(i);
00361         }
00362 
00363 
00364         //cout << "Ground plane initial: " << names[0] <<" ("<<heights[0]<<") " << names[1] << " ("<<heights[1]<<") " << names[2] << " ("<<heights[2]<<")"<< endl;
00365 
00366 //now check interest points
00367         for(InterestPointMap::const_iterator it=ips.begin(); it!=ips.end(); ++it) {
00368                 if(jointMaps[it->second.output]==NULL)
00369                         continue;
00370                 fmat::Column<3> ip_b=jointMaps[it->second.output]->getFullT() * it->second.p;
00371                 float h = -fmat::dotProduct(ip_b,down);
00372                 if(h<heights[0]) {
00373                         unsigned int leg;
00374                         if(it->second.output>=LegOffset && it->second.output<LegOffset+NumFrLegJoints)
00375                                 leg = (it->second.output - LegOffset) / JointsPerFrLeg;
00376                         else if(it->second.output>=LMdLegOffset && it->second.output<LMdLegOffset+NumPosLegJoints)
00377                                 leg = (it->second.output - LMdLegOffset) / JointsPerPosLeg;
00378                         else if(it->second.output>=FootFrameOffset && it->second.output<FootFrameOffset+NumLegs)
00379                                 leg = (it->second.output - FootFrameOffset);
00380                         else
00381                                 leg=-1U;
00382 
00383                         if(h<heights[1]) {
00384                                 if(h<heights[2]) {
00385                                         if(leg==-1U || (legs[1]!=leg && legs[2]!=leg)) {
00386                                                 heights[0]=heights[1];
00387                                                 lowip.column(0)=lowip.column(1);
00388                                                 legs[0]=legs[1];
00389                                                 names[0]=names[1];
00390                                         }
00391                                         if(leg==-1U || legs[2]!=leg) {
00392                                                 heights[1]=heights[2];
00393                                                 lowip.column(1)=lowip.column(2);
00394                                                 if(legs[2]!=leg)
00395                                                         legs[1]=legs[2];
00396                                                 names[1]=names[2];
00397                                         }
00398 
00399                                         heights[2]=h;
00400                                         lowip.column(2)=ip_b;
00401                                         legs[2]=leg;
00402                                         names[2]=(*it).first;
00403                                 } else {
00404                                         if(leg!=-1U && legs[2]==leg)
00405                                                 continue;
00406                                         if(leg==-1U || legs[1]!=leg) {
00407                                                 heights[0]=heights[1];
00408                                                 lowip.column(0)=lowip.column(1);
00409                                                 legs[0]=legs[1];
00410                                                 names[0]=names[1];
00411                                         }
00412                                         heights[1]=h;
00413                                         lowip.column(1)=ip_b;
00414                                         legs[1]=leg;
00415                                         names[1]=(*it).first;
00416                                 }
00417                         } else {
00418                                 if(leg!=-1U && (legs[1]==leg || legs[2]==leg))
00419                                         continue;
00420                                 heights[0]=h;
00421                                 lowip.column(0)=ip_b;
00422                                 legs[0]=leg;
00423                                 names[0]=(*it).first;
00424                         }
00425                 }
00426         }
00427 
00428         //Fit a plane to the remaining 3 feet
00429         fmat::Column<3> ones(1.f);
00430         fmat::Column<3> dir;
00431         try {
00432                 dir = invert(lowip.transpose())*ones;
00433         } catch(...) {
00434                 std::cout << "Exception during ground plane processing, saving current posture..." << std::flush;
00435                 if(PostureEngine * tpose=dynamic_cast<PostureEngine*>(this)) {
00436                         tpose->setSaveFormat(true,state);
00437                         tpose->saveFile("/error.pos");
00438                 } else {
00439                         PostureEngine pose;
00440                         pose.takeSnapshot();
00441                         pose.setWeights(1);
00442                         pose.setSaveFormat(true,state);
00443                         pose.saveFile("/error.pos");
00444                 }
00445                 std::cout << "Wrote current sensor info \"error.pos\" on memstick" << std::endl;
00446                 cout << "Ground plane was using " << names[0] <<" ("<<heights[0]<<") " << names[1] << " ("<<heights[1]<<") " << names[2] << " ("<<heights[2]<<")"<< endl;
00447                 cout << lowip;
00448                 throw;
00449         }
00450         // todo this doesn't handle plane through the origin, what if plane is z=0 (e.g. [0,0,1,0])
00451         return PlaneEquation(dir, 1);
00452 }
00453 
00454 #else // NO LEGS -- constant ground plane
00455 
00456 PlaneEquation Kinematics::calculateGroundPlane() {
00457   return PlaneEquation(0,0,1,0);
00458 }
00459 
00460 PlaneEquation
00461 Kinematics::calculateGroundPlane(const fmat::Column<3>& down) {
00462   return PlaneEquation(-down, 0); // flat x-y plane through the origin with z pointing up
00463 }
00464 
00465 #endif
00466 
00467 fmat::Column<4> 
00468 Kinematics::projectToPlane(
00469       unsigned int j, const fmat::Column<3>& r_j,
00470       unsigned int b, const PlaneEquation& p_b,
00471       unsigned int f,
00472       float objCentroidHeight)
00473 {
00474   update();
00475   if((j!=b && (jointMaps[j]==NULL || jointMaps[b]==NULL)) || (f!=b && (jointMaps[f]==NULL || jointMaps[b]==NULL)) )
00476     return fmat::Column<4>(0.f);
00477   
00478   /*! Mathematical implementation:
00479    *  
00480    *  We'll convert the ray to the plane's reference frame, solve there.
00481    *  We find a point on the ray (ro_b) and the direction of the ray (rv_b).
00482    *  rv_b does not need to be normalized because we're going to find
00483    *  a scaling factor for it, and that factor accounts for current magnitude.
00484    *
00485    *  Proof, p=plane normal vector, d=plane displacement, r = ray direction, o = ray offset, x = [x y z] coordinates, t = scaling factor */
00486    
00487   /* Non-latex/doxygen version for easier reading in source (UTF-8):
00488    p⃑ · x⃑ = d    (definition of plane)
00489    x⃑ = r⃑(t) + o⃑    (definition of ray through point)
00490    p⃑ · ( r⃑(t)  + o⃑ ) = d
00491    p⃑ · r⃑(t) + p⃑ · o⃑ = d
00492    t ( p⃑ · r⃑ ) = d - p⃑ · o⃑
00493    t = (d - p⃑ · o⃑) / (p⃑ · r⃑)
00494    t = dist / align
00495    substitute back to find intersection: x⃑ = r⃑(t) + o⃑
00496    */
00497    
00498    /*! @f{eqnarray*} 
00499    \vec p \cdot\vec x &=& d \qquad{\rm(Definition\ of\ plane)}\\
00500    \vec x &=& t \vec r + \vec o \qquad{\rm(Definition\ of\ ray\ through\ point)}\\
00501    \vec p \cdot ( t \vec r  + \vec o ) &=& d \\
00502    \vec p \cdot t \vec r + \vec p \cdot \vec o &=& d \\
00503    t ( \vec p \cdot \vec r ) &=& d - \vec p \cdot \vec o \\
00504    t &=& \frac{d - \vec p \cdot \vec o}{\vec p \cdot \vec r} = \frac{dist}{align} \\
00505    && {\rm (substitute\ back\ to\ find\ } \vec x = t \vec r + \vec o{\rm )}
00506    @f}
00507    */
00508   fmat::Column<3> ro_b, rv_b;
00509   if(j==b)
00510     rv_b=r_j;
00511   else {
00512     fmat::Transform tr = jointMaps[j]->getT(*jointMaps[b]);
00513     ro_b = tr.translation();
00514     rv_b = tr.rotation() * r_j;
00515   }
00516   //std::cout << "ro_b: " << ro_b << "  rv_b: " << rv_b << std::endl;
00517   
00518   /*! Find distance from the ray offset (ro_b) and the closest point on the plane. */
00519   float dist = p_b.getDisplacement() - fmat::dotProduct(p_b.getDirection(),ro_b);
00520   /*! Object height is applied along the plane normal toward the ray origin
00521    *  (we assume the ray source is "above" ground) */
00522   dist += signbit(dist) ? objCentroidHeight : -objCentroidHeight;
00523   /*! Find scaling factor by projecting ray vector (rv_b) onto plane normal. */
00524   float align = fmat::dotProduct(p_b.getDirection(),rv_b);
00525   //std::cout << "dist " << dist << "  align " << align << std::endl;
00526   
00527   /*! Intersection point will be rv_b*dist/align + ro_b, but need to watch out
00528    *  for case where align==0 (rv_b and plane are parallel, no intersection) */
00529   fmat::Column<4> hit;
00530   if(std::abs(align)>numeric_limits<float>::epsilon())
00531     hit = fmat::pack(rv_b*(dist/align)+ro_b,1.f);
00532   else if(align!=0 && dist!=0 && signbit(align)!=signbit(dist))
00533     hit = fmat::pack(-rv_b,std::abs(align));
00534   else
00535     hit = fmat::pack(rv_b,std::abs(align));
00536   //std::cout << "hit " << hit << std::endl;
00537   
00538   return (f==b) ? hit : jointMaps[b]->getT(*jointMaps[f]) * hit;
00539 }
00540 
00541 fmat::Column<4>
00542 Kinematics::projectToGround(const VisionObjectEvent& visObj, const PlaneEquation& gndPlane, float objCentroidHeight) {
00543 #ifndef TGT_HAS_CAMERA
00544   return fmat::Column<4>();
00545 #else
00546   fmat::Column<3> imgRay_c;
00547   config->vision.computeRay(visObj.getCenterX(),visObj.getCenterY(), imgRay_c[0],imgRay_c[1],imgRay_c[2]);
00548   return projectToPlane(CameraFrameOffset, imgRay_c, BaseFrameOffset, calculateGroundPlane(), BaseFrameOffset, objCentroidHeight);
00549 #endif
00550 }
00551 
00552 
00553 void
00554 Kinematics::update() const {
00555   if(lastUpdateTime == state->lastSensorUpdateTime)
00556      return;
00557   for(unsigned int j=0; j<NumOutputs; j++) {
00558     if(jointMaps[j]!=NULL)
00559       jointMaps[j]->setQ(state->outputs[j]);
00560   }
00561   lastUpdateTime = state->lastSensorUpdateTime;
00562 }
00563 
00564 
00565 /*! @file
00566  * @brief 
00567  * @author ejt (Creator)
00568  */
00569 

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