Eigen::MatrixXd MinimumJerkTrajectory::getDesiredValues(double _time)
{
    /**
    * For details on the analytical point to point min-jerk formulation see:
    * http://www.jneurosci.org/content/5/7/1688.full.pdf
    * http://shadmehrlab.org/book/minimum_jerk/minimumjerk.htm
    */
    if (startTrigger)
    {
        startTrigger = false;
        t0 = _time;
    }

    Eigen::MatrixXd desiredValue = Eigen::MatrixXd::Zero(nDoF, TRAJ_DIM);

    double tau = (_time - t0) / pointToPointDuration;


    if ((tau <= TAU_MAX) && (currentWaypointIndex<(nWaypoints-1)))
    {

        if (nonRotationDof != 0)
        {
            Eigen::VectorXd alpha = waypoints.col(currentWaypointIndex+1) - waypoints.col(currentWaypointIndex);
            desiredValue.block(0,POS_INDEX,nonRotationDof,1) = waypoints.col(currentWaypointIndex) + alpha * ( 10*pow(tau,3.0) - 15*pow(tau,4.0)  + 6*pow(tau,5.0)   );
            desiredValue.block(0,VEL_INDEX,nonRotationDof,1) = Eigen::VectorXd::Zero(nDoF) + alpha * ( 30*pow(tau,2.0) - 60*pow(tau,3.0)  + 30*pow(tau,4.0)  );
            desiredValue.block(0,ACC_INDEX,nonRotationDof,1) = Eigen::VectorXd::Zero(nDoF) + alpha * ( 60*pow(tau,1.0) - 180*pow(tau,2.0) + 120*pow(tau,3.0) );
        }
        if (endsWithQuaternion)
        {
            Eigen::Rotation3d qStart, qEnd;
            eigenVectorToQuaternion(waypoints.block((nDoF-QUATERNION_DIM),(currentWaypointIndex), QUATERNION_DIM, 1),  qStart);
            eigenVectorToQuaternion(waypoints.block((nDoF-QUATERNION_DIM),(currentWaypointIndex+1), QUATERNION_DIM, 1),  qEnd);

            Eigen::Rotation3d interpolatedQuat = quaternionSlerp(tau, qStart, qEnd);

            Eigen::VectorXd interpolatedQuatVector = quaternionToEigenVector(interpolatedQuat);
            desiredValue.block((nDoF-QUATERNION_DIM),POS_INDEX,QUATERNION_DIM,1) = interpolatedQuatVector;
        }
    }
    else if ((tau > TAU_MAX) && (currentWaypointIndex<(nWaypoints-1)))
    {
        startTrigger = true;
        currentWaypointIndex++;
        desiredValue.col(POS_INDEX) = waypoints.col(currentWaypointIndex);
        if (currentWaypointIndex<nWaypoints-1) {
            pointToPointDuration = pointToPointDurationVector(currentWaypointIndex);
        }
    }
    else{
        desiredValue.col(POS_INDEX) = waypoints.col(nWaypoints-1);
        trajectoryFinished = true;
    }

    return desiredValue;
}
Example #2
0
static void interpolateJob( void* pData )
{
    tKeyFrameJobData* pJobData = (tKeyFrameJobData *)pData;
    Vector4Lerp( pJobData->mpResultPos,
                 pJobData->mpPos1,
                 pJobData->mpPos0,
                 pJobData->mfPct );
    
    Vector4Lerp( pJobData->mpResultScale,
                 pJobData->mpScale0,
                 pJobData->mpScale1,
                 pJobData->mfPct );
    
    quaternionSlerp( pJobData->mpResultRot,
                     pJobData->mpRot0,
                     pJobData->mpRot1,
                     pJobData->mfPct );
    
    Vector4Lerp( pJobData->mpResultRotVec,
                 pJobData->mpRotVec0,
                 pJobData->mpRotVec1,
                 pJobData->mfPct );
    
}
Example #3
0
void animSequencePlay( tAnimSequence const* pAnimSequence,
                       tAnimHierarchy const* pAnimHierarchy,
                       tVector4* aPositions,
                       tVector4* aScalings,
                       tQuaternion* aRotations,
                       tVector4* aRotationVecs,
                       tMatrix44* aAnimMatrices,
                       float fTime )
{
    float fNumLoops = floorf( fTime / pAnimSequence->mfLastTime );
    float fFrameTime = fTime - fNumLoops * pAnimSequence->mfLastTime;
    
    // key frame for the joints
    int iNumJoints = pAnimSequence->miNumJoints;
    for( int i = 0; i < iNumJoints; i++ )
    {
        int iStart = pAnimSequence->maiStartFrames[i];
        int iEnd = pAnimSequence->maiEndFrames[i];
        
        // no valid animation frame for this joint
        if( iStart < 0 || iEnd < 0 )
        {
            continue;
        }
     
        // find the ending frame
        int iEndFrame = iStart;
        for( iEndFrame = iStart; iEndFrame <= iEnd; iEndFrame++ )
        {
            if( pAnimSequence->mafTime[iEndFrame] > fFrameTime )
            {
                break;
            }
            
        }   // for end frame = start to end
        
        // didn't find end frame
        if( iEndFrame > iEnd )
        {
            iEndFrame = iEnd;
        }
        
        int iStartFrame = iEndFrame - 1;
        if( iStartFrame < 0 )
        {
            iStartFrame = 0;
        }
        
        // just at the start
        if( iStartFrame < iStart )
        {
            iStartFrame = iStart;
        }
        
        WTFASSERT2( iStartFrame >= iStart && iStartFrame <= iEnd, "out of bounds looking for start animation frame" );
        WTFASSERT2( iEndFrame >= iStart && iEndFrame <= iEnd, "out of bounds looking for end animation frame" );
        
        float fTimeDuration = pAnimSequence->mafTime[iEndFrame] - pAnimSequence->mafTime[iStartFrame];
        float fTimeFromStart = fFrameTime - pAnimSequence->mafTime[iStartFrame];
        float fPct = 0.0f;
        
        if( fTimeDuration > 0.0f )
        {
            fPct = fTimeFromStart / fTimeDuration;
        }
        
        // clamp pct
        if( fPct > 1.0f )
        {
            fPct = 1.0f;
        }
        
        Vector4Lerp( &aPositions[i],
                     &pAnimSequence->maPositions[iStartFrame],
                     &pAnimSequence->maPositions[iEndFrame],
                     fPct );
        
        Vector4Lerp( &aScalings[i],
                     &pAnimSequence->maScalings[iStartFrame],
                     &pAnimSequence->maScalings[iEndFrame],
                     fPct );
        
        quaternionSlerp( &aRotations[i],
                         &pAnimSequence->maRotation[iStartFrame],
                         &pAnimSequence->maRotation[iEndFrame],
                         fPct );
        
        Vector4Lerp( &aRotationVecs[i],
                     &pAnimSequence->maRotationVec[iStartFrame],
                     &pAnimSequence->maRotationVec[iEndFrame],
                     fPct );
        
#if 0
        tJoint* pJoint = pAnimSequence->mapJoints[iStart];
        
        tJob job;
        tKeyFrameJobData interpJobData;
        
        interpJobData.mfPct = fPct;
        interpJobData.mpPos0 = &pAnimSequence->maPositions[iStartFrame];
        interpJobData.mpPos1 = &pAnimSequence->maPositions[iEndFrame];
        interpJobData.mpScale0 = &pAnimSequence->maScalings[iStartFrame];
        interpJobData.mpScale1 = &pAnimSequence->maScalings[iEndFrame];
        interpJobData.mpRot0 = &pAnimSequence->maRotation[iStartFrame];
        interpJobData.mpRot1 = &pAnimSequence->maRotation[iEndFrame];
        interpJobData.mpResultPos = &aPositions[i];
        interpJobData.mpResultScale = &aScalings[i];
        interpJobData.mpResultRot = &aRotations[i];
        interpJobData.mpJoint = pJoint;
        
        interpJobData.mpRotVec0 = &pAnimSequence->maRotationVec[iStartFrame];
        interpJobData.mpRotVec1 = &pAnimSequence->maRotationVec[iEndFrame];
        interpJobData.mpResultRotVec = &aRotationVecs[i];
        
        job.mpfnFunc = interpolateJob;
        job.mpData = &interpJobData;
        job.miDataSize = sizeof( tKeyFrameJobData );
        
        jobManagerAddJob( gpJobManager, &job );
#endif // #if 0
    }

#if 0
        tVector4* pScale = &aScalings[i];
        tVector4* pPosition = &aPositions[i];
        
        // interpolate position, scale, and rotation
        Vector4Lerp( pPosition,
                     &pAnimSequence->maPositions[iEndFrame],
                     &pAnimSequence->maPositions[iStartFrame],
                     fPct );
        
        Vector4Lerp( pScale,
                     &pAnimSequence->maScalings[iEndFrame],
                     &pAnimSequence->maScalings[iStartFrame],
                     fPct );
        
        quaternionSlerp( &aRotations[i],
                         &pAnimSequence->maRotation[iEndFrame],
                         &pAnimSequence->maRotation[iStartFrame],
                         fPct );
    
    jobManagerWait( gpJobManager );
#endif // #if 0
    
    for( int i = 0; i < iNumJoints; i++ )
    {
        int iStart = pAnimSequence->maiStartFrames[i];
        int iEnd = pAnimSequence->maiEndFrames[i];
        
        // no valid animation frame for this joint
        if( iStart < 0 || iEnd < 0 )
        {
            continue;
        }
        
#if 0
        tJob job;
        tMatrixJobData matrixJobData;
        matrixJobData.mpPosition = &aPositions[i];
        matrixJobData.mpRotation = &aRotations[i];
        matrixJobData.mpScale = &aScalings[i];
        matrixJobData.mpResultMat = &aAnimMatrices[i];
        matrixJobData.mpJoint = pAnimSequence->mapUniqueJoints[i];
        
        matrixJobData.mpRotationVec = &aRotationVecs[i];
        
        job.mpfnFunc = &matrixUpdateJob;
        job.mpData = &matrixJobData;
        job.miDataSize = sizeof( tMatrixJobData );
        
        jobManagerAddJob( gpJobManager, &job );
#endif // #if 0
        
        tMatrix44 posMatrix, scaleMatrix, rotMatrix, posRotMatrix;
        //quaternionToMatrix( &rotMatrix, pMatrixData->mpRotation );
        
        tMatrix44 rotMatZY, rotMatX, rotMatY, rotMatZ;
        Matrix44RotateX( &rotMatX, aRotationVecs[i].fX );
        Matrix44RotateY( &rotMatY, aRotationVecs[i].fY );
        Matrix44RotateZ( &rotMatZ, aRotationVecs[i].fZ );
        
        Matrix44Multiply( &rotMatZY, &rotMatZ, &rotMatY );
        Matrix44Multiply( &rotMatrix, &rotMatZY, &rotMatX );
        
        
        Matrix44Scale( &scaleMatrix, aScalings[i].fX, aScalings[i].fY, aScalings[i].fZ );
        Matrix44Translate( &posMatrix, &aPositions[i] );
        Matrix44Multiply( &posRotMatrix, &posMatrix, &rotMatrix );
        
        Matrix44Multiply( &aAnimMatrices[i], &posRotMatrix, &scaleMatrix );
        
#if 0
        // concat for animation matrix
        tMatrix44 posMatrix, scaleMatrix, rotMatrix, posRotMatrix;
        quaternionToMatrix( &rotMatrix, &aRotations[i] );
        Matrix44Scale( &scaleMatrix, pScale->fX, pScale->fY, pScale->fZ );
        Matrix44Translate( &posMatrix, pPosition );
        Matrix44Multiply( &posRotMatrix, &posMatrix, &rotMatrix );
        
        tMatrix44* pAnimMatrix = &aAnimMatrices[i];
        Matrix44Multiply( pAnimMatrix, &posRotMatrix, &scaleMatrix );
#endif // #if 0
        
    }   // for i = 0 to num joints
    
    jobManagerWait( gpJobManager );
}
Example #4
0
void animSequenceUpdateJointAnimValues( tAnimSequence const* pAnimSequence,
                                        tAnimHierarchy const* pAnimHierarchy,
                                        tVector4* aPositions,
                                        tVector4* aScalings,
                                        tQuaternion* aRotations,
                                        tVector4* aRotationVecs,
                                        float fTime )
{
    float fNumLoops = 0.0f;
	
	//if( pAnimSequence->mfLastTime > 0.0f )
	//{
	//	fNumLoops = floorf( fTime / pAnimSequence->mfLastTime );
	//}

	float fFrameTime = fTime - fNumLoops * pAnimSequence->mfLastTime;
    
    // key frame for the joints
    int iNumJoints = pAnimSequence->miNumJoints;
    for( int i = 0; i < iNumJoints; i++ )
    {
        int iStart = pAnimSequence->maiStartFrames[i];
        int iEnd = pAnimSequence->maiEndFrames[i];
        
        // no valid animation frame for this joint
        if( iStart < 0 || iEnd < 0 )
        {
            continue;
        }
        
        tJoint* pJoint = pAnimSequence->mapJoints[iStart];
        
        // find the ending frame
        int iEndFrame = iStart;
        for( iEndFrame = iStart; iEndFrame <= iEnd; iEndFrame++ )
        {
            if( pAnimSequence->mafTime[iEndFrame] > fFrameTime )
            {
                break;
            }
            
        }   // for end frame = start to end
        
        // didn't find end frame
        if( iEndFrame > iEnd )
        {
            iEndFrame = iEnd;
        }
        
        int iStartFrame = iEndFrame - 1;
        if( iStartFrame < 0 )
        {
            iStartFrame = 0;
        }
        
        // just at the start
        if( iStartFrame < iStart )
        {
            iStartFrame = iStart;
        }
        
        WTFASSERT2( iStartFrame >= iStart && iStartFrame <= iEnd, "out of bounds looking for start animation frame" );
        WTFASSERT2( iEndFrame >= iStart && iEndFrame <= iEnd, "out of bounds looking for end animation frame" );
        
        float fTimeDuration = pAnimSequence->mafTime[iEndFrame] - pAnimSequence->mafTime[iStartFrame];
        float fTimeFromStart = fFrameTime - pAnimSequence->mafTime[iStartFrame];
        float fPct = 0.0f;
        
        if( fTimeDuration > 0.0f )
        {
            fPct = fTimeFromStart / fTimeDuration;
        }
        
        // clamp pct
        if( fPct > 1.0f )
        {
            fPct = 1.0f;
        }
        
        int iJointIndex = 0;
        int iNumHierarchyJoints = pAnimHierarchy->miNumJoints;
        for( iJointIndex = 0; iJointIndex < iNumHierarchyJoints; iJointIndex++ )
        {
            if( !strcmp( pJoint->mszName, pAnimHierarchy->maJoints[iJointIndex].mszName ) )
            {
                break;
            }
        }
        
        WTFASSERT2( iJointIndex == i, "TEST" );
        WTFASSERT2( iJointIndex < iNumHierarchyJoints, "can't find joint in hierarchy" );
        
        Vector4Lerp( &aPositions[i],
                     &pAnimSequence->maPositions[iStartFrame],
                     &pAnimSequence->maPositions[iEndFrame],
                     fPct );
        
        Vector4Lerp( &aScalings[i],
                     &pAnimSequence->maScalings[iStartFrame],
                     &pAnimSequence->maScalings[iEndFrame],
                     fPct );
        
        quaternionSlerp( &aRotations[i],
                         &pAnimSequence->maRotation[iStartFrame],
                         &pAnimSequence->maRotation[iEndFrame],
                         fPct );
        
        Vector4Lerp( &aRotationVecs[i],
                     &pAnimSequence->maRotationVec[iStartFrame],
                     &pAnimSequence->maRotationVec[iEndFrame],
                     fPct );
        
#if 0
        tJob job;
        tKeyFrameJobData interpJobData;
        
        interpJobData.mfPct = fPct;
        interpJobData.mpPos0 = &pAnimSequence->maPositions[iStartFrame];
        interpJobData.mpPos1 = &pAnimSequence->maPositions[iEndFrame];
        interpJobData.mpScale0 = &pAnimSequence->maScalings[iStartFrame];
        interpJobData.mpScale1 = &pAnimSequence->maScalings[iEndFrame];
        interpJobData.mpRot0 = &pAnimSequence->maRotation[iStartFrame];
        interpJobData.mpRot1 = &pAnimSequence->maRotation[iEndFrame];
        interpJobData.mpResultPos = &aPositions[iJointIndex];
        interpJobData.mpResultScale = &aScalings[iJointIndex];
        interpJobData.mpResultRot = &aRotations[iJointIndex];
        interpJobData.mpJoint = pJoint;
        
        interpJobData.mpRotVec0 = &pAnimSequence->maRotationVec[iStartFrame];
        interpJobData.mpRotVec1 = &pAnimSequence->maRotationVec[iEndFrame];
        interpJobData.mpResultRotVec = &aRotationVecs[iJointIndex];
        
        job.mpfnFunc = interpolateJob;
        job.mpData = &interpJobData;
        job.miDataSize = sizeof( tKeyFrameJobData );
        
        jobManagerAddJob( gpJobManager, &job );
#endif // #if 0
        
    }   // for i = 0 to num joints
}