Add files for multiclip reward

This commit is contained in:
tfederico 2020-09-17 18:04:41 +01:00
parent 5ce97ffdb1
commit ab8d927845
14 changed files with 12367 additions and 0 deletions

View File

@ -0,0 +1,25 @@
--scene imitate
--num_update_substeps 10
--num_sim_substeps 2
--world_scale 4
--terrain_file data/terrain/plane.txt
--char_types general
--character_files data/characters/humanoid3d.txt
--enable_char_soft_contact false
--fall_contact_bodies 0 1 2 3 4 6 7 8 9 10 12 13 14
--char_ctrls ct_pd
--char_ctrl_files data/controllers/humanoid3d_ctrl.txt
--motion_file data/motions/walker/walk_forward0.txt
--sync_char_root_pos true
--sync_char_root_rot false
--agent_files data/agents/ct_agent_humanoid_ppo.txt
--train_agents false
#--output_path output
#--int_output_path output/intermediate
--model_files data/policies/humanoid3d/humanoid3d_walker.ckpt

View File

@ -0,0 +1,33 @@
--scene imitate
--time_lim_min 0.5
--time_lim_max 0.5
--time_lim_exp 0.2
--time_end_lim_min 20
--time_end_lim_max 20
--time_end_lim_exp 50
--anneal_samples 32000000
--num_update_substeps 10
--num_sim_substeps 2
--world_scale 4
--terrain_file data/terrain/plane.txt
--char_types general
--character_files data/characters/humanoid3d.txt
--enable_char_soft_contact false
--fall_contact_bodies 0 1 2 3 4 6 7 8 9 10 12 13 14
--char_ctrls ct_pd
--char_ctrl_files data/controllers/humanoid3d_ctrl.txt
--motion_file data/motions/walker/
--sync_char_root_pos true
--sync_char_root_rot false
--agent_files data/agents/ct_agent_humanoid_ppo.txt
#--train_agents false
--output_path output
#--int_output_path output/intermediate
#--model_files data/policies/humanoid3d/agent0_model.ckpt

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
import numpy as np
import sys
import os
import inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(os.path.dirname(currentdir))
os.sys.path.insert(0, parentdir)
print("parentdir=", parentdir)
from pybullet_envs.deep_mimic.env.pybullet_deep_mimic_env_multiclip import PyBulletDeepMimicEnvMultiClip
from pybullet_envs.deep_mimic.learning.rl_world import RLWorld
from pybullet_utils.logger import Logger
from pybullet_envs.deep_mimic.testrl_multiclip import update_world, update_timestep, build_world
import pybullet_utils.mpi_util as MPIUtil
args = []
world = None
def run():
global update_timestep
global world
done = False
while not (done):
update_world(world, update_timestep)
return
def shutdown():
global world
Logger.print2('Shutting down...')
world.shutdown()
return
def main():
global args
global world
# Command line arguments
args = sys.argv[1:]
enable_draw = False
world = build_world(args, enable_draw)
run()
shutdown()
return
if __name__ == '__main__':
main()

View File

