/**
         *      This method is used to compute the torques that mimick the effect of applying a force on
         *      a rigid body, at some point. It works best if the end joint is connected to something that
         *      is grounded, otherwise (I think) this is just an approximation.
         *
         *      This function works by making use of the formula:
         *
         *      t = J' * f, where J' is dp/dq, where p is the position where the force is applied, q is
         *      'sorta' the relative orientation between links. It makes the connection between the velocity
         *      of the point p and the relative angular velocities at each joint. Here's an example of how to compute it.
         *
         *      Assume: p = pBase + R1 * v1 + R2 * v2, where R1 is the matrix from link 1 to whatever pBase is specified in,
         *              and R2 is the rotation matrix from link 2 to whatever pBase is specified in, v1 is the point from link 1's
         *              origin to link 2's origin (in link 1 coordinates), and v2 is the vector from origin of link 2 to p
         *              (in link 2 coordinates).
         *
         *              dp/dt = d(R1 * v1)/dt + d(R2 * v2)/dt = d R1/dt * v1 + d R2/dt * v2, and dR/dt = wx * R, where wx is
         *              the cross product matrix associated with the angular velocity w
         *              so dp/dt = w1x * R1 * v1 + w2x * R2 * v2, and w2 = w1 + wRel
         *
         *              = [-(R1*v1 + R2*v2)x   -(R2*v1)x ] [w1   wRel]', so the first matrix is the Jacobian.
         *              The first entry is the cross product matrix of the vector (in 'global' coordinates) from the
         *              origin of link 1 to p, and the second entry is the vector (in 'global' coordinates) from
         *              the origin of link 2 to p (and therein lies the general way of writing this).
         */
        public void computeJointTorquesEquivalentToForce(CWJoint start, Vector3 pLocal, Vector3 fGlobal, CWJoint end)
        {
            //starting from the start joint, going towards the end joint, get the origin of each link, in world coordinates,
            //and compute the vector to the global coordinates of pLocal.

            CWJoint currentJoint = start;
            Vector3 tmpV;
            Vector3 pGlobal = start.getChild().getWorldCoordinatesPoint(pLocal);

            while (currentJoint != end)
            {
                //if (currentJoint == null)
                //throwError("VirtualModelController::computeJointTorquesEquivalentToForce --> end was not a parent of start...");
                tmpV = pGlobal - currentJoint.getParent().getWorldCoordinatesPoint(currentJoint.getParentJointPosition());
                Vector3 tmpT = Vector3.Cross(tmpV, fGlobal);
                torques[currentJoint.getId()] = ((float)torques[currentJoint.getId()]) - tmpT.z;
                currentJoint = currentJoint.getParent().getParentJoint();
            }

            //and we just have to do it once more for the end joint, if it's not NULL
            if (end != null)
            {
                tmpV = pGlobal - currentJoint.getParent().getWorldCoordinatesPoint(currentJoint.getParentJointPosition());
                //torques[currentJoint.getId()] = ((float)torques[currentJoint.getId()]) - Vector3.Cross(tmpV, fGlobal).z;
            }
        }
Example #2
0
        /**
         *      This method is used to compute the torques that are to be applied at the next step.
         */
        override public void computeTorques()
        {
            ReducedCharacterState rs = new ReducedCharacterState(desiredPose);

            for (int i = 0; i < jointCount; i++)
            {
                CWJoint joint = character.getJoint(i);
                if (!joint.getRelToRootFrame())
                {
                    targetOrientation[i] = rs.getJointRelativeOrientation(i);
                }
                else
                {
                    targetOrientation[i] = Quaternion.Inverse(joint.getParent().getOrientation()) * (currentHeading * rs.getJointRelativeOrientation(i));
                }
            }
        }