Inheritance: MonoBehaviour, IOptimizable
示例#1
0
    void drawStepCycles(float p_phi, float p_yOffset, LegFrame p_frame, int legFrameId)
    {
        for (int i = 0; i < LegFrame.c_legCount; i++)
        {
            StepCycle cycle = p_frame.m_tuneStepCycles[i];
            if (cycle != null)
            {
                // DRAW!
                float timelineLen = 300.0f;
                float xpad        = 10.0f;
                float offset      = cycle.m_tuneStepTrigger;
                float len         = cycle.m_tuneDutyFactor;
                float lineStart   = xpad;
                float lineEnd     = lineStart + timelineLen;
                float dutyEnd     = lineStart + timelineLen * (offset + len);
                float w           = 4.0f;
                float y           = p_yOffset + (float)i * w * 2.0f;
                bool  stance      = cycle.isInStance(p_phi);
                // Draw back
                Color ucol = Color.white * 0.5f + new Color((float)(legFrameId % 2), (float)(i % 2), 1 - (float)(i % 2), 1.0f);
                int   h    = (int)w / 2;
                Drawing.DrawLine(new Vector2(lineStart - 1, y - h - 1), new Vector2(lineEnd + 1, y - h - 1), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineStart - 1, y + h), new Vector2(lineEnd + 1, y + h), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineStart - 1, y - h - 1), new Vector2(lineStart - 1, y + h + 1), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineEnd + 1, y - h - 1), new Vector2(lineEnd + 1, y + h), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineStart, y), new Vector2(lineEnd, y), new Color(1.0f, 1.0f, 1.0f, 1.0f), w);
                // Color depending on stance
                Color currentCol = Color.black;
                float phase      = cycle.getStancePhase(p_phi);
                if (stance)
                {
                    currentCol = Color.Lerp(ucol, Color.black, phase * phase);
                }

                // draw df
                Drawing.DrawLine(new Vector2(lineStart + timelineLen * offset, y), new Vector2(Mathf.Min(lineEnd, dutyEnd), y), currentCol, w);
                // draw rest if out of bounds
                if (offset + len > 1.0f)
                {
                    Drawing.DrawLine(new Vector2(lineStart, y), new Vector2(lineStart + timelineLen * (offset + len - 1.0f), y), currentCol, w);
                }

                // Draw current time marker
                Drawing.DrawLine(new Vector2(lineStart + timelineLen * p_phi - 1, y), new Vector2(lineStart + timelineLen * p_phi + 3, y),
                                 Color.red, w);
                Drawing.DrawLine(new Vector2(lineStart + timelineLen * p_phi, y), new Vector2(lineStart + timelineLen * p_phi + 2, y),
                                 Color.green * 2, w);
            }
        }
    }
示例#2
0
 void debugColorLegs()
 {
     for (int i = 0; i < m_legFrames.Length; i++)
     {
         LegFrame lf = m_legFrames[i];
         for (int n = 0; n < lf.m_tuneStepCycles.Length; n++)
         {
             StepCycle cycle   = lf.m_tuneStepCycles[n];
             Rigidbody current = m_joints[lf.m_neighbourJointIds[n]];
             if (lf.isInControlledStance(n, m_player.m_gaitPhase))
             {
                 current.gameObject.GetComponentInChildren <Renderer>().material.color = Color.yellow;
             }
             else
             {
                 current.gameObject.GetComponentInChildren <Renderer>().material.color = Color.white;
             }
         }
     }
 }
示例#3
0
 // Compute the torque of all PD-controllers in the joints
 Vector3[] computePDTorques(float p_phi)
 {
     // This loop might have to be rewritten into something a little less cumbersome
     Vector3[] newTorques = new Vector3[m_jointTorques.Length];
     if (m_usePDTorque)
     {
         for (int i = 0; i < m_legFrames.Length; i++)
         {
             LegFrame lf = m_legFrames[i];
             newTorques[lf.m_id] = m_jointTorques[lf.m_id];
             // All hip joints
             for (int n = 0; n < lf.m_tuneStepCycles.Length; n++)
             {
                 StepCycle cycle   = lf.m_tuneStepCycles[n];
                 int       jointID = lf.m_neighbourJointIds[n];
                 if (lf.isInControlledStance(i, m_player.m_gaitPhase))
                 {
                     newTorques[jointID] = Vector3.zero;
                     // m_jointTorques[jointID];
                     //Vector3.zero;
                     //
                 }
                 else if (m_desiredJointTorquesPD.Length > 0)
                 {
                     newTorques[jointID] = m_desiredJointTorquesPD[jointID].m_vec;
                 }
             }
             // All other joints
             for (int n = 0; n < lf.m_legJointIds.Length; n++)
             {
                 int jointID = lf.m_legJointIds[n];
                 if (jointID > -1)
                 {
                     newTorques[jointID] = m_desiredJointTorquesPD[jointID].m_vec;
                 }
             }
         }
     }
     return(newTorques);
 }
