# Balancing biped

Howdy guys

I want to balance a biped on a shifting platform ( think a ship at sea ). I’ve created the project but Im worried that my policy for the ml agent wont be feasible.

My attempt here is to have the zmp and compoint laying almost ontop of eachother, which I reward the
agent for. Please correct me if this the wrong way of doing this.

I have some concerns while looking at the training.

• velocity should probably be apart of calculation of center of mass point.
• I’ve come across “inverted pendelum” which I think in principle is reach the zero momentum
for balance ? but from what I saw that project required very high framerate for it to be accurate.

All in all I just wanted to spruce up a ragdoll state but I would be cool if I could get it
rebalance - but Im not holding my breath.

Im thankful for any input on this or experiance !

``````        Vector3 zmpPoint = PointOnDirectionPercent(rFoot.joint.transform.position, lFoot.joint.transform.position, 0.5f);

if (rFootContact.HasContact() && !lFootContact.HasContact())
{
zmpPoint = rFoot.joint.transform.position;
}
else if (!rFootContact.HasContact() && lFootContact.HasContact())
{
zmpPoint = lFoot.joint.transform.position;
}

Vector3 zmpLoc = root.transform.InverseTransformPoint(zmpPoint);
zmpLoc.y = 0;
Vector3 comLoc = root.transform.InverseTransformPoint(CoMPoint);
comLoc.y = 0;

// Todo calculate total centermass of all character

Vector3 comZmpDelta = zmpLoc - comLoc;
float CoMScore = Mathf.Clamp(1 - comZmpDelta.magnitude, 0, 1);
//Debug.Log("CoMScore : " + CoMScore);

);
``````

Here is a snippet.

The CoMpoint is the center of mass of all the articulated joints - calculated like this.

``````        Vector3 CoM = Vector3.zero;
float c = 0f;

foreach (ArticulationBody part in assembly)
{
CoM += part.worldCenterOfMass * part.mass;
c += part.mass;
}

return CoM /= c;
``````

You can try using a body root object (hips, torso etc) and reward the agent for minimizing its inclination.
Something like

``````float normalized_inclination = Mathf.Clamp01(Vector3.Angle(Vector3.up, body_root.up) / 90f);
float reward = Mathf.Pow(1 - normalized_inclination, exponent) * reward_factor;
``````

Or maybe calculate the average up angle of a couple of body parts.