@ -0,0 +1,997 @@
from pybullet_utils import pd_controller_stable
from pybullet_envs.deep_mimic.env import humanoid_pose_interpolator
import math
import numpy as np
chest = 1
neck = 2
rightHip = 3
rightKnee = 4
rightAnkle = 5
rightShoulder = 6
rightElbow = 7
leftHip = 9
leftKnee = 10
leftAnkle = 11
leftShoulder = 12
leftElbow = 13
jointFrictionForce = 0
class HumanoidStablePDMultiClip(object):
def __init__(self, pybullet_client, mocap_data, timeStep,
useFixedBase=True, arg_parser=None, useComReward=False):
self._pybullet_client = pybullet_client
self._mocap_data = mocap_data # this is a dictionary
self._arg_parser = arg_parser
self._n_clips = self._mocap_data.getNumClips()
print("LOADING humanoid!")
flags = self._pybullet_client.URDF_MAINTAIN_LINK_ORDER + self._pybullet_client.URDF_USE_SELF_COLLISION + self._pybullet_client.URDF_USE_SELF_COLLISION_EXCLUDE_ALL_PARENTS
self._sim_model = self._pybullet_client.loadURDF(
"humanoid/humanoid.urdf", [0, 0.889540259, 0],
globalScaling=0.25,
useFixedBase=useFixedBase,
flags=flags)
# self._pybullet_client.setCollisionFilterGroupMask(self._sim_model,-1,collisionFilterGroup=0,collisionFilterMask=0)
# for j in range (self._pybullet_client.getNumJoints(self._sim_model)):
# self._pybullet_client.setCollisionFilterGroupMask(self._sim_model,j,collisionFilterGroup=0,collisionFilterMask=0)
self._end_effectors = [5, 8, 11, 14] # ankle and wrist, both left and right
self._kin_models = {}
self._poseInterpolators = {}
for i in range(self._n_clips):
self._kin_models[i] = self._pybullet_client.loadURDF(
"humanoid/humanoid.urdf", [0, 0.85, 0],
globalScaling=0.25,
useFixedBase=True,
flags=self._pybullet_client.URDF_MAINTAIN_LINK_ORDER)
self._pybullet_client.changeDynamics(self._sim_model, -1, lateralFriction=0.9)
for j in range(self._pybullet_client.getNumJoints(self._sim_model)):
self._pybullet_client.changeDynamics(self._sim_model, j, lateralFriction=0.9)
self._pybullet_client.changeDynamics(self._sim_model, -1, linearDamping=0, angularDamping=0)
for i in range(self._n_clips):
self._pybullet_client.changeDynamics(self._kin_models[i], -1, linearDamping=0, angularDamping=0)
# todo: add feature to disable simulation for a particular object. Until then, disable all collisions
self._pybullet_client.setCollisionFilterGroupMask(self._kin_models[i],
-1,
collisionFilterGroup=0,
collisionFilterMask=0)
self._pybullet_client.changeDynamics(
self._kin_models[i],
-1,
activationState=self._pybullet_client.ACTIVATION_STATE_SLEEP +
self._pybullet_client.ACTIVATION_STATE_ENABLE_SLEEPING +
self._pybullet_client.ACTIVATION_STATE_DISABLE_WAKEUP)
alpha = 0.4
self._pybullet_client.changeVisualShape(self._kin_models[i], -1, rgbaColor=[1, 1, 1, alpha])
for j in range(self._pybullet_client.getNumJoints(self._kin_models[i])):
self._pybullet_client.setCollisionFilterGroupMask(self._kin_models[i],
j,
collisionFilterGroup=0,
collisionFilterMask=0)
self._pybullet_client.changeDynamics(
self._kin_models[i],
j,
activationState=self._pybullet_client.ACTIVATION_STATE_SLEEP +
self._pybullet_client.ACTIVATION_STATE_ENABLE_SLEEPING +
self._pybullet_client.ACTIVATION_STATE_DISABLE_WAKEUP)
self._pybullet_client.changeVisualShape(self._kin_models[i], j, rgbaColor=[1, 1, 1, alpha])
self._poseInterpolators[i] = humanoid_pose_interpolator.HumanoidPoseInterpolator()
for j in range(self._mocap_data.getNumFrames() - 1):
frameData = self._mocap_data._motion_data[i]['Frames'][j]
self._poseInterpolators[i].PostProcessMotionData(frameData)
self._stablePD = pd_controller_stable.PDControllerStableMultiDof(self._pybullet_client)
self._timeStep = timeStep
self._kpOrg = [
0, 0, 0, 0, 0, 0, 0, 1000, 1000, 1000, 1000, 100, 100, 100, 100, 500, 500, 500, 500, 500,
400, 400, 400, 400, 400, 400, 400, 400, 300, 500, 500, 500, 500, 500, 400, 400, 400, 400,
400, 400, 400, 400, 300
]
self._kdOrg = [
0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 10, 10, 10, 10, 50, 50, 50, 50, 50, 40, 40, 40,
40, 40, 40, 40, 40, 30, 50, 50, 50, 50, 50, 40, 40, 40, 40, 40, 40, 40, 40, 30
]
self._jointIndicesAll = [
chest, neck, rightHip, rightKnee, rightAnkle, rightShoulder, rightElbow, leftHip, leftKnee,
leftAnkle, leftShoulder, leftElbow
]
for j in self._jointIndicesAll:
# self._pybullet_client.setJointMotorControlMultiDof(self._sim_model, j, self._pybullet_client.POSITION_CONTROL, force=[1,1,1])
self._pybullet_client.setJointMotorControl2(self._sim_model,
j,
self._pybullet_client.POSITION_CONTROL,
targetPosition=0,
positionGain=0,
targetVelocity=0,
force=jointFrictionForce)
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
j,
self._pybullet_client.POSITION_CONTROL,
targetPosition=[0, 0, 0, 1],
targetVelocity=[0, 0, 0],
positionGain=0,
velocityGain=1,
force=[jointFrictionForce, jointFrictionForce, jointFrictionForce])
for i in range(self._n_clips):
self._pybullet_client.setJointMotorControl2(self._kin_models[i],
j,
self._pybullet_client.POSITION_CONTROL,
targetPosition=0,
positionGain=0,
targetVelocity=0,
force=0)
self._pybullet_client.setJointMotorControlMultiDof(
self._kin_models[i],
j,
self._pybullet_client.POSITION_CONTROL,
targetPosition=[0, 0, 0, 1],
targetVelocity=[0, 0, 0],
positionGain=0,
velocityGain=1,
force=[jointFrictionForce, jointFrictionForce, 0])
self._jointDofCounts = [4, 4, 4, 1, 4, 4, 1, 4, 1, 4, 4, 1]
# only those body parts/links are allowed to touch the ground, otherwise the episode terminates
fall_contact_bodies = []
if self._arg_parser is not None:
fall_contact_bodies = self._arg_parser.parse_ints("fall_contact_bodies")
self._fall_contact_body_parts = fall_contact_bodies
# [x,y,z] base position and [x,y,z,w] base orientation!
self._totalDofs = 7
for dof in self._jointDofCounts:
self._totalDofs += dof
self.setSimTime(0)
self._useComReward = useComReward
self.resetPose()
def resetPose(self):
# print("resetPose with self._frame=", self._frame, " and self._frameFraction=",self._frameFraction)
pose = self.computePose(self._frameFraction, 0)
self.initializePose(self._poseInterpolators[0], self._sim_model, initBase=True)
self.initializePose(self._poseInterpolators[0], self._kin_models[0], initBase=False)
for i in range(1, self._n_clips):
_ = self.computePose(self._frameFraction, i)
# self.initializePose(self._poseInterpolators[i], self._sim_model, initBase=True)
self.initializePose(self._poseInterpolators[i], self._kin_models[i], initBase=False)
def initializePose(self, pose, phys_model, initBase, initializeVelocity=True):
useArray = True
if initializeVelocity:
if initBase:
self._pybullet_client.resetBasePositionAndOrientation(phys_model, pose._basePos,
pose._baseOrn)
self._pybullet_client.resetBaseVelocity(phys_model, pose._baseLinVel, pose._baseAngVel)
if useArray:
indices = [chest, neck, rightHip, rightKnee,
rightAnkle, rightShoulder, rightElbow, leftHip,
leftKnee, leftAnkle, leftShoulder, leftElbow]
jointPositions = [pose._chestRot, pose._neckRot, pose._rightHipRot, pose._rightKneeRot,
pose._rightAnkleRot, pose._rightShoulderRot, pose._rightElbowRot, pose._leftHipRot,
pose._leftKneeRot, pose._leftAnkleRot, pose._leftShoulderRot, pose._leftElbowRot]
jointVelocities = [pose._chestVel, pose._neckVel, pose._rightHipVel, pose._rightKneeVel,
pose._rightAnkleVel, pose._rightShoulderVel, pose._rightElbowVel, pose._leftHipVel,
pose._leftKneeVel, pose._leftAnkleVel, pose._leftShoulderVel, pose._leftElbowVel]
self._pybullet_client.resetJointStatesMultiDof(phys_model, indices,
jointPositions, jointVelocities)
else:
self._pybullet_client.resetJointStateMultiDof(phys_model, chest, pose._chestRot,
pose._chestVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, neck, pose._neckRot, pose._neckVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, rightHip, pose._rightHipRot,
pose._rightHipVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, rightKnee, pose._rightKneeRot,
pose._rightKneeVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, rightAnkle, pose._rightAnkleRot,
pose._rightAnkleVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, rightShoulder,
pose._rightShoulderRot, pose._rightShoulderVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, rightElbow, pose._rightElbowRot,
pose._rightElbowVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, leftHip, pose._leftHipRot,
pose._leftHipVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, leftKnee, pose._leftKneeRot,
pose._leftKneeVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, leftAnkle, pose._leftAnkleRot,
pose._leftAnkleVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, leftShoulder,
pose._leftShoulderRot, pose._leftShoulderVel)
self._pybullet_client.resetJointStateMultiDof(phys_model, leftElbow, pose._leftElbowRot,
pose._leftElbowVel)
else:
if initBase:
self._pybullet_client.resetBasePositionAndOrientation(phys_model, pose._basePos,
pose._baseOrn)
if useArray:
indices = [chest, neck, rightHip, rightKnee,
rightAnkle, rightShoulder, rightElbow, leftHip,
leftKnee, leftAnkle, leftShoulder, leftElbow]
jointPositions = [pose._chestRot, pose._neckRot, pose._rightHipRot, pose._rightKneeRot,
pose._rightAnkleRot, pose._rightShoulderRot, pose._rightElbowRot, pose._leftHipRot,
pose._leftKneeRot, pose._leftAnkleRot, pose._leftShoulderRot, pose._leftElbowRot]
self._pybullet_client.resetJointStatesMultiDof(phys_model, indices, jointPositions)
else:
self._pybullet_client.resetJointStateMultiDof(phys_model, chest, pose._chestRot, [0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, neck, pose._neckRot, [0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, rightHip, pose._rightHipRot,
[0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, rightKnee, pose._rightKneeRot, [0])
self._pybullet_client.resetJointStateMultiDof(phys_model, rightAnkle, pose._rightAnkleRot,
[0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, rightShoulder,
pose._rightShoulderRot, [0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, rightElbow, pose._rightElbowRot,
[0])
self._pybullet_client.resetJointStateMultiDof(phys_model, leftHip, pose._leftHipRot,
[0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, leftKnee, pose._leftKneeRot, [0])
self._pybullet_client.resetJointStateMultiDof(phys_model, leftAnkle, pose._leftAnkleRot,
[0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, leftShoulder,
pose._leftShoulderRot, [0, 0, 0])
self._pybullet_client.resetJointStateMultiDof(phys_model, leftElbow, pose._leftElbowRot, [0])
def calcCycleCount(self, simTime, cycleTime):
phases = simTime / cycleTime
count = math.floor(phases)
loop = True
# count = (loop) ? count : cMathUtil::Clamp(count, 0, 1);
return count
def getCycleTime(self):
keyFrameDuration = self._mocap_data.getKeyFrameDuration()
cycleTime = keyFrameDuration * (self._mocap_data.getNumFrames() - 1)
return cycleTime
def setSimTime(self, t):
self._simTime = t
# print("SetTimeTime time =",t)
keyFrameDuration = self._mocap_data.getKeyFrameDuration()
cycleTime = self.getCycleTime()
# print("self._motion_data.NumFrames()=",self._mocap_data.NumFrames())
self._cycleCount = self.calcCycleCount(t, cycleTime)
# print("cycles=",cycles)
frameTime = t - self._cycleCount * cycleTime
if (frameTime < 0):
frameTime += cycleTime
# print("keyFrameDuration=",keyFrameDuration)
# print("frameTime=",frameTime)
self._frame = int(frameTime / keyFrameDuration)
# print("self._frame=",self._frame)
self._frameNext = self._frame + 1
if (self._frameNext >= self._mocap_data.getNumFrames()):
self._frameNext = self._frame
self._frameFraction = (frameTime - self._frame * keyFrameDuration) / (keyFrameDuration)
def computeCycleOffset(self, i=0):
firstFrame = 0
lastFrame = self._mocap_data.getNumFrames() - 1
frameData = self._mocap_data._motion_data[i]['Frames'][0]
frameDataNext = self._mocap_data._motion_data[i]['Frames'][lastFrame]
basePosStart = [frameData[1], frameData[2], frameData[3]]
basePosEnd = [frameDataNext[1], frameDataNext[2], frameDataNext[3]]
self._cycleOffset = [
basePosEnd[0] - basePosStart[0], basePosEnd[1] - basePosStart[1],
basePosEnd[2] - basePosStart[2]
]
return self._cycleOffset
def computePose(self, frameFraction, i=0):
frameData = self._mocap_data._motion_data[i]['Frames'][self._frame]
frameDataNext = self._mocap_data._motion_data[i]['Frames'][self._frameNext]
self._poseInterpolators[i].Slerp(frameFraction, frameData, frameDataNext, self._pybullet_client)
# print("self._poseInterpolator.Slerp(", frameFraction,")=", pose)
self.computeCycleOffset()
oldPos = self._poseInterpolators[i]._basePos
self._poseInterpolators[i]._basePos = [
oldPos[0] + self._cycleCount * self._cycleOffset[0],
oldPos[1] + self._cycleCount * self._cycleOffset[1],
oldPos[2] + self._cycleCount * self._cycleOffset[2]
]
pose = self._poseInterpolators[i].GetPose()
return pose
def convertActionToPose(self, action, i):
pose = self._poseInterpolators[i].ConvertFromAction(self._pybullet_client, action)
return pose
def computeAndApplyPDForces(self, desiredPositions, maxForces):
dofIndex = 7
scaling = 1
indices = []
forces = []
targetPositions = []
targetVelocities = []
kps = []
kds = []
for index in range(len(self._jointIndicesAll)):
jointIndex = self._jointIndicesAll[index]
indices.append(jointIndex)
kps.append(self._kpOrg[dofIndex])
kds.append(self._kdOrg[dofIndex])
if self._jointDofCounts[index] == 4:
force = [
scaling * maxForces[dofIndex + 0],
scaling * maxForces[dofIndex + 1],
scaling * maxForces[dofIndex + 2]
]
targetVelocity = [0, 0, 0]
targetPosition = [
desiredPositions[dofIndex + 0],
desiredPositions[dofIndex + 1],
desiredPositions[dofIndex + 2],
desiredPositions[dofIndex + 3]
]
if self._jointDofCounts[index] == 1:
force = [scaling * maxForces[dofIndex]]
targetPosition = [desiredPositions[dofIndex + 0]]
targetVelocity = [0]
forces.append(force)
targetPositions.append(targetPosition)
targetVelocities.append(targetVelocity)
dofIndex += self._jointDofCounts[index]
# static char* kwlist[] = { "bodyUniqueId",
# "jointIndices",
# "controlMode", "targetPositions", "targetVelocities", "forces", "positionGains", "velocityGains", "maxVelocities", "physicsClientId", NULL };
self._pybullet_client.setJointMotorControlMultiDofArray(self._sim_model,
indices,
self._pybullet_client.STABLE_PD_CONTROL,
targetPositions=targetPositions,
targetVelocities=targetVelocities,
forces=forces,
positionGains=kps,
velocityGains=kds,
)
def computePDForces(self, desiredPositions, desiredVelocities, maxForces):
"""Compute torques from the PD controller."""
if desiredVelocities == None:
desiredVelocities = [0] * self._totalDofs
taus = self._stablePD.computePD(bodyUniqueId=self._sim_model,
jointIndices=self._jointIndicesAll,
desiredPositions=desiredPositions,
desiredVelocities=desiredVelocities,
kps=self._kpOrg,
kds=self._kdOrg,
maxForces=maxForces,
timeStep=self._timeStep)
return taus
def applyPDForces(self, taus):
"""Apply pre-computed torques."""
dofIndex = 7
scaling = 1
useArray = True
indices = []
forces = []
if (useArray):
for index in range(len(self._jointIndicesAll)):
jointIndex = self._jointIndicesAll[index]
indices.append(jointIndex)
if self._jointDofCounts[index] == 4:
force = [
scaling * taus[dofIndex + 0], scaling * taus[dofIndex + 1],
scaling * taus[dofIndex + 2]
]
if self._jointDofCounts[index] == 1:
force = [scaling * taus[dofIndex]]
# print("force[", jointIndex,"]=",force)
forces.append(force)
dofIndex += self._jointDofCounts[index]
self._pybullet_client.setJointMotorControlMultiDofArray(self._sim_model,
indices,
self._pybullet_client.TORQUE_CONTROL,
forces=forces)
else:
for index in range(len(self._jointIndicesAll)):
jointIndex = self._jointIndicesAll[index]
if self._jointDofCounts[index] == 4:
force = [
scaling * taus[dofIndex + 0], scaling * taus[dofIndex + 1],
scaling * taus[dofIndex + 2]
]
# print("force[", jointIndex,"]=",force)
self._pybullet_client.setJointMotorControlMultiDof(self._sim_model,
jointIndex,
self._pybullet_client.TORQUE_CONTROL,
force=force)
if self._jointDofCounts[index] == 1:
force = [scaling * taus[dofIndex]]
# print("force[", jointIndex,"]=",force)
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
jointIndex,
controlMode=self._pybullet_client.TORQUE_CONTROL,
force=force)
dofIndex += self._jointDofCounts[index]
def setJointMotors(self, desiredPositions, maxForces, i=0):
controlMode = self._pybullet_client.POSITION_CONTROL
startIndex = 7
chest = 1
neck = 2
rightHip = 3
rightKnee = 4
rightAnkle = 5
rightShoulder = 6
rightElbow = 7
leftHip = 9
leftKnee = 10
leftAnkle = 11
leftShoulder = 12
leftElbow = 13
kp = 0.2
forceScale = 1
# self._jointDofCounts=[4,4,4,1,4,4,1,4,1,4,4,1]
maxForce = [
forceScale * maxForces[startIndex], forceScale * maxForces[startIndex + 1],
forceScale * maxForces[startIndex + 2], forceScale * maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
chest,
controlMode,
targetPosition=self._poseInterpolators[i]._chestRot,
positionGain=kp,
force=maxForce)
maxForce = [
maxForces[startIndex], maxForces[startIndex + 1], maxForces[startIndex + 2],
maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
neck,
controlMode,
targetPosition=self._poseInterpolators[i]._neckRot,
positionGain=kp,
force=maxForce)
maxForce = [
maxForces[startIndex], maxForces[startIndex + 1], maxForces[startIndex + 2],
maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
rightHip,
controlMode,
targetPosition=self._poseInterpolators[i]._rightHipRot,
positionGain=kp,
force=maxForce)
maxForce = [forceScale * maxForces[startIndex]]
startIndex += 1
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
rightKnee,
controlMode,
targetPosition=self._poseInterpolators[i]._rightKneeRot,
positionGain=kp,
force=maxForce)
maxForce = [
maxForces[startIndex], maxForces[startIndex + 1], maxForces[startIndex + 2],
maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
rightAnkle,
controlMode,
targetPosition=self._poseInterpolators[i]._rightAnkleRot,
positionGain=kp,
force=maxForce)
maxForce = [
forceScale * maxForces[startIndex], forceScale * maxForces[startIndex + 1],
forceScale * maxForces[startIndex + 2], forceScale * maxForces[startIndex + 3]
]
startIndex += 4
maxForce = [forceScale * maxForces[startIndex]]
startIndex += 1
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
rightElbow,
controlMode,
targetPosition=self._poseInterpolators[i]._rightElbowRot,
positionGain=kp,
force=maxForce)
maxForce = [
maxForces[startIndex], maxForces[startIndex + 1], maxForces[startIndex + 2],
maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
leftHip,
controlMode,
targetPosition=self._poseInterpolators[i]._leftHipRot,
positionGain=kp,
force=maxForce)
maxForce = [forceScale * maxForces[startIndex]]
startIndex += 1
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
leftKnee,
controlMode,
targetPosition=self._poseInterpolators[i]._leftKneeRot,
positionGain=kp,
force=maxForce)
maxForce = [
maxForces[startIndex], maxForces[startIndex + 1], maxForces[startIndex + 2],
maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
leftAnkle,
controlMode,
targetPosition=self._poseInterpolators[i]._leftAnkleRot,
positionGain=kp,
force=maxForce)
maxForce = [
maxForces[startIndex], maxForces[startIndex + 1], maxForces[startIndex + 2],
maxForces[startIndex + 3]
]
startIndex += 4
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
leftShoulder,
controlMode,
targetPosition=self._poseInterpolators[i]._leftShoulderRot,
positionGain=kp,
force=maxForce)
maxForce = [forceScale * maxForces[startIndex]]
startIndex += 1
self._pybullet_client.setJointMotorControlMultiDof(
self._sim_model,
leftElbow,
controlMode,
targetPosition=self._poseInterpolators[i]._leftElbowRot,
positionGain=kp,
force=maxForce)
# print("startIndex=",startIndex)
def getPhase(self):
keyFrameDuration = self._mocap_data.getKeyFrameDuration()
cycleTime = keyFrameDuration * (self._mocap_data.getNumFrames() - 1)
phase = self._simTime / cycleTime
phase = math.fmod(phase, 1.0)
if (phase < 0):
phase += 1
return phase
def buildHeadingTrans(self, rootOrn):
# align root transform 'forward' with world-space x axis
eul = self._pybullet_client.getEulerFromQuaternion(rootOrn)
refDir = [1, 0, 0]
rotVec = self._pybullet_client.rotateVector(rootOrn, refDir)
heading = math.atan2(-rotVec[2], rotVec[0])
heading2 = eul[1]
# print("heading=",heading)
headingOrn = self._pybullet_client.getQuaternionFromAxisAngle([0, 1, 0], -heading)
return headingOrn
def buildOriginTrans(self):
rootPos, rootOrn = self._pybullet_client.getBasePositionAndOrientation(self._sim_model)
# print("rootPos=",rootPos, " rootOrn=",rootOrn)
invRootPos = [-rootPos[0], 0, -rootPos[2]]
# invOrigTransPos, invOrigTransOrn = self._pybullet_client.invertTransform(rootPos,rootOrn)
headingOrn = self.buildHeadingTrans(rootOrn)
# print("headingOrn=",headingOrn)
headingMat = self._pybullet_client.getMatrixFromQuaternion(headingOrn)
# print("headingMat=",headingMat)
# dummy, rootOrnWithoutHeading = self._pybullet_client.multiplyTransforms([0,0,0],headingOrn, [0,0,0], rootOrn)
# dummy, invOrigTransOrn = self._pybullet_client.multiplyTransforms([0,0,0],rootOrnWithoutHeading, invOrigTransPos, invOrigTransOrn)
invOrigTransPos, invOrigTransOrn = self._pybullet_client.multiplyTransforms([0, 0, 0],
headingOrn,
invRootPos,
[0, 0, 0, 1])
# print("invOrigTransPos=",invOrigTransPos)
# print("invOrigTransOrn=",invOrigTransOrn)
invOrigTransMat = self._pybullet_client.getMatrixFromQuaternion(invOrigTransOrn)
# print("invOrigTransMat =",invOrigTransMat )
return invOrigTransPos, invOrigTransOrn
def getState(self):
stateVector = []
phase = self.getPhase()
# print("phase=",phase)
stateVector.append(phase)
rootTransPos, rootTransOrn = self.buildOriginTrans()
basePos, baseOrn = self._pybullet_client.getBasePositionAndOrientation(self._sim_model)
rootPosRel, dummy = self._pybullet_client.multiplyTransforms(rootTransPos, rootTransOrn,
basePos, [0, 0, 0, 1])
# print("!!!rootPosRel =",rootPosRel )
# print("rootTransPos=",rootTransPos)
# print("basePos=",basePos)
localPos, localOrn = self._pybullet_client.multiplyTransforms(rootTransPos, rootTransOrn,
basePos, baseOrn)
localPos = [
localPos[0] - rootPosRel[0], localPos[1] - rootPosRel[1], localPos[2] - rootPosRel[2]
]
# print("localPos=",localPos)
stateVector.append(rootPosRel[1])
# self.pb2dmJoints=[0,1,2,9,10,11,3,4,5,12,13,14,6,7,8]
self.pb2dmJoints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
linkIndicesSim = []
for pbJoint in range(self._pybullet_client.getNumJoints(self._sim_model)):
linkIndicesSim.append(self.pb2dmJoints[pbJoint])
linkStatesSim = self._pybullet_client.getLinkStates(self._sim_model, linkIndicesSim,
computeForwardKinematics=True, computeLinkVelocity=True)
for pbJoint in range(self._pybullet_client.getNumJoints(self._sim_model)):
j = self.pb2dmJoints[pbJoint]
# print("joint order:",j)
# ls = self._pybullet_client.getLinkState(self._sim_model, j, computeForwardKinematics=True)
ls = linkStatesSim[pbJoint]
linkPos = ls[0]
linkOrn = ls[1]
linkPosLocal, linkOrnLocal = self._pybullet_client.multiplyTransforms(
rootTransPos, rootTransOrn, linkPos, linkOrn)
if (linkOrnLocal[3] < 0):
linkOrnLocal = [-linkOrnLocal[0], -linkOrnLocal[1], -linkOrnLocal[2], -linkOrnLocal[3]]
linkPosLocal = [
linkPosLocal[0] - rootPosRel[0], linkPosLocal[1] - rootPosRel[1],
linkPosLocal[2] - rootPosRel[2]
]
for l in linkPosLocal:
stateVector.append(l)
# re-order the quaternion, DeepMimic uses w,x,y,z
if (linkOrnLocal[3] < 0):
linkOrnLocal[0] *= -1
linkOrnLocal[1] *= -1
linkOrnLocal[2] *= -1
linkOrnLocal[3] *= -1
stateVector.append(linkOrnLocal[3])
stateVector.append(linkOrnLocal[0])
stateVector.append(linkOrnLocal[1])
stateVector.append(linkOrnLocal[2])
for pbJoint in range(self._pybullet_client.getNumJoints(self._sim_model)):
j = self.pb2dmJoints[pbJoint]
# ls = self._pybullet_client.getLinkState(self._sim_model, j, computeLinkVelocity=True)
ls = linkStatesSim[pbJoint]
linkLinVel = ls[6]
linkAngVel = ls[7]
linkLinVelLocal, unused = self._pybullet_client.multiplyTransforms([0, 0, 0], rootTransOrn,
linkLinVel, [0, 0, 0, 1])
# linkLinVelLocal=[linkLinVelLocal[0]-rootPosRel[0],linkLinVelLocal[1]-rootPosRel[1],linkLinVelLocal[2]-rootPosRel[2]]
linkAngVelLocal, unused = self._pybullet_client.multiplyTransforms([0, 0, 0], rootTransOrn,
linkAngVel, [0, 0, 0, 1])
for l in linkLinVelLocal:
stateVector.append(l)
for l in linkAngVelLocal:
stateVector.append(l)
# print("stateVector len=",len(stateVector))
# for st in range (len(stateVector)):
# print("state[",st,"]=",stateVector[st])
return stateVector
def terminates(self):
# check if any non-allowed body part hits the ground
terminates = False
pts = self._pybullet_client.getContactPoints()
for p in pts:
part = -1
# ignore self-collision
if (p[1] == p[2]):
continue
if (p[1] == self._sim_model):
part = p[3]
if (p[2] == self._sim_model):
part = p[4]
if (part >= 0 and part in self._fall_contact_body_parts):
# print("terminating part:", part)
terminates = True
return terminates
def quatMul(self, q1, q2):
return [
q1[3] * q2[0] + q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1],
q1[3] * q2[1] + q1[1] * q2[3] + q1[2] * q2[0] - q1[0] * q2[2],
q1[3] * q2[2] + q1[2] * q2[3] + q1[0] * q2[1] - q1[1] * q2[0],
q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2]
]
def calcRootAngVelErr(self, vel0, vel1):
diff = [vel0[0] - vel1[0], vel0[1] - vel1[1], vel0[2] - vel1[2]]
return diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]
def calcRootRotDiff(self, orn0, orn1):
orn0Conj = [-orn0[0], -orn0[1], -orn0[2], orn0[3]]
q_diff = self.quatMul(orn1, orn0Conj)
axis, angle = self._pybullet_client.getAxisAngleFromQuaternion(q_diff)
return angle * angle
def getReward(self, pose, i=0):
"""Compute and return the pose-based reward."""
# from DeepMimic double cSceneImitate::CalcRewardImitate
# todo: compensate for ground height in some parts, once we move to non-flat terrain
# not values from the paper, but from the published code.
pose_w = 0.5
vel_w = 0.05
end_eff_w = 0.15
# does not exist in paper
root_w = 0.2
if self._useComReward:
com_w = 0.1
else:
com_w = 0
total_w = pose_w + vel_w + end_eff_w + root_w + com_w
pose_w /= total_w
vel_w /= total_w
end_eff_w /= total_w
root_w /= total_w
com_w /= total_w
pose_scale = 2
vel_scale = 0.1
end_eff_scale = 40
root_scale = 5
com_scale = 10
err_scale = 1 # error scale
reward = 0
pose_err = 0
vel_err = 0
end_eff_err = 0
root_err = 0
com_err = 0
heading_err = 0
# create a mimic reward, comparing the dynamics humanoid with a kinematic one
# pose = self.InitializePoseFromMotionData()
# print("self._kin_model=",self._kin_model)
# print("kinematicHumanoid #joints=",self._pybullet_client.getNumJoints(self._kin_model))
# self.ApplyPose(pose, True, True, self._kin_model, self._pybullet_client)
# const Eigen::VectorXd& pose0 = sim_char.GetPose();
# const Eigen::VectorXd& vel0 = sim_char.GetVel();
# const Eigen::VectorXd& pose1 = kin_char.GetPose();
# const Eigen::VectorXd& vel1 = kin_char.GetVel();
# tMatrix origin_trans = sim_char.BuildOriginTrans();
# tMatrix kin_origin_trans = kin_char.BuildOriginTrans();
#
# tVector com0_world = sim_char.CalcCOM();
if self._useComReward:
comSim, comSimVel = self.computeCOMposVel(self._sim_model)
comKin, comKinVel = self.computeCOMposVel(self._kin_models[i])
# tVector com_vel0_world = sim_char.CalcCOMVel();
# tVector com1_world;
# tVector com_vel1_world;
# cRBDUtil::CalcCoM(joint_mat, body_defs, pose1, vel1, com1_world, com_vel1_world);
#
root_id = 0
# tVector root_pos0 = cKinTree::GetRootPos(joint_mat, pose0);
# tVector root_pos1 = cKinTree::GetRootPos(joint_mat, pose1);
# tQuaternion root_rot0 = cKinTree::GetRootRot(joint_mat, pose0);
# tQuaternion root_rot1 = cKinTree::GetRootRot(joint_mat, pose1);
# tVector root_vel0 = cKinTree::GetRootVel(joint_mat, vel0);
# tVector root_vel1 = cKinTree::GetRootVel(joint_mat, vel1);
# tVector root_ang_vel0 = cKinTree::GetRootAngVel(joint_mat, vel0);
# tVector root_ang_vel1 = cKinTree::GetRootAngVel(joint_mat, vel1);
mJointWeights = [
0.20833, 0.10416, 0.0625, 0.10416, 0.0625, 0.041666666666666671, 0.0625, 0.0416, 0.00,
0.10416, 0.0625, 0.0416, 0.0625, 0.0416, 0.0000
]
num_end_effs = 0
num_joints = 15
root_rot_w = mJointWeights[root_id]
rootPosSim, rootOrnSim = self._pybullet_client.getBasePositionAndOrientation(self._sim_model)
rootPosKin, rootOrnKin = self._pybullet_client.getBasePositionAndOrientation(self._kin_models[i])
linVelSim, angVelSim = self._pybullet_client.getBaseVelocity(self._sim_model)
# don't read the velocities from the kinematic model (they are zero), use the pose interpolator velocity
# see also issue https://github.com/bulletphysics/bullet3/issues/2401
linVelKin = self._poseInterpolators[i]._baseLinVel
angVelKin = self._poseInterpolators[i]._baseAngVel
root_rot_err = self.calcRootRotDiff(rootOrnSim, rootOrnKin)
pose_err += root_rot_w * root_rot_err
root_vel_diff = [
linVelSim[0] - linVelKin[0], linVelSim[1] - linVelKin[1], linVelSim[2] - linVelKin[2]
]
root_vel_err = root_vel_diff[0] * root_vel_diff[0] + root_vel_diff[1] * root_vel_diff[
1] + root_vel_diff[2] * root_vel_diff[2]
root_ang_vel_err = self.calcRootAngVelErr(angVelSim, angVelKin)
vel_err += root_rot_w * root_ang_vel_err
useArray = True
if useArray:
jointIndices = range(num_joints)
simJointStates = self._pybullet_client.getJointStatesMultiDof(self._sim_model, jointIndices)
kinJointStates = self._pybullet_client.getJointStatesMultiDof(self._kin_models[i], jointIndices)
linkStatesSim = self._pybullet_client.getLinkStates(self._sim_model, jointIndices)
linkStatesKin = self._pybullet_client.getLinkStates(self._kin_models[i], jointIndices)
for j in range(num_joints):
curr_pose_err = 0
curr_vel_err = 0
w = mJointWeights[j]
if useArray:
simJointInfo = simJointStates[j]
else:
simJointInfo = self._pybullet_client.getJointStateMultiDof(self._sim_model, j)
# print("simJointInfo.pos=",simJointInfo[0])
# print("simJointInfo.vel=",simJointInfo[1])
if useArray:
kinJointInfo = kinJointStates[j]
else:
kinJointInfo = self._pybullet_client.getJointStateMultiDof(self._kin_models[i], j)
# print("kinJointInfo.pos=",kinJointInfo[0])
# print("kinJointInfo.vel=",kinJointInfo[1])
if (len(simJointInfo[0]) == 1):
angle = simJointInfo[0][0] - kinJointInfo[0][0]
curr_pose_err = angle * angle
velDiff = simJointInfo[1][0] - kinJointInfo[1][0]
curr_vel_err = velDiff * velDiff
if (len(simJointInfo[0]) == 4):
# print("quaternion diff")
diffQuat = self._pybullet_client.getDifferenceQuaternion(simJointInfo[0], kinJointInfo[0])
axis, angle = self._pybullet_client.getAxisAngleFromQuaternion(diffQuat)
curr_pose_err = angle * angle
diffVel = [
simJointInfo[1][0] - kinJointInfo[1][0], simJointInfo[1][1] - kinJointInfo[1][1],
simJointInfo[1][2] - kinJointInfo[1][2]
]
curr_vel_err = diffVel[0] * diffVel[0] + diffVel[1] * diffVel[1] + diffVel[2] * diffVel[2]
pose_err += w * curr_pose_err
vel_err += w * curr_vel_err
is_end_eff = j in self._end_effectors
if is_end_eff:
if useArray:
linkStateSim = linkStatesSim[j]
linkStateKin = linkStatesKin[j]
else:
linkStateSim = self._pybullet_client.getLinkState(self._sim_model, j)
linkStateKin = self._pybullet_client.getLinkState(self._kin_models[i], j)
linkPosSim = linkStateSim[0]
linkPosKin = linkStateKin[0]
linkPosDiff = [
linkPosSim[0] - linkPosKin[0], linkPosSim[1] - linkPosKin[1],
linkPosSim[2] - linkPosKin[2]
]
curr_end_err = linkPosDiff[0] * linkPosDiff[0] + linkPosDiff[1] * linkPosDiff[
1] + linkPosDiff[2] * linkPosDiff[2]
end_eff_err += curr_end_err
num_end_effs += 1
if (num_end_effs > 0):
end_eff_err /= num_end_effs
# double root_ground_h0 = mGround->SampleHeight(sim_char.GetRootPos())
# double root_ground_h1 = kin_char.GetOriginPos()[1]
# root_pos0[1] -= root_ground_h0
# root_pos1[1] -= root_ground_h1
root_pos_diff = [
rootPosSim[0] - rootPosKin[0], rootPosSim[1] - rootPosKin[1], rootPosSim[2] - rootPosKin[2]
]
root_pos_err = root_pos_diff[0] * root_pos_diff[0] + root_pos_diff[1] * root_pos_diff[
1] + root_pos_diff[2] * root_pos_diff[2]
#
# root_rot_err = cMathUtil::QuatDiffTheta(root_rot0, root_rot1)
# root_rot_err *= root_rot_err
# root_vel_err = (root_vel1 - root_vel0).squaredNorm()
# root_ang_vel_err = (root_ang_vel1 - root_ang_vel0).squaredNorm()
root_err = root_pos_err + 0.1 * root_rot_err + 0.01 * root_vel_err + 0.001 * root_ang_vel_err
# COM error in initial code -> COM velocities
if self._useComReward:
com_err = 0.1 * np.sum(np.square(comKinVel - comSimVel))
# com_err = 0.1 * np.sum(np.square(comKin - comSim))
# com_err = 0.1 * (com_vel1_world - com_vel0_world).squaredNorm()
# print("pose_err=",pose_err)
# print("vel_err=",vel_err)
pose_reward = math.exp(-err_scale * pose_scale * pose_err)
vel_reward = math.exp(-err_scale * vel_scale * vel_err)
end_eff_reward = math.exp(-err_scale * end_eff_scale * end_eff_err)
root_reward = math.exp(-err_scale * root_scale * root_err)
com_reward = math.exp(-err_scale * com_scale * com_err)
reward = pose_w * pose_reward + vel_w * vel_reward + end_eff_w * end_eff_reward + root_w * root_reward + com_w * com_reward
# pose_reward,vel_reward,end_eff_reward, root_reward, com_reward);
# print("reward=",reward)
# print("pose_reward=",pose_reward)
# print("vel_reward=",vel_reward)
# print("end_eff_reward=",end_eff_reward)
# print("root_reward=",root_reward)
# print("com_reward=",com_reward)
info_rew = dict(
pose_reward=pose_reward,
vel_reward=vel_reward,
end_eff_reward=end_eff_reward,
root_reward=root_reward,
com_reward=com_reward
)
info_errs = dict(
pose_err=pose_err,
vel_err=vel_err,
end_eff_err=end_eff_err,
root_err=root_err,
com_err=com_err
)
return reward
def computeCOMposVel(self, uid: int):
"""Compute center-of-mass position and velocity."""
pb = self._pybullet_client
num_joints = 15
jointIndices = range(num_joints)
link_states = pb.getLinkStates(uid, jointIndices, computeLinkVelocity=1)
link_pos = np.array([s[0] for s in link_states])
link_vel = np.array([s[-2] for s in link_states])
tot_mass = 0.
masses = []
for j in jointIndices:
mass_, *_ = pb.getDynamicsInfo(uid, j)
masses.append(mass_)
tot_mass += mass_
masses = np.asarray(masses)[:, None]
com_pos = np.sum(masses * link_pos, axis=0) / tot_mass
com_vel = np.sum(masses * link_vel, axis=0) / tot_mass
return com_pos, com_vel