示例#4
0
    // Compute the torque of all applied virtual forces
    Vector3[] computeVFTorques(float p_phi, float p_dt)
    {
        Vector3[] newTorques = new Vector3[m_jointTorques.Length];
        if (m_useVFTorque)
        {
            for (int i = 0; i < m_legFrames.Length; i++)
            {
                LegFrame lf = m_legFrames[i];
                lf.calculateNetLegVF(p_phi, p_dt, m_currentVelocity, m_desiredVelocity);
                // Calculate torques using each leg chain
                for (int n = 0; n < LegFrame.c_legCount; n++)
                {
                    //  get the joints
                    int legFrameRoot = lf.m_id;
                    //legFrameRoot = -1;
                    int legRoot         = lf.m_neighbourJointIds[n];
                    int legSegmentCount = LegFrame.c_legSegments; // hardcoded now
                    // Use joint ids to get dof ids
                    // Start in chain
                    int legFrameRootDofId = -1; // if we have separate root as base link
                    if (legFrameRoot != -1)
                    {
                        legFrameRootDofId = m_chain[legFrameRoot].m_dofListIdx;
                    }
                    // otherwise, use first in chain as base link
                    int legRootDofId = m_chain[legRoot].m_dofListIdx;
                    // end in chain
                    int lastDofIdx = legRoot + legSegmentCount - 1;
                    int legDofEnd  = m_chain[lastDofIdx].m_dofListIdx + m_chain[lastDofIdx].m_dof.Length;
                    //
                    // get force for the leg
                    Vector3 VF = lf.m_netLegBaseVirtualForces[n];
                    // Calculate torques for each joint
                    // Start by updating joint information based on their gameobjects
                    Vector3 end = transform.localPosition;
                    //Debug.Log("legroot "+legRoot+" legseg "+legSegmentCount);
                    int jointstart = legRoot;
                    if (legFrameRoot != -1)
                    {
                        jointstart = legFrameRoot;
                    }
                    for (int x = jointstart; x < legRoot + legSegmentCount; x++)
                    {
                        if (legFrameRoot != -1 && x < legRoot && x != legFrameRoot)
                        {
                            x = legRoot;
                        }
                        Joint      current    = m_chain[x];
                        GameObject currentObj = m_chainObjs[x];
                        //Debug.Log("joint pos: " + currentObj.transform.localPosition);
                        // Update Joint
                        current.length     = currentObj.transform.localScale.y;
                        current.m_position = currentObj.transform.position /*- (-currentObj.transform.up) * current.length * 0.5f*/;
                        current.m_endPoint = currentObj.transform.position + (-currentObj.transform.up) * current.length /* * 0.5f*/;
                        //m_chain[i] = current;
                        //Debug.DrawLine(current.m_position, current.m_endPoint, Color.red);
                        //Debug.Log(x+" joint pos: " + current.m_position + " = " + m_chain[x].m_position);
                        end = current.m_endPoint;
                    }
                    //foreach(Joint j in m_chain)
                    //    Debug.Log("joint pos CC: " + j.m_position);

                    //CMatrix J = Jacobian.calculateJacobian(m_chain, m_chain.Count, end, Vector3.forward);
                    CMatrix J = Jacobian.calculateJacobian(m_chain,            // Joints (Joint script)
                                                           m_chainObjs,        // Gameobjects in chain
                                                           m_dofs,             // Degrees Of Freedom (Per joint)
                                                           m_dofJointId,       // Joint id per DOF
                                                           end + VF,           // Target position
                                                           legRootDofId,       // Starting link id in chain (start offset)
                                                           legDofEnd,          // End of chain of link (ie. size)
                                                           legFrameRootDofId); // As we use the leg frame as base, we supply it separately (it will be actual root now)
                    CMatrix Jt = CMatrix.Transpose(J);

                    //Debug.DrawLine(end, end + VF, Color.magenta, 0.3f);
                    int jIdx  = 0;
                    int extra = 0;
                    int start = legRootDofId;
                    if (legFrameRootDofId >= 0)
                    {
                        start = legFrameRootDofId;
                        extra = m_chain[legFrameRoot].m_dof.Length;
                    }


                    for (int g = start; g < legDofEnd; g++)
                    {
                        if (extra > 0)
                        {
                            extra--;
                        }
                        else if (g < legRootDofId)
                        {
                            g = legRootDofId;
                        }

                        // store torque
                        int     x    = m_dofJointId[g];
                        Vector3 addT = m_dofs[g] * Vector3.Dot(new Vector3(Jt[jIdx, 0], Jt[jIdx, 1], Jt[jIdx, 2]), VF);
                        Debug.DrawLine(m_joints[x].transform.position, m_joints[x].transform.position + VF, new Color(0.0f, 153.0f / 256.0f, 0.0f));
                        newTorques[x] += addT;
                        jIdx++;
                        //Vector3 drawTorque = new Vector3(0.0f, 0.0f, -addT.x);
                        //Debug.DrawLine(m_joints[x].transform.position, m_joints[x].transform.position + drawTorque*0.1f, Color.cyan);
                    }
                    // Come to think of it, the jacobian and torque could be calculated in the same
                    // kernel as it lessens write to global memory and the need to fetch joint matrices several time (transform above)
                }
            }
        }
        return(newTorques);
    }
