Skip to content

Commit

Permalink
added new actuators to MyoSkeleton.
Browse files Browse the repository at this point in the history
- also added missing myomodel init module.
  • Loading branch information
robfiras committed Sep 10, 2024
1 parent 2fc1907 commit 6e2a08a
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 6 deletions.
2 changes: 1 addition & 1 deletion examples/simple_mushroom_env/example_myoskeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
if i == 1000 or absorbing:
env.reset()
i = 0
action = np.random.randn(action_dim) * 0.1
action = np.random.randn(action_dim)
nstate, _, absorbing, _ = env.step(action)

env.render()
Expand Down
107 changes: 102 additions & 5 deletions loco_mujoco/environments/humanoids/myoskeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,16 +1407,113 @@ def _add_actuators(xml_handle):
"""
Adds a generic actuator to each joint.
.. note:: Forces generated by the actuators are not realistic. These are preliminary actuators added for testing.
"""
max_joint_forces = dict(L5_S1_Flex_Ext=200,
L5_S1_Lat_Bending=200,
L5_S1_axial_rotation=200,
L4_L5_Flex_Ext=200,
L4_L5_Lat_Bending=200,
L4_L5_axial_rotation=200,
L3_L4_Flex_Ext=200,
L3_L4_Lat_Bending=200,
L3_L4_axial_rotation=200,
L2_L3_Flex_Ext=200,
L2_L3_Lat_Bending=200,
L2_L3_axial_rotation=200,
L1_L2_Flex_Ext=200,
L1_L2_Lat_Bending=200,
L1_L2_axial_rotation=200,
L1_T12_Flex_Ext=200,
L1_T12_Lat_Bending=200,
L1_T12_axial_rotation=200,
c7_c6_FE=50,
c7_c6_LB=50,
c7_c6_AR=50,
c6_c5_FE=50,
c6_c5_LB=50,
c6_c5_AR=50,
c5_c4_FE=50,
c5_c4_LB=50,
c5_c4_AR=50,
c4_c3_FE=50,
c4_c3_LB=50,
c4_c3_AR=50,
c3_c2_FE=50,
c3_c2_LB=50,
c3_c2_AR=50,
c2_c1_FE=50,
c2_c1_LB=50,
c2_c1_AR=50,
c1_skull_FE=50,
c1_skull_LB=50,
c1_skull_AR=50,
skull_FE=50,
skull_LB=50,
skull_AR=50,
sternoclavicular_r2_r=80,
sternoclavicular_r3_r=80,
unrotscap_r3_r=80,
unrotscap_r2_r=80,
acromioclavicular_r2_r=80,
acromioclavicular_r3_r=80,
acromioclavicular_r1_r=80,
unrothum_r1_r=80,
unrothum_r3_r=80,
unrothum_r2_r=80,
elv_angle_r=80,
shoulder_elv_r=80,
shoulder1_r2_r=80,
shoulder_rot_r=80,
elbow_flex_r=80,
pro_sup=80,
deviation=80,
flexion_r=80,
sternoclavicular_r2_l=80,
sternoclavicular_r3_l=80,
unrotscap_r3_l=80,
unrotscap_r2_l=80,
acromioclavicular_r2_l=80,
acromioclavicular_r3_l=80,
acromioclavicular_r1_l=80,
unrothum_r1_l=80,
unrothum_r3_l=80,
unrothum_r2_l=80,
elv_angle_l=80,
shoulder_elv_l=80,
shoulder1_r2_l=80,
shoulder_rot_l=80,
elbow_flex_l=80,
pro_sup_l=80,
deviation_l=80,
flexion_l=80,
hip_flexion_r=200,
hip_adduction_r=200,
hip_rotation_r=200,
knee_angle_r=200,
knee_angle_r_rotation2=20,
knee_angle_r_rotation3=20,
ankle_angle_r=200,
subtalar_angle_r=200,
mtp_angle_r=200,
knee_angle_r_beta_rotation1=20,
hip_flexion_l=200,
hip_adduction_l=200,
hip_rotation_l=200,
knee_angle_l=200,
knee_angle_l_rotation2=20,
knee_angle_l_rotation3=20,
ankle_angle_l=200,
subtalar_angle_l=200,
mtp_angle_l=200,
knee_angle_l_beta_rotation1=20)