View File

@ -0,0 +1,239 @@
import json
import math
import random
import numpy as np
from os import listdir
from os.path import isfile, join
from scipy.spatial.transform import Rotation as R
from scipy.spatial.transform import Slerp
class MotionCaptureDataMultiClip(object):
def __init__(self):
self.Reset()
def Reset(self):
self._motion_data = {}
self._num_frames_min = 9999
self._num_frames_max = -1
self._num_clips = -1
self._names = []
def Load(self, path):
if isfile(path):
files = [path]
else:
files = [join(path, f) for f in listdir(path) if isfile(join(path, f))]
for i in range(len(files)):
with open(files[i], 'r') as f:
self._names.append(files[i].split('/')[-1])
self._motion_data[i] = json.load(f)
t = len(self._motion_data[i]['Frames'])
self._num_frames_min = min(t, self._num_frames_min)
self._num_frames_max = max(t, self._num_frames_max)
self._num_clips = len(self._motion_data)
downsample = False
if downsample:
self.downsampleClips()
else:
self.upsampleClips()
def getNumFrames(self):
return self._num_frames_min
def getKeyFrameDuration(self, id=0):
return self._motion_data[id]['Frames'][0][0]
def getCycleTime(self):
keyFrameDuration = self.getKeyFrameDuration()
cycleTime = keyFrameDuration * (self.getNumFrames() - 1)
return cycleTime
def calcCycleCount(self, simTime, cycleTime):
phases = simTime / cycleTime
count = math.floor(phases)
return count
def computeCycleOffset(self, id=0):
lastFrame = self.getNumFrames() - 1
frameData = self._motion_data[id]['Frames'][0]
frameDataNext = self._motion_data[id]['Frames'][lastFrame]
basePosStart = [frameData[1], frameData[2], frameData[3]]
basePosEnd = [frameDataNext[1], frameDataNext[2], frameDataNext[3]]
self._cycleOffset = [
basePosEnd[0] - basePosStart[0], basePosEnd[1] - basePosStart[1],
basePosEnd[2] - basePosStart[2]
]
return self._cycleOffset
def getNumClips(self):
return self._num_clips
def downsampleClips(self):
for i in range(self._num_clips):
n_frames = len(self._motion_data[i]['Frames'])
if n_frames != self._num_frames_min:
sample = random.sample(range(n_frames), self._num_frames_min)
sample.sort()
downsampled = np.array(self._motion_data[i]['Frames'])[sample]
self._motion_data[i]['Frames'] = downsampled.tolist()
#s = json.dumps(self._motion_data[i])
#with open("output/{}".format(self._names[i]), 'w') as f:
# f.writelines(s)
def upsampleClips(self):
print("Max number of frames: ", self._num_frames_max)
for i in range(self._num_clips):
print("Uspsampling clip number: ", i)
keyframe_duration = self.getKeyFrameDuration(i)
old_times = np.arange(0, len(self._motion_data[i]['Frames']) * keyframe_duration, keyframe_duration)
while len(old_times) < self._num_frames_max:
new_times, new_vals = self.slerpSingleClip(self._motion_data[i]['Frames'], old_times)
#print("Number of final frames: ", len(new_vals))
self._motion_data[i]['Frames'] = new_vals
old_times = new_times
#s = json.dumps(self._motion_data[i])
#with open("output/{}".format(self._names[i]), 'w') as f:
# f.writelines(s)
self._num_frames_min = self._num_frames_max
def slerpSingleClip(self, clip, key_times):
print("Number of initial frames: ", len(key_times))
dict_clip = self.extractQuaternions(clip)
dict_clip = np.asarray(dict_clip)
t = dict_clip[:, 0]
root_pos = dict_clip[:, 1]
key_rots = dict_clip[:, 2]
n_frames = len(key_rots)
assert len(key_times) == n_frames
needed_frames = self._num_frames_max - n_frames
print("Needed frames: ", needed_frames)
inter_times = self.calc_inter_times(key_times)
inter_times = sorted(random.sample(inter_times, min(len(inter_times), needed_frames)))
print("Number of frames to interpolate: ", len(inter_times))
print("Number of rots: ", len(key_rots[0]))
inter_joint = []
for i in range(len(key_rots[0])):
quats = [rot[i] for rot in key_rots]
if len(quats[0]) == 4:
joint = R.from_quat(quats)
slerp = Slerp(key_times, joint)
interp_rots = slerp(inter_times)
interp_rots = interp_rots.as_quat().tolist()
else:
interp_rots = []
for tim in range(len(inter_times)):
lb = key_times.tolist().index(max([st for st in key_times if st < inter_times[tim]]))
ub = lb + 1
#print(lb, ub)
new_rot = (quats[ub][0] + quats[lb][0])/2
interp_rots.append([new_rot])
inter_joint.append(interp_rots)
inter_joint = np.array(inter_joint).T
#print("Shape of interpolated joints: ", inter_joint.shape)
old_dict = dict(zip(key_times, key_rots))
new_dict = dict(zip(inter_times, inter_joint))
old_root_pos = dict(zip(key_times, root_pos))
inter_root_pos = self.calc_inter_root_pos(root_pos, key_times, inter_times)
new_root_pos = dict(zip(inter_times, inter_root_pos))
new_dict = {**old_dict, **new_dict}
new_rp_dict = {**old_root_pos, **new_root_pos}
ord_keys = sorted(new_dict.keys())
ord_rots = [new_dict[k] for k in ord_keys]
ord_root_pos = [new_rp_dict[k] for k in ord_keys]
new_clip = self.insertClip(t, ord_root_pos, ord_rots)
return np.array(ord_keys), new_clip
def extractQuaternions(self, clip):
new_clips = []
for c in clip:
t = c[0]
root_pos = c[1:4]
root_rotation = c[4:8]
chest_rotation = c[8:12]
neck_rotation = c[12:16]
right_hip_rotation = c[16:20]
right_knee_rotation = c[20]
right_ankle_rotation = c[21:25]
right_shoulder_rotation = c[25:29]
right_elbow_rotation = c[29]
left_hip_rotation = c[30:34]
left_knee_rotation = c[34]
left_ankle_rotation = c[35:39]
left_shoulder_rotation = c[39:43]
left_elbow_rotation = c[43]
d = [
t,
root_pos,
[
self.deepmimic_to_scipy_quaternion(root_rotation),
self.deepmimic_to_scipy_quaternion(chest_rotation),
self.deepmimic_to_scipy_quaternion(neck_rotation),
self.deepmimic_to_scipy_quaternion(right_hip_rotation),
[right_knee_rotation],
self.deepmimic_to_scipy_quaternion(right_ankle_rotation),
self.deepmimic_to_scipy_quaternion(right_shoulder_rotation),
[right_elbow_rotation],
self.deepmimic_to_scipy_quaternion(left_hip_rotation),
[left_knee_rotation],
self.deepmimic_to_scipy_quaternion(left_ankle_rotation),
self.deepmimic_to_scipy_quaternion(left_shoulder_rotation),
[left_elbow_rotation]
]
]
new_clips.append(d)
return new_clips
def deepmimic_to_scipy_quaternion(self, quat):
return quat[1:] + [quat[0]]
def scipy_to_deepmimic_quaternion(self, quat):
return [quat[-1]] + quat[:-1]
def calc_inter_times(self, times, method="intermediate"):
if method == "intermediate":
inter_times = []
for i in range(1, len(times)):
it = (times[i] - times[i-1])/2 + times[i-1]
inter_times.append(it)
return inter_times
def calc_inter_root_pos(self, root_pos, times, inter_times):
inter_root_pos = []
all_times = sorted([*times.tolist(), *inter_times])
for i in range(len(inter_times)):
low_index = times.tolist().index(all_times[all_times.index(inter_times[i]) - 1])
up_index = times.tolist().index(all_times[all_times.index(inter_times[i]) + 1])
assert low_index == up_index - 1
inter_root_pos.append(((np.array(root_pos[up_index]) + np.array(root_pos[low_index]))/2).tolist())
return inter_root_pos
def insertClip(self, t, ord_root_pos, ord_rots):
delta_t = t[0]
new_quats = self.insertQuaternions(ord_rots)
a = []
for i in range(len(ord_root_pos)):
rot = new_quats[i]
a.append([
delta_t,
*ord_root_pos[i],
*rot
])
return a
def insertQuaternions(self, rotations):
quats = []
for rot in rotations:
rots = []
for r in rot:
if len(r) == 4:
r = self.scipy_to_deepmimic_quaternion(r)
rots += [el for el in r]
quats.append(rots)
return quats