示例#5
0
    // Compute the torque needed on swing legs to compensate for gravity
    Vector3[] computeCGVFTorques(float p_phi, float p_dt)
    {
        Vector3[] newTorques = new Vector3[m_jointTorques.Length];
        if (m_useVFTorque)
        {
            for (int i = 0; i < m_legFrames.Length; i++)
            {
                LegFrame lf = m_legFrames[i];
                // Calculate torques using each leg chain
                for (int n = 0; n < LegFrame.c_legCount; n++)              // for each leg
                {
                    if (!lf.isInControlledStance(n, m_player.m_gaitPhase)) // only on swing
                    {
                        for (int m = 0; m < LegFrame.c_legSegments; m++)   // for each segment in leg
                        {
                            //  get the joints
                            int segIdx = n * LegFrame.c_legSegments + m + 1; // get segment index in list (+1 to offset for LF)
                            //Debug.Log("sidx: " + segIdx);
                            Rigidbody segment = m_joints[segIdx];
                            lf.calculateFgravcomp(segIdx - 1, segment);
                            //
                            // Calculate jacobian
                            //
                            //  get the joints
                            int legFrameRoot = lf.m_id;
                            //legFrameRoot = -1;
                            int legRoot         = lf.m_neighbourJointIds[n];
                            int legSegmentCount = m + 1; // the amount of segments decreases the further in in the hierarchy we get
                            // Use joint ids to get dof ids
                            // Start in chain
                            int legFrameRootDofId = -1; // if we have separate root as base link
                            if (legFrameRoot != -1)
                            {
                                legFrameRootDofId = m_chain[legFrameRoot].m_dofListIdx;
                            }
                            // otherwise, use first in chain as base link
                            int legRootDofId = m_chain[legRoot].m_dofListIdx;
                            // end in chain
                            int lastDofIdx = legRoot + m;
                            int legDofEnd  = m_chain[lastDofIdx].m_dofListIdx + m_chain[lastDofIdx].m_dof.Length;
                            //
                            // get force for the leg
                            Vector3 VF = lf.m_legSegmentGravityCompVirtualForces[segIdx - 1];
                            // Calculate torques for each joint
                            // Start by updating joint information based on their gameobjects
                            Vector3 end = segment.transform.TransformPoint(segment.centerOfMass);
                            //foreach(Joint j in m_chain)
                            //    Debug.Log("joint pos CC: " + j.m_position);

                            //CMatrix J = Jacobian.calculateJacobian(m_chain, m_chain.Count, end, Vector3.forward);
                            CMatrix J = Jacobian.calculateJacobian(m_chain,            // Joints (Joint script)
                                                                   m_chainObjs,        // Gameobjects in chain
                                                                   m_dofs,             // Degrees Of Freedom (Per joint)
                                                                   m_dofJointId,       // Joint id per DOF
                                                                   end + VF,           // Target position
                                                                   legRootDofId,       // Starting link id in chain (start offset)
                                                                   legDofEnd,          // End of chain of link (ie. size)
                                                                   legFrameRootDofId); // As we use the leg frame as base, we supply it separately (it will be actual root now)
                            CMatrix Jt = CMatrix.Transpose(J);

                            //Debug.DrawLine(end, end + VF * 0.4f, Color.magenta);

                            /*Color idxCol = new Color((float)n / (float)LegFrame.c_legCount, (float)m / (float)LegFrame.c_legSegments, (float)segIdx / (float)(LegFrame.c_legCount * LegFrame.c_legSegments));
                             * Debug.DrawLine(end, end + VF, idxCol);
                             * Debug.DrawLine(end, end + VF, idxCol);*/

                            int jIdx  = 0;
                            int extra = 0;
                            int start = legRootDofId;
                            if (legFrameRootDofId >= 0)
                            {
                                start = legFrameRootDofId;
                                extra = m_chain[legFrameRoot].m_dof.Length;
                            }


                            for (int g = start; g < legDofEnd; g++)
                            {
                                if (extra > 0)
                                {
                                    extra--;
                                }
                                else if (g < legRootDofId)
                                {
                                    g = legRootDofId;
                                }

                                // store torque
                                int x = m_dofJointId[g];
                                Debug.DrawLine(m_joints[x].transform.position, m_joints[x].transform.position + VF, new Color(1.0f, 153.0f / 255.0f, 153.0f / 255.0f));
                                Vector3 addT = m_dofs[g] * Vector3.Dot(new Vector3(Jt[jIdx, 0], Jt[jIdx, 1], Jt[jIdx, 2]), VF);
                                newTorques[x] += addT;
                                jIdx++;
                                Vector3 drawTorque = addT;
                                //Debug.DrawLine(m_joints[x].transform.position, m_joints[x].transform.position + drawTorque * 0.5f, idxCol);
                            }
                        } // endfor legsegments
                    }     // endif not-stance
                }         // endfor legs
            }
        }
        return(newTorques);
    }