joints = xml_handle.find_all("joint")
for joint in joints:
# add an actuator for every joint except the pelvis
if "pelvis" not in joint.name:
xml_handle.actuator.add("general", name="act_" + joint.name, ctrllimited=True, ctrlrange=[-1.0, 1.0],
forcerange=[-250, 250], joint=joint.name, gaintype="fixed", biastype="affine",
gainprm=[500.0], biasprm=[0.0, -250.0, 0.0])
max_force = max_joint_forces[joint.name] if joint.name in max_joint_forces.keys() else 50
xml_handle.actuator.add("general", name="act_" + joint.name, joint=joint.name,
ctrlrange=[-max_force, max_force], ctrllimited=True)
return xml_handle

@staticmethod
Expand Down
99 changes: 99 additions & 0 deletions loco_mujoco/utils/myomodel_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import os
import shutil
from os.path import expanduser
import git
from pathlib import Path

import loco_mujoco


data_dir = Path(loco_mujoco.__file__).resolve().parent / "environments" / "data"


def fetch_git(repo_url, commit_hash, clone_directory, clone_path):
"""
fetch git repo using provided details
"""

clone_directory = os.path.join(clone_path, clone_directory)

try:
# Create the clone directory if it doesn't exist
os.makedirs(clone_directory, exist_ok=True)

# Clone the repository to the specified path
if not os.path.exists(os.path.join(clone_directory, '.git')):
repo = git.Repo.clone_from(repo_url, clone_directory)
print(f"{repo_url} cloned at {clone_directory}")
else:
repo = git.Repo(clone_directory)
origin = repo.remote('origin')
origin.fetch()

# Check out the specific commit if not already
current_commit_hash = repo.head.commit.hexsha
if current_commit_hash != commit_hash:
repo.git.checkout(commit_hash)
print(f"{repo_url}@{commit_hash} fetched at {clone_directory}")
except git.GitCommandError as e:
print(f"Error: {e}")

return clone_directory


def clear_myoskeleton():
"""
Remove cached MyoSkeleton if it exists.
"""
print("LocoMujoco:> Clearing MyoSkeleton ...")
api_path = os.path.join(data_dir, 'myo_model')
if os.path.exists(api_path):
shutil.rmtree(api_path)
else:
print("LocoMujoco:> MyoSkeleton directory does not exist.")
print("LocoMujoco:> MyoSkeleton cleared")


def accept_license():
prompt = """
A permissive license for non-commercial scientific research of the MyoSkeleton by the MyoLab Inc. is available.
You can review the license at: https://github.com/myolab/myo_model/blob/main/LICENSE
Do you accept the terms of the license? (yes/no):
"""
response = input(prompt).strip().lower()

if response == 'yes':
print("Thank you for accepting the license. You may proceed.")
return True
elif response == 'no':
print("You have rejected the license terms. Exiting...")
return False
else:
print("Invalid input. Please enter 'yes' or 'no'.")
return accept_license() # Recursively prompt again for valid input


def fetch_myoskeleton():
"""
Fetch a copy of MyoSkeleton.
"""
print("\n\nLocoMuJoCo:> Initializing MyoSkeleton...")

# Inform user about API
if accept_license():
# Proceed with the rest of the code
print("LocoMuJoCo:> MyoSkeleton License accepted. Proceeding initialization ...")
else:
# Exit or handle the rejection case
print("LocoMuJoCo:> MyoSkeleton License rejected. Exiting")
return

# Fetch
print("LocoMuJoCo:> Downloading simulation assets (upto ~100MBs)")
fetch_git(repo_url="https://github.com/myolab/myo_model.git",
commit_hash="619b1a876113e91a302b9baeaad6c2341e12ac81",
clone_directory="myo_model",
clone_path=data_dir)

print("LocoMuJoCo:> Successfully initialized MyoSkeleton .")

0 comments on commit 6e2a08a

Please sign in to comment.