View File

@ -0,0 +1,358 @@
import numpy as np
import math
from pybullet_envs.deep_mimic.env.env import Env
from pybullet_envs.deep_mimic.env.action_space import ActionSpace
from pybullet_utils import bullet_client
import time
from pybullet_envs.deep_mimic.env import motion_capture_data_multiclip
from pybullet_envs.deep_mimic.env import humanoid_stable_pd_multiclip
import pybullet_data
import pybullet as p1
import random
from enum import Enum
class InitializationStrategy(Enum):
"""Set how the environment is initialized."""
START = 0
RANDOM = 1 # random state initialization (RSI)
class PyBulletDeepMimicEnvMultiClip(Env):
def __init__(self, arg_parser=None, enable_draw=False, pybullet_client=None,
time_step=1. / 240,
init_strategy=InitializationStrategy.RANDOM):
super().__init__(arg_parser, enable_draw)
self._num_agents = 1
self._pybullet_client = pybullet_client
self._isInitialized = False
self._useStablePD = True
self._arg_parser = arg_parser
self.timeStep = time_step
self._init_strategy = init_strategy
self._n_clips = -1
print("Initialization strategy: {:s}".format(init_strategy))
self.reset()
def reset(self):
if not self._isInitialized:
if self.enable_draw:
self._pybullet_client = bullet_client.BulletClient(connection_mode=p1.GUI)
# disable 'GUI' since it slows down a lot on Mac OSX and some other platforms
self._pybullet_client.configureDebugVisualizer(self._pybullet_client.COV_ENABLE_GUI, 0)
else:
self._pybullet_client = bullet_client.BulletClient()
self._pybullet_client.setAdditionalSearchPath(pybullet_data.getDataPath())
z2y = self._pybullet_client.getQuaternionFromEuler([-math.pi * 0.5, 0, 0])
self._planeId = self._pybullet_client.loadURDF("plane_implicit.urdf", [0, 0, 0],
z2y,
useMaximalCoordinates=True)
# print("planeId=",self._planeId)
self._pybullet_client.configureDebugVisualizer(self._pybullet_client.COV_ENABLE_Y_AXIS_UP, 1)
self._pybullet_client.setGravity(0, -9.8, 0)
self._pybullet_client.setPhysicsEngineParameter(numSolverIterations=10)
self._pybullet_client.changeDynamics(self._planeId, linkIndex=-1, lateralFriction=0.9)
self._mocapData = motion_capture_data_multiclip.MotionCaptureDataMultiClip()
motion_file = self._arg_parser.parse_strings('motion_file')
print("motion_file=", motion_file[0])
motionPath = pybullet_data.getDataPath() + "/" + motion_file[0]
# motionPath = pybullet_data.getDataPath()+"/motions/humanoid3d_backflip.txt"
self._mocapData.Load(motionPath)
self._n_clips = self._mocapData.getNumClips()
timeStep = self.timeStep
useFixedBase = False
self._humanoid = humanoid_stable_pd_multiclip.HumanoidStablePDMultiClip(self._pybullet_client, self._mocapData,
timeStep, useFixedBase, self._arg_parser)
self._isInitialized = True
self._pybullet_client.setTimeStep(timeStep)
self._pybullet_client.setPhysicsEngineParameter(numSubSteps=1)
selfCheck = False
if (selfCheck):
curTime = 0
while self._pybullet_client.isConnected():
self._humanoid.setSimTime(curTime)
state = self._humanoid.getState()
# print("state=",state)
# pose = self._humanoid.computePose(self._humanoid._frameFraction) this would need an id
for i in range(10):
curTime += timeStep
# taus = self._humanoid.computePDForces(pose)
# self._humanoid.applyPDForces(taus)
# self._pybullet_client.stepSimulation()
time.sleep(timeStep)
# print("numframes = ", self._humanoid._mocap_data.NumFrames())
# startTime = random.randint(0,self._humanoid._mocap_data.NumFrames()-2)
if self._init_strategy == InitializationStrategy.RANDOM:
rnrange = 1000
rn = random.randint(0, rnrange)
startTime = float(rn) / rnrange * self._humanoid.getCycleTime()
elif self._init_strategy == InitializationStrategy.START:
startTime = 0
self.t = startTime
self._humanoid.setSimTime(startTime)
self._humanoid.resetPose()
# this clears the contact points. Todo: add API to explicitly clear all contact points?
# self._pybullet_client.stepSimulation()
self._humanoid.resetPose()
self.needs_update_time = self.t - 1 # force update
def get_num_agents(self):
return self._num_agents
def get_action_space(self, agent_id):
return ActionSpace(ActionSpace.Continuous)
def get_reward_min(self, agent_id):
return 0
def get_reward_max(self, agent_id):
return 1
def get_reward_fail(self, agent_id):
return self.get_reward_min(agent_id)
def get_reward_succ(self, agent_id):
return self.get_reward_max(agent_id)
# scene_name == "imitate" -> cDrawSceneImitate
def get_state_size(self, agent_id):
# cCtController::GetStateSize()
# int state_size = cDeepMimicCharController::GetStateSize();
# state_size += GetStatePoseSize();#106
# state_size += GetStateVelSize(); #(3+3)*numBodyParts=90
# state_size += GetStatePhaseSize();#1
# 197
return 197
def build_state_norm_groups(self, agent_id):
# if (mEnablePhaseInput)
# {
# int phase_group = gNormGroupNone;
# int phase_offset = GetStatePhaseOffset();
# int phase_size = GetStatePhaseSize();
# out_groups.segment(phase_offset, phase_size) = phase_group * Eigen::VectorXi::Ones(phase_size);
groups = [0] * self.get_state_size(agent_id)
groups[0] = -1
return groups
def build_state_offset(self, agent_id):
out_offset = [0] * self.get_state_size(agent_id)
phase_offset = -0.5
out_offset[0] = phase_offset
return np.array(out_offset)
def build_state_scale(self, agent_id):
out_scale = [1] * self.get_state_size(agent_id)
phase_scale = 2
out_scale[0] = phase_scale
return np.array(out_scale)
def get_goal_size(self, agent_id):
return 0
def get_action_size(self, agent_id):
ctrl_size = 43 # numDof
root_size = 7
return ctrl_size - root_size
def build_goal_norm_groups(self, agent_id):
return np.array([])
def build_goal_offset(self, agent_id):
return np.array([])
def build_goal_scale(self, agent_id):
return np.array([])
def build_action_offset(self, agent_id):
out_offset = [0] * self.get_action_size(agent_id)
out_offset = [
0.0000000000, 0.0000000000, 0.0000000000, -0.200000000, 0.0000000000, 0.0000000000,
0.0000000000, -0.200000000, 0.0000000000, 0.0000000000, 0.00000000, -0.2000000, 1.57000000,
0.00000000, 0.00000000, 0.00000000, -0.2000000, 0.00000000, 0.00000000, 0.00000000,
-0.2000000, -1.5700000, 0.00000000, 0.00000000, 0.00000000, -0.2000000, 1.57000000,
0.00000000, 0.00000000, 0.00000000, -0.2000000, 0.00000000, 0.00000000, 0.00000000,
-0.2000000, -1.5700000
]
# see cCtCtrlUtil::BuildOffsetScalePDPrismatic and
# see cCtCtrlUtil::BuildOffsetScalePDSpherical
return np.array(out_offset)
def build_action_scale(self, agent_id):
out_scale = [1] * self.get_action_size(agent_id)
# see cCtCtrlUtil::BuildOffsetScalePDPrismatic and
# see cCtCtrlUtil::BuildOffsetScalePDSpherical
out_scale = [
0.20833333333333, 1.00000000000000, 1.00000000000000, 1.00000000000000, 0.25000000000000,
1.00000000000000, 1.00000000000000, 1.00000000000000, 0.12077294685990, 1.00000000000000,
1.000000000000, 1.000000000000, 0.159235668789, 0.159235668789, 1.000000000000,
1.000000000000, 1.000000000000, 0.079617834394, 1.000000000000, 1.000000000000,
1.000000000000, 0.159235668789, 0.120772946859, 1.000000000000, 1.000000000000,
1.000000000000, 0.159235668789, 0.159235668789, 1.000000000000, 1.000000000000,
1.000000000000, 0.107758620689, 1.000000000000, 1.000000000000, 1.000000000000,
0.159235668789
]
return np.array(out_scale)
def build_action_bound_min(self, agent_id):
# see cCtCtrlUtil::BuildBoundsPDSpherical
out_scale = [-1] * self.get_action_size(agent_id)
out_scale = [
-4.79999999999, -1.00000000000, -1.00000000000, -1.00000000000, -4.00000000000,
-1.00000000000, -1.00000000000, -1.00000000000, -7.77999999999, -1.00000000000,
-1.000000000, -1.000000000, -7.850000000, -6.280000000, -1.000000000, -1.000000000,
-1.000000000, -12.56000000, -1.000000000, -1.000000000, -1.000000000, -4.710000000,
-7.779999999, -1.000000000, -1.000000000, -1.000000000, -7.850000000, -6.280000000,
-1.000000000, -1.000000000, -1.000000000, -8.460000000, -1.000000000, -1.000000000,
-1.000000000, -4.710000000
]
return out_scale
def build_action_bound_max(self, agent_id):
out_scale = [1] * self.get_action_size(agent_id)
out_scale = [
4.799999999, 1.000000000, 1.000000000, 1.000000000, 4.000000000, 1.000000000, 1.000000000,
1.000000000, 8.779999999, 1.000000000, 1.0000000, 1.0000000, 4.7100000, 6.2800000,
1.0000000, 1.0000000, 1.0000000, 12.560000, 1.0000000, 1.0000000, 1.0000000, 7.8500000,
8.7799999, 1.0000000, 1.0000000, 1.0000000, 4.7100000, 6.2800000, 1.0000000, 1.0000000,
1.0000000, 10.100000, 1.0000000, 1.0000000, 1.0000000, 7.8500000
]
return out_scale
def set_mode(self, mode):
self._mode = mode
def need_new_action(self, agent_id):
if self.t >= self.needs_update_time:
self.needs_update_time = self.t + 1. / 30.
return True
return False
def record_state(self, agent_id):
state = self._humanoid.getState()
return np.array(state)
def record_goal(self, agent_id):
return np.array([])
def calc_reward(self, agent_id):
rewards = {}
for i in range(self._n_clips):
kinPose = self._humanoid.computePose(self._humanoid._frameFraction, i)
rewards[i] = self._humanoid.getReward(kinPose, i)
reward = self.select_reward(rewards)
return reward
def set_action(self, agent_id, action):
# print("action=",)
# for a in action:
# print(a)
# np.savetxt("pb_action.csv", action, delimiter=",")
self.desiredPose = {} # TODO: is this necessary???
for i in range(self._n_clips):
self.desiredPose[i] = self._humanoid.convertActionToPose(action, i)
# we need the target root positon and orientation to be zero, to be compatible with deep mimic
self.desiredPose[i][0] = 0
self.desiredPose[i][1] = 0
self.desiredPose[i][2] = 0
self.desiredPose[i][3] = 0
self.desiredPose[i][4] = 0
self.desiredPose[i][5] = 0
self.desiredPose[i][6] = 0
target_pose = np.array(self.desiredPose[i])
# np.savetxt("pb_target_pose.csv", target_pose, delimiter=",")
# print("set_action: desiredPose=", self.desiredPose)
def log_val(self, agent_id, val):
pass
def update(self, timeStep):
# print("pybullet_deep_mimic_env:update timeStep=",timeStep," t=",self.t)
self._pybullet_client.setTimeStep(timeStep)
self._humanoid._timeStep = timeStep
self.timeStep = timeStep
for j in range(1):
self.t += timeStep
self._humanoid.setSimTime(self.t)
if self.desiredPose:
for i in range(self._n_clips):
kinPose = self._humanoid.computePose(self._humanoid._frameFraction, i)
self._humanoid.initializePose(self._humanoid._poseInterpolators[i],
self._humanoid._kin_models[i],
initBase=True)
# pos,orn=self._pybullet_client.getBasePositionAndOrientation(self._humanoid._sim_model)
# self._pybullet_client.resetBasePositionAndOrientation(self._humanoid._kin_model, [pos[0]+3,pos[1],pos[2]],orn)
# print("desiredPositions=",self.desiredPose[i])
maxForces = [
0, 0, 0, 0, 0, 0, 0, 200, 200, 200, 200, 50, 50, 50, 50, 200, 200, 200, 200, 150, 90,
90, 90, 90, 100, 100, 100, 100, 60, 200, 200, 200, 200, 150, 90, 90, 90, 90, 100, 100,
100, 100, 60
]
if self._useStablePD:
usePythonStablePD = False
if usePythonStablePD:
taus = self._humanoid.computePDForces(self.desiredPose[0], # TODO: check if correct
desiredVelocities=None,
maxForces=maxForces)
# taus = [0]*43
self._humanoid.applyPDForces(taus)
else:
self._humanoid.computeAndApplyPDForces(self.desiredPose[0],
maxForces=maxForces)
else:
self._humanoid.setJointMotors(self.desiredPose[0], maxForces=maxForces, i=0)
self._pybullet_client.stepSimulation()
def set_sample_count(self, count):
return
def check_terminate(self, agent_id):
return Env.Terminate(self.is_episode_end())
def is_episode_end(self):
isEnded = self._humanoid.terminates()
# also check maximum time, 20 seconds (todo get from file)
# print("self.t=",self.t)
if (self.t > 20):
isEnded = True
return isEnded
def check_valid_episode(self):
# could check if limbs exceed velocity threshold
return True
def getKeyboardEvents(self):
return self._pybullet_client.getKeyboardEvents()
def isKeyTriggered(self, keys, key):
o = ord(key)
# print("ord=",o)
if o in keys:
return keys[ord(key)] & self._pybullet_client.KEY_WAS_TRIGGERED
return False
def select_reward(self, rewards, criterion=None):
# todo create enum for criterion
return max(rewards.values())

