implementation of drecon in unity 2022 lts
forked from:
https://github.com/joanllobera/marathon-envs
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
5.7 KiB
199 lines
5.7 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
using Unity.MLAgents.Policies;
|
|
using Unity.MLAgents;
|
|
|
|
public class MapRangeOfMotion2Constraints : MonoBehaviour
|
|
{
|
|
|
|
/*
|
|
[SerializeField]
|
|
bool applyROMInGamePlay;
|
|
|
|
public bool ApplyROMInGamePlay { set => applyROMInGamePlay = value; }
|
|
*/
|
|
|
|
|
|
public RangeOfMotionValues info2store;
|
|
|
|
[Range(0, 359)]
|
|
int MinROMNeededForJoint = 5;
|
|
|
|
|
|
|
|
|
|
[SerializeField]
|
|
bool debugWithLargestROM = false;
|
|
|
|
[Tooltip("extra range for upper and lower angles of moving articulations ")]
|
|
[SerializeField]
|
|
float extraoffset = 10;
|
|
|
|
|
|
public void ConfigureTrainingForRagdoll(int minROM)
|
|
{
|
|
|
|
MinROMNeededForJoint = minROM;
|
|
|
|
int dof = ApplyRangeOfMotionToRagDoll();
|
|
if (dof == -1)
|
|
{
|
|
Debug.LogError("Problems applying the range of motion to the ragdoll");
|
|
}
|
|
else
|
|
{
|
|
|
|
ApplyDoFOnBehaviorParameters(dof);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
int ApplyRangeOfMotionToRagDoll()
|
|
{
|
|
if (info2store == null || info2store.Values.Length == 0)
|
|
return -1;
|
|
|
|
ArticulationBody[] articulationBodies =
|
|
GetComponentsInChildren<ArticulationBody>(true)
|
|
.Where(x=>x.name.StartsWith("articulation:"))
|
|
.ToArray();
|
|
|
|
int DegreesOfFreedom = 0;
|
|
|
|
|
|
|
|
foreach (ArticulationBody body in articulationBodies)
|
|
{
|
|
if (body.isRoot)
|
|
continue;
|
|
|
|
string keyword1 = "articulation:";
|
|
string keyword2 = "collider:";
|
|
string valuename = body.name.TrimStart(keyword1.ToArray<char>());
|
|
valuename = valuename.TrimStart(keyword2.ToArray<char>());
|
|
|
|
RangeOfMotionValue rom = info2store.Values.FirstOrDefault(x => x.name == valuename);
|
|
|
|
if (rom == null)
|
|
{
|
|
Debug.LogError("Could not find a rangoe of motionvalue for articulation: " + body.name);
|
|
return -1;
|
|
}
|
|
|
|
bool isLocked = true;
|
|
body.twistLock = ArticulationDofLock.LockedMotion;
|
|
body.swingYLock = ArticulationDofLock.LockedMotion;
|
|
body.swingZLock = ArticulationDofLock.LockedMotion;
|
|
body.jointType = ArticulationJointType.FixedJoint;
|
|
|
|
body.anchorRotation = Quaternion.identity; //we make sure the anchor has no Rotation, otherwise the constraints do not make any sense
|
|
|
|
if (rom.rangeOfMotion.x > (float)MinROMNeededForJoint)
|
|
{
|
|
DegreesOfFreedom++;
|
|
isLocked = false;
|
|
body.twistLock = ArticulationDofLock.LimitedMotion;
|
|
var drive = body.xDrive;
|
|
drive.lowerLimit = rom.lower.x - extraoffset;
|
|
drive.upperLimit = rom.upper.x + extraoffset;
|
|
body.xDrive = drive;
|
|
if (debugWithLargestROM)
|
|
{
|
|
drive.lowerLimit = -170;
|
|
drive.upperLimit = +170;
|
|
}
|
|
|
|
}
|
|
if (rom.rangeOfMotion.y >= (float)MinROMNeededForJoint)
|
|
{
|
|
DegreesOfFreedom++;
|
|
isLocked = false;
|
|
body.swingYLock = ArticulationDofLock.LimitedMotion;
|
|
var drive = body.yDrive;
|
|
drive.lowerLimit = rom.lower.y - extraoffset;
|
|
drive.upperLimit = rom.upper.y + extraoffset;
|
|
body.yDrive = drive;
|
|
|
|
if (debugWithLargestROM)
|
|
{
|
|
drive.lowerLimit = -170 - extraoffset;
|
|
drive.upperLimit = +170 + extraoffset;
|
|
}
|
|
|
|
|
|
}
|
|
if (rom.rangeOfMotion.z >= (float)MinROMNeededForJoint)
|
|
{
|
|
DegreesOfFreedom++;
|
|
isLocked = false;
|
|
body.swingZLock = ArticulationDofLock.LimitedMotion;
|
|
var drive = body.zDrive;
|
|
drive.lowerLimit = rom.lower.z - extraoffset;
|
|
drive.upperLimit = rom.upper.z + extraoffset;
|
|
body.zDrive = drive;
|
|
|
|
if (debugWithLargestROM)
|
|
{
|
|
drive.lowerLimit = -170;
|
|
drive.upperLimit = +170;
|
|
}
|
|
|
|
}
|
|
|
|
if (!isLocked)
|
|
{
|
|
body.jointType = ArticulationJointType.SphericalJoint;
|
|
}
|
|
|
|
}
|
|
|
|
return DegreesOfFreedom;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ApplyDoFOnBehaviorParameters(int DegreesOfFreedom)
|
|
{
|
|
|
|
BehaviorParameters bp = GetComponent<BehaviorParameters>();
|
|
|
|
Unity.MLAgents.Actuators.ActionSpec myActionSpec = bp.BrainParameters.ActionSpec;
|
|
|
|
|
|
|
|
myActionSpec.NumContinuousActions = DegreesOfFreedom;
|
|
myActionSpec.BranchSizes = new List<int>().ToArray();
|
|
bp.BrainParameters.ActionSpec = myActionSpec;
|
|
Debug.Log("Space of actions calculated at:" + myActionSpec.NumContinuousActions + " continuous dimensions");
|
|
|
|
|
|
/*
|
|
* To calculate the space of observations:
|
|
|
|
*/
|
|
|
|
|
|
int numsensors = GetComponentsInChildren<SensorBehavior>().Length;
|
|
int num_miscelaneous = GetComponent<ProcRagdollAgent>().calculateDreConObservationsize();
|
|
|
|
//apparently the number of sensors is already acocunted for in the degrees of freedom, so:
|
|
// int ObservationDimensions = DegreesOfFreedom + numsensors + num_miscelaneous;
|
|
int ObservationDimensions = DegreesOfFreedom + num_miscelaneous;
|
|
bp.BrainParameters.VectorObservationSize = ObservationDimensions;
|
|
Debug.Log("Space of perceptions calculated at:" + bp.BrainParameters.VectorObservationSize + " continuous dimensions, with: " + " sensors: " + numsensors + "and DreCon miscelaneous: " + num_miscelaneous);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|