Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00018 #include "LinkTraverse.h"
00019 #include "Link.h"
00020 #include <hrpUtil/Eigen3d.h>
00021
00022 using namespace std;
00023 using namespace hrp;
00024
00025
00026 LinkTraverse::LinkTraverse()
00027 {
00028
00029 }
00030
00031
00032 LinkTraverse::LinkTraverse(int size)
00033 : links(size)
00034 {
00035 links.clear();
00036 }
00037
00038
00039 LinkTraverse::LinkTraverse(Link* root, bool doUpward, bool doDownward)
00040 {
00041 find(root, doUpward, doDownward);
00042 }
00043
00044
00045 LinkTraverse::~LinkTraverse()
00046 {
00047
00048 }
00049
00050
00051 void LinkTraverse::find(Link* root, bool doUpward, bool doDownward)
00052 {
00053 numUpwardConnections = 0;
00054 links.clear();
00055 traverse(root, doUpward, doDownward, false, 0);
00056 }
00057
00058
00059 void LinkTraverse::traverse(Link* link, bool doUpward, bool doDownward, bool isUpward, Link* prev)
00060 {
00061 links.push_back(link);
00062 if(isUpward){
00063 ++numUpwardConnections;
00064 }
00065
00066 if(doUpward && link->parent){
00067 traverse(link->parent, doUpward, true, true, link);
00068 }
00069 if(doDownward){
00070 for(Link* child = link->child; child; child = child->sibling){
00071 if(child != prev){
00072 traverse(child, false, true, false, 0);
00073 }
00074 }
00075 }
00076 }
00077
00078
00079 void LinkTraverse::calcForwardKinematics(bool calcVelocity, bool calcAcceleration) const
00080 {
00081 Vector3 arm;
00082 int i;
00083 for(i=1; i <= numUpwardConnections; ++i){
00084
00085 Link* link = links[i];
00086 Link* child = links[i-1];
00087
00088 switch(child->jointType){
00089
00090 case Link::ROTATIONAL_JOINT:
00091 link->R.noalias() = child->R * rodrigues(child->a, child->q).transpose();
00092 arm.noalias() = link->R * child->b;
00093 link->p = child->p - arm;
00094
00095 if(calcVelocity){
00096 child->sw.noalias() = link->R * child->a;
00097 link->w = child->w - child->dq * child->sw;
00098 link->v = child->v - link->w.cross(arm);
00099
00100 if(calcAcceleration){
00101 link->dw = child->dw - child->dq * child->w.cross(child->sw) - (child->ddq * child->sw);
00102 link->dv = child->dv - child->w.cross(child->w.cross(arm)) - child->dw.cross(arm);
00103 }
00104 }
00105 break;
00106
00107 case Link::SLIDE_JOINT:
00108 link->R = child->R;
00109 arm.noalias() = link->R * (child->b + child->q * child->d);
00110 link->p = child->p - arm;
00111
00112 if(calcVelocity){
00113 child->sv.noalias() = link->R * child->d;
00114 link->w = child->w;
00115 link->v = child->v - child->dq * child->sv;
00116
00117 if(calcAcceleration){
00118 link->dw = child->dw;
00119 link->dv = child->dv - child->w.cross(child->w.cross(arm)) - child->dw.cross(arm)
00120 - 2.0 * child->dq * child->w.cross(child->sv) - child->ddq * child->sv;
00121 }
00122 }
00123 break;
00124
00125 case Link::FIXED_JOINT:
00126 default:
00127 link->R = child->R;
00128 link->p = child->p - (link->R * child->b);
00129
00130 if(calcVelocity){
00131 link->w = child->w;
00132 link->v = child->v;
00133
00134 if(calcAcceleration){
00135 link->dw = child->dw;
00136 link->dv = child->dv;
00137 }
00138 }
00139 break;
00140 }
00141 }
00142
00143 int n = links.size();
00144 for( ; i < n; ++i){
00145
00146 Link* link = links[i];
00147 Link* parent = link->parent;
00148
00149 switch(link->jointType){
00150
00151 case Link::ROTATIONAL_JOINT:
00152 link->R.noalias() = parent->R * rodrigues(link->a, link->q);
00153 arm.noalias() = parent->R * link->b;
00154 link->p = parent->p + arm;
00155
00156 if(calcVelocity){
00157 link->sw.noalias() = parent->R * link->a;
00158 link->w = parent->w + link->sw * link->dq;
00159 link->v = parent->v + parent->w.cross(arm);
00160
00161 if(calcAcceleration){
00162 link->dw = parent->dw + link->dq * parent->w.cross(link->sw) + (link->ddq * link->sw);
00163 link->dv = parent->dv + parent->w.cross(parent->w.cross(arm)) + parent->dw.cross(arm);
00164 }
00165 }
00166 break;
00167
00168 case Link::SLIDE_JOINT:
00169 link->R = parent->R;
00170 arm.noalias() = parent->R * (link->b + link->q * link->d);
00171 link->p = parent->p + arm;
00172
00173 if(calcVelocity){
00174 link->sv.noalias() = parent->R * link->d;
00175 link->w = parent->w;
00176 link->v = parent->v + link->sv * link->dq;
00177
00178 if(calcAcceleration){
00179 link->dw = parent->dw;
00180 link->dv = parent->dv + parent->w.cross(parent->w.cross(arm)) + parent->dw.cross(arm)
00181 + 2.0 * link->dq * parent->w.cross(link->sv) + link->ddq * link->sv;
00182 }
00183 }
00184 break;
00185
00186 case Link::FIXED_JOINT:
00187 default:
00188 link->R = parent->R;
00189 link->p = parent->R * link->b + parent->p;
00190
00191 if(calcVelocity){
00192 link->w = parent->w;
00193 link->v = parent->v;
00194
00195 if(calcAcceleration){
00196 link->dw = parent->dw;
00197 link->dv = parent->dv;
00198 }
00199 }
00200 break;
00201 }
00202 }
00203 }
00204
00205
00206 double LinkTraverse::calcTotalMass()
00207 {
00208 totalMass_ = 0.0;
00209
00210 for(int i = 0; i < numLinks(); ++i) {
00211 totalMass_ += links[i]->m;
00212 }
00213
00214 return totalMass_;
00215 }
00216
00217
00218 std::ostream& operator<<(std::ostream& os, LinkTraverse& traverse)
00219 {
00220 int n = traverse.numLinks();
00221 for(int i=0; i < n; ++i){
00222 Link* link = traverse[i];
00223 os << link->name;
00224 if(i != n){
00225 os << (traverse.isDownward(i) ? " => " : " <= ");
00226 }
00227 }
00228 os << std::endl;
00229
00230 return os;
00231 }