View File

@ -0,0 +1,25 @@
import sys
import subprocess
from pybullet_utils.arg_parser import ArgParser
from pybullet_utils.logger import Logger
def main():
# Command line arguments
args = sys.argv[1:]
arg_parser = ArgParser()
arg_parser.load_args(args)
num_workers = arg_parser.parse_int('num_workers', 1)
assert (num_workers > 0)
Logger.print2('Running with {:d} workers'.format(num_workers))
cmd = 'mpiexec -n {:d} python3 DeepMimic_Optimizer_multiclip.py '.format(num_workers)
cmd += ' '.join(args)
Logger.print2('cmd: ' + cmd)
subprocess.call(cmd, shell=True)
return
if __name__ == '__main__':
main()

View File

@ -0,0 +1,112 @@
import time
import os
import inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(os.path.dirname(currentdir))
os.sys.path.insert(0, parentdir)
print("parentdir=", parentdir)
import json
from pybullet_envs.deep_mimic.learning.rl_world import RLWorld
from pybullet_envs.deep_mimic.learning.ppo_agent import PPOAgent
import pybullet_data
from pybullet_utils.arg_parser import ArgParser
from pybullet_utils.logger import Logger
from pybullet_envs.deep_mimic.env.pybullet_deep_mimic_env_multiclip import PyBulletDeepMimicEnvMultiClip
import sys
import random
update_timestep = 1. / 240.
animating = True
step = False
total_reward = 0
steps = 0
def update_world(world, time_elapsed):
timeStep = update_timestep
world.update(timeStep)
reward = world.env.calc_reward(agent_id=0)
global total_reward
total_reward += reward
global steps
steps += 1
end_episode = world.env.is_episode_end()
if (end_episode or steps >= 1000):
print("total_reward=", total_reward)
total_reward = 0
steps = 0
world.end_episode()
world.reset()
def build_arg_parser(args):
arg_parser = ArgParser()
arg_parser.load_args(args)
arg_file = arg_parser.parse_string('arg_file', '')
if arg_file == '':
arg_file = "run_humanoid3d_backflip_args.txt"
if (arg_file != ''):
path = pybullet_data.getDataPath() + "/args/" + arg_file
if os.path.isfile(path):
succ = arg_parser.load_file(path)
else:
files = [arg_parser.load_file(f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
succ = all(files)
Logger.print2(arg_file)
assert succ, Logger.print2('Failed to load args from: ' + arg_file)
return arg_parser
args = sys.argv[1:]
def build_world(args, enable_draw):
arg_parser = build_arg_parser(args)
print("enable_draw=", enable_draw)
env = PyBulletDeepMimicEnvMultiClip(arg_parser, enable_draw)
world = RLWorld(env, arg_parser)
motion_file = arg_parser.parse_string("motion_file")
print("motion_file=", motion_file)
bodies = arg_parser.parse_ints("fall_contact_bodies")
print("bodies=", bodies)
int_output_path = arg_parser.parse_string("int_output_path")
print("int_output_path=", int_output_path)
agent_files = pybullet_data.getDataPath() + "/" + arg_parser.parse_string("agent_files")
AGENT_TYPE_KEY = "AgentType"
print("agent_file=", agent_files)
with open(agent_files) as data_file:
json_data = json.load(data_file)
print("json_data=", json_data)
assert AGENT_TYPE_KEY in json_data
agent_type = json_data[AGENT_TYPE_KEY]
print("agent_type=", agent_type)
agent = PPOAgent(world, id, json_data)
agent.set_enable_training(False)
world.reset()
return world
if __name__ == '__main__':
world = build_world(args, True)
while (world.env._pybullet_client.isConnected()):
timeStep = update_timestep
time.sleep(timeStep)
keys = world.env.getKeyboardEvents()
if world.env.isKeyTriggered(keys, ' '):
animating = not animating
if world.env.isKeyTriggered(keys, 'i'):
step = True
if (animating or step):
update_world(world, timeStep)
step = False