Example #1
0
void JointPath::calcJacobian(Eigen::MatrixXd& out_J) const
{
    const int n = joints.size();
    out_J.resize(6, n);
	
    if(n > 0){

        //! \todo compare the efficiency for the following codes
        if(false){
            setJacobian<0x3f, 0, 0>(*this, linkPath.endLink(), out_J);

        } else {
        
            Link* targetLink = linkPath.endLink();
		
            for(int i=0; i < n; ++i){
			
                Link* link = joints[i];
			
                switch(link->jointType()){
				
                case Link::ROTATIONAL_JOINT:
                {
                    Vector3 omega = link->R() * link->a();
                    const Vector3 arm = targetLink->p() - link->p();
                    if(!isJointDownward(i)){
                        omega = -omega;
                    }
                    out_J.col(i) << omega.cross(arm), omega;
                }
                break;
				
                case Link::SLIDE_JOINT:
                {
                    Vector3 dp = link->R() * link->d();
                    if(!isJointDownward(i)){
                        dp = -dp;
                    }
                    out_J.col(i) << dp, Vector3::Zero();
                }
                break;
				
                default:
                    out_J.col(i).setZero();
                }
            }
        }
    }
}
Example #2
0
/**
   @brief compute CoM Jacobian
   @param base link fixed to the environment
   @param J CoM Jacobian
   @note Link::wc must be computed by calcCM() before calling
*/
void calcCMJacobian(const BodyPtr& body, Link* base, Eigen::MatrixXd& J)
{
    // prepare subm, submwc

    const int nj = body->numJoints();
    vector<SubMass> subMasses(body->numLinks());
    Link* rootLink = body->rootLink();

    JointPath path;
    if(!base) {
        calcSubMass(rootLink, subMasses);
        J.resize(3, nj + 6);

    } else {
        path.setPath(rootLink, base);
        Link* skip = path.joint(0);
        SubMass& sub = subMasses[skip->index()];
        sub.m = rootLink->m();
        sub.mwc = rootLink->m() * rootLink->wc();

        for(Link* child = rootLink->child(); child; child = child->sibling()) {
            if(child != skip) {
                calcSubMass(child, subMasses);
                subMasses[skip->index()] += subMasses[child->index()];
            }
        }

        // assuming there is no branch between base and root
        for(int i=1; i < path.numJoints(); i++) {
            Link* joint = path.joint(i);
            const Link* parent = joint->parent();
            SubMass& sub = subMasses[joint->index()];
            sub.m = parent->m();
            sub.mwc = parent->m() * parent->wc();
            sub += subMasses[parent->index()];
        }

        J.resize(3, nj);
    }

    // compute Jacobian
    std::vector<int> sgn(nj, 1);
    for(int i=0; i < path.numJoints(); i++) {
        sgn[path.joint(i)->jointId()] = -1;
    }

    for(int i=0; i < nj; i++) {
        Link* joint = body->joint(i);
        if(joint->isRotationalJoint()) {
            const Vector3 omega = sgn[joint->jointId()] * joint->R() * joint->a();
            const SubMass& sub = subMasses[joint->index()];
            const Vector3 arm = (sub.mwc - sub.m * joint->p()) / body->mass();
            const Vector3 dp = omega.cross(arm);
            J.col(joint->jointId()) = dp;
        } else {
            std::cerr << "calcCMJacobian() : unsupported jointType("
                      << joint->jointType() << std::endl;
        }
    }

    if(!base) {
        const int c = nj;
        J.block(0, c, 3, 3).setIdentity();

        const Vector3 dp = subMasses[0].mwc / body->mass() - rootLink->p();

        J.block(0, c + 3, 3, 3) <<
                                0.0,  dp(2), -dp(1),
                                      -dp(2),    0.0,  dp(0),
                                      dp(1), -dp(0),    0.0;
    }
}
Example #3
0
static void nearCallback(void* data, dGeomID g1, dGeomID g2)
{
    if(dGeomIsSpace(g1) || dGeomIsSpace(g2)) { 
        dSpaceCollide2(g1, g2, data, &nearCallback);
        if(false) { // Currently just skip same body link pairs. 
            if(dGeomIsSpace(g1)){
                dSpaceCollide((dSpaceID)g1, data, &nearCallback);
            }
            if(dGeomIsSpace(g2)){
                dSpaceCollide((dSpaceID)g2, data, &nearCallback);
            }
        }
    } else {
        ODESimulatorItemImpl* impl = (ODESimulatorItemImpl*)data;
        static const int MaxNumContacts = 100;
        dContact contacts[MaxNumContacts];
        int numContacts = dCollide(g1, g2, MaxNumContacts, &contacts[0].geom, sizeof(dContact));
        
        if(numContacts > 0){
            dBodyID body1ID = dGeomGetBody(g1);
            dBodyID body2ID = dGeomGetBody(g2);
            Link* crawlerlink = 0;
            double sign = 1.0;
            if(!impl->crawlerLinks.empty()){
                CrawlerLinkMap::iterator p = impl->crawlerLinks.find(body1ID);
                if(p != impl->crawlerLinks.end()){
                    crawlerlink = p->second;
                }
                p = impl->crawlerLinks.find(body2ID);
                if(p != impl->crawlerLinks.end()){
                    crawlerlink = p->second;
                    sign = -1.0;
                }
            }
            for(int i=0; i < numContacts; ++i){
                dSurfaceParameters& surface = contacts[i].surface;
                if(!crawlerlink){
                    //surface.mode = dContactApprox1 | dContactBounce;
                    //surface.bounce = 0.0;
                    //surface.bounce_vel = 1.0;
                    surface.mode = dContactApprox1;
                    surface.mu = impl->friction;

                } else {
                    if(contacts[i].geom.depth > 0.001){
                        continue;
                    }
                    surface.mode = dContactFDir1 | dContactMotion1 | dContactMu2 | dContactApprox1_2;
                    const Vector3 axis = crawlerlink->R() * crawlerlink->a();
                    const Vector3 n(contacts[i].geom.normal);
                    Vector3 dir = axis.cross(n);
                    if(dir.norm() < 1.0e-5){
                        surface.mode = dContactApprox1;
                        surface.mu = impl->friction;
                    } else {
                        dir *= sign;
                        dir.normalize();
                        contacts[i].fdir1[0] = dir[0];
                        contacts[i].fdir1[1] = dir[1];
                        contacts[i].fdir1[2] = dir[2];
                        //dVector3& dpos = contacts[i].geom.pos;
                        //Vector3 pos(dpos[0], dpos[1], dpos[2]);
                        //Vector3 v = crawlerlink->v + crawlerlink->w.cross(pos-crawlerlink->p);
                        //surface.motion1 = dir.dot(v) + crawlerlink->u;
                        surface.motion1 = crawlerlink->u();
                        surface.mu = impl->friction;
                        surface.mu2 = 0.5;
                    }
                }
                dJointID jointID = dJointCreateContact(impl->worldID, impl->contactJointGroupID, &contacts[i]);
                dJointAttach(jointID, body1ID, body2ID);
            }
        }
    }
}
Example #4
0
void ODESimulatorItemImpl::collisionCallback(const CollisionPair& collisionPair)
{
    ODELink* link1 = geometryIdToLink[collisionPair.geometryId[0]];
    ODELink* link2 = geometryIdToLink[collisionPair.geometryId[1]];
    const vector<Collision>& collisions = collisionPair.collisions;

    dBodyID body1ID = link1->bodyID;
    dBodyID body2ID = link2->bodyID;
    Link* crawlerlink = 0;
    double sign = 1.0;
    if(!crawlerLinks.empty()){
        CrawlerLinkMap::iterator p = crawlerLinks.find(body1ID);
        if(p != crawlerLinks.end()){
            crawlerlink = p->second;
        }
        p = crawlerLinks.find(body2ID);
        if(p != crawlerLinks.end()){
            crawlerlink = p->second;
            sign = -1.0;
        }
    }

    int numContacts = collisions.size();
    for(int i=0; i < numContacts; ++i){
        dContact contact;
        contact.geom.pos[0] = collisions[i].point[0];
        contact.geom.pos[1] = collisions[i].point[1];
        contact.geom.pos[2] = collisions[i].point[2];
        contact.geom.normal[0] = -collisions[i].normal[0];
        contact.geom.normal[1] = -collisions[i].normal[1];
        contact.geom.normal[2] = -collisions[i].normal[2];
        contact.geom.depth = collisions[i].depth;

        dSurfaceParameters& surface = contact.surface;
        if(!crawlerlink){
            surface.mode = dContactApprox1;
            surface.mu = friction;
        } else {
            if(contact.geom.depth > 0.001){
                continue;
            }
            surface.mode = dContactFDir1 | dContactMotion1 | dContactMu2 | dContactApprox1_2;
            const Vector3 axis = crawlerlink->R() * crawlerlink->a();
            const Vector3 n(contact.geom.normal);
            Vector3 dir = axis.cross(n);
            if(dir.norm() < 1.0e-5){
                surface.mode = dContactApprox1;
                surface.mu = friction;
            } else {
                dir *= sign;
                dir.normalize();
                contact.fdir1[0] = dir[0];
                contact.fdir1[1] = dir[1];
                contact.fdir1[2] = dir[2];
                surface.motion1 = crawlerlink->u();
                surface.mu = friction;
                surface.mu2 = 0.5;
            }
        }
        dJointID jointID = dJointCreateContact(worldID, contactJointGroupID, &contact);
        dJointAttach(jointID, body1ID, body2ID);
    }
}
Example #5
0
void LinkTraverse::calcForwardKinematics(bool calcVelocity, bool calcAcceleration) const
{
    Vector3 arm;
    int i;
    for(i=1; i <= numUpwardConnections; ++i){

        Link* link = links[i];
        const Link* child = links[i-1];

        switch(child->jointType()){

        case Link::ROTATIONAL_JOINT:
            link->R().noalias() = child->R() * AngleAxisd(child->q(), child->a()).inverse();
            arm.noalias() = link->R() * child->b();
            link->p().noalias() = child->p() - arm;

            if(calcVelocity){
                const Vector3 sw(link->R() * child->a());
                link->w() = child->w() - child->dq() * sw;
                link->v() = child->v() - link->w().cross(arm);
                
                if(calcAcceleration){
                    link->dw() = child->dw() - child->dq() * child->w().cross(sw) - (child->ddq() * sw);
                    link->dv() = child->dv() - child->w().cross(child->w().cross(arm)) - child->dw().cross(arm);
                }
            }
            break;
            
        case Link::SLIDE_JOINT:
            link->R() = child->R();
            arm.noalias() = link->R() * (child->b() + child->q() * child->d());
            link->p().noalias() = child->p() - arm;

            if(calcVelocity){
                const Vector3 sv(link->R() * child->d());
                link->w() = child->w();
                link->v().noalias() = child->v() - child->dq() * sv;

                if(calcAcceleration){
                    link->dw() = child->dw();
                    link->dv().noalias() =
                        child->dv() - child->w().cross(child->w().cross(arm)) - child->dw().cross(arm)
                        - 2.0 * child->dq() * child->w().cross(sv) - child->ddq() * sv;
                }
            }
            break;
            
        case Link::FIXED_JOINT:
        default:
            arm.noalias() = link->R() * child->b();
            link->R() = child->R();
            link->p().noalias() = child->p() - arm;

            if(calcVelocity){
                
                link->w() = child->w();
                link->v() = child->v() - link->w().cross(arm);
				
                if(calcAcceleration){
                    link->dw() = child->dw();
                    link->dv() = child->dv() - child->w().cross(child->w().cross(arm)) - child->dw().cross(arm);;
                }
            }
            break;
        }
    }

    const int n = links.size();
    for( ; i < n; ++i){
        
        Link* link = links[i];
        const Link* parent = link->parent();

        switch(link->jointType()){
            
        case Link::ROTATIONAL_JOINT:
            link->R().noalias() = parent->R() * AngleAxisd(link->q(), link->a());
            arm.noalias() = parent->R() * link->b();
            link->p().noalias() = parent->p() + arm;

            if(calcVelocity){
                const Vector3 sw(parent->R() * link->a());
                link->w().noalias() = parent->w() + sw * link->dq();
                link->v().noalias() = parent->v() + parent->w().cross(arm);

                if(calcAcceleration){
                    link->dw().noalias() = parent->dw() + link->dq() * parent->w().cross(sw) + (link->ddq() * sw);
                    link->dv().noalias() = parent->dv() + parent->w().cross(parent->w().cross(arm)) + parent->dw().cross(arm);
                }
            }
            break;
            
        case Link::SLIDE_JOINT:
            link->R() = parent->R();
            arm.noalias() = parent->R() * (link->b() + link->q() * link->d());
            link->p() = parent->p() + arm;

            if(calcVelocity){
                const Vector3 sv(parent->R() * link->d());
                link->w() = parent->w();
                link->v().noalias() = parent->v() + sv * link->dq();

                if(calcAcceleration){
                    link->dw() = parent->dw();
                    link->dv().noalias() = parent->dv() + parent->w().cross(parent->w().cross(arm)) + parent->dw().cross(arm)
                        + 2.0 * link->dq() * parent->w().cross(sv) + link->ddq() * sv;
                }
            }
            break;

        case Link::FIXED_JOINT:
        default:
            arm.noalias() = parent->R() * link->b();
            link->R() = parent->R();
            link->p().noalias() = arm + parent->p();

            if(calcVelocity){
                link->w() = parent->w();
                link->v() = parent->v() + parent->w().cross(arm);;

                if(calcAcceleration){
                    link->dw() = parent->dw();
                    link->dv().noalias() = parent->dv() +
                        parent->w().cross(parent->w().cross(arm)) + parent->dw().cross(arm);
                }
            }
            break;
        }
    }
}