示例#6
0
    void drawStepCycles(float p_phi,float p_yOffset,LegFrame p_frame, int legFrameId)
    {
        for (int i = 0; i < LegFrame.c_legCount; i++)
        {
            StepCycle cycle = p_frame.m_tuneStepCycles[i];
            if (cycle!=null)
            {
                // DRAW!
                float timelineLen = 300.0f;
                float xpad = 10.0f;
                float offset = cycle.m_tuneStepTrigger;
                float len = cycle.m_tuneDutyFactor;
                float lineStart = xpad;
                float lineEnd = lineStart + timelineLen;
                float dutyEnd = lineStart + timelineLen * (offset + len);
                float w = 4.0f;
                float y = p_yOffset+(float)i*w*2.0f;
                bool stance = cycle.isInStance(p_phi);
                // Draw back
                Color ucol = Color.white*0.5f+new Color((float)(legFrameId%2), (float)(i%2), 1-(float)(i%2),1.0f);
                int h = (int)w / 2;
                Drawing.DrawLine(new Vector2(lineStart-1, y-h-1), new Vector2(lineEnd+1, y-h-1), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineStart-1, y+h), new Vector2(lineEnd+1, y+h), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineStart-1, y-h-1), new Vector2(lineStart-1, y+h+1), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineEnd+1, y-h-1), new Vector2(lineEnd+1, y+h), Color.black, 1);
                Drawing.DrawLine(new Vector2(lineStart, y), new Vector2(lineEnd, y), new Color(1.0f,1.0f,1.0f,1.0f), w);
                // Color depending on stance
                Color currentCol = Color.black;
                float phase = cycle.getStancePhase(p_phi);
                if (stance)
                    currentCol = Color.Lerp(ucol, Color.black, phase*phase);

                // draw df
                Drawing.DrawLine(new Vector2(lineStart + timelineLen * offset, y), new Vector2(Mathf.Min(lineEnd, dutyEnd), y), currentCol, w);
                // draw rest if out of bounds
                if (offset + len > 1.0f)
                    Drawing.DrawLine(new Vector2(lineStart, y), new Vector2(lineStart + timelineLen * (offset + len - 1.0f), y), currentCol, w);

                // Draw current time marker
                Drawing.DrawLine(new Vector2(lineStart + timelineLen * p_phi-1, y), new Vector2(lineStart + timelineLen * p_phi + 3, y),
                    Color.red, w);
                Drawing.DrawLine(new Vector2(lineStart + timelineLen * p_phi, y), new Vector2(lineStart + timelineLen * p_phi + 2, y),
                    Color.green*2, w);
            }
        }
    }