はじめに
本記事は以下の人を対象としています.
- 筋骨格シミュレータに興味がある人
- MuJoCoに興味がある人
本記事では5_Move_Hand_Fingers.ipynbをGoogle Colabで実行した際の手順と結果に関してまとめる.
MyoSuiteとは
MuJoCoを学習モジュールとして組み込んだ筋骨格シミュレータ
2024年にICRAにてworkshopを展開
https://sites.google.com/view/myosuite/myosymposium/icra24
Tutorial Notebook
実施事項
Tutorialに記載のコードを1つずつ試して, Errorになったところは都度修正版を記載する.
ライブラリのinstallと環境変数設定
!pip install -U myosuite
!pip install tabulate matplotlib torch gym==0.13 git+https://github.com/aravindr93/mjrl.git@pvr_beta_1vk
!pip install scikit-learn
%env MUJOCO_GL=egl
ライブラリのimportと結果表示の関数
from myosuite.utils import gym
import skvideo.io
import numpy as np
import os
from IPython.display import HTML
from base64 import b64encode
def show_video(video_path, video_width = 400):
video_file = open(video_path, "r+b").read()
video_url = f"data:video/mp4;base64,{b64encode(video_file).decode()}"
return HTML(f"""<video autoplay width={video_width} controls><source src="{video_url}"></video>""")
handとfingerの動作デモ
import mujoco
env = gym.make('myoHandPoseRandom-v0', normalize_act = False)
env.env.init_qpos[:] = np.zeros(len(env.env.init_qpos),)
mjcModel = env.env.sim.model
# actuatorの名称については後述
musc_fe = [mjcModel.actuator('FDP2').id,mjcModel.actuator('EDC2').id]
L_range = round(1/mjcModel.opt.timestep)
skip_frame = 50
env.reset()
frames_sim = []
for iter_n in range(3):
print("iteration: "+str(iter_n))
res_sim = []
for rp in range(2): #alternate between flexor and extensor
for s in range(L_range):
if not(s%skip_frame):
frame = env.sim.renderer.render_offscreen(
width=400,
height=400,
camera_id=0)
frames_sim.append(frame)
ctrl = np.zeros(mjcModel.na,)
act_val = 1 # maximum muscle activation
if rp==0:
ctrl[musc_fe[0]] = act_val
ctrl[musc_fe[1]] = 0
else:
ctrl[musc_fe[1]] = act_val
ctrl[musc_fe[0]] = 0
env.step(ctrl)
os.makedirs('videos', exist_ok=True)
# make a local copy
skvideo.io.vwrite('videos/MyoSuite.mp4', np.asarray(frames_sim),outputdict={"-pix_fmt": "yuv420p"})
# show in the notebook
show_video('videos/MyoSuite.mp4')
出力結果(実際は2秒ほど)
動作のはじめに腕が半回転するような挙動が見てとれるが、原因は不明
actuatorに関して
以下のコマンドを実行するとMuscleとJointの情報を得ることができる
print("Muscles:")
for i in range(mjcModel.na):
print([i,mjcModel.actuator(i).name])
print("\nJoints:")
for i in range(mjcModel.njnt):
print([i,mjcModel.joint(i).name])
出力結果
Muscles:
[0, 'ECRL']
[1, 'ECRB']
[2, 'ECU']
[3, 'FCR']
[4, 'FCU']
[5, 'PL']
[6, 'PT']
[7, 'PQ']
[8, 'FDS5']
[9, 'FDS4']
[10, 'FDS3']
[11, 'FDS2']
[12, 'FDP5']
[13, 'FDP4']
[14, 'FDP3']
[15, 'FDP2']
[16, 'EDC5']
[17, 'EDC4']
[18, 'EDC3']
[19, 'EDC2']
[20, 'EDM']
[21, 'EIP']
[22, 'EPL']
[23, 'EPB']
[24, 'FPL']
[25, 'APL']
[26, 'OP']
[27, 'RI2']
[28, 'LU_RB2']
[29, 'UI_UB2']
[30, 'RI3']
[31, 'LU_RB3']
[32, 'UI_UB3']
[33, 'RI4']
[34, 'LU_RB4']
[35, 'UI_UB4']
[36, 'RI5']
[37, 'LU_RB5']
[38, 'UI_UB5']
Joints:
[0, 'pro_sup']
[1, 'deviation']
[2, 'flexion']
[3, 'cmc_abduction']
[4, 'cmc_flexion']
[5, 'mp_flexion']
[6, 'ip_flexion']
[7, 'mcp2_flexion']
[8, 'mcp2_abduction']
[9, 'pm2_flexion']
[10, 'md2_flexion']
[11, 'mcp3_flexion']
[12, 'mcp3_abduction']
[13, 'pm3_flexion']
[14, 'md3_flexion']
[15, 'mcp4_flexion']
[16, 'mcp4_abduction']
[17, 'pm4_flexion']
[18, 'md4_flexion']
[19, 'mcp5_flexion']
[20, 'mcp5_abduction']
[21, 'pm5_flexion']
[22, 'md5_flexion']
今回はこの内MuscleのFDP2
とEDC2
を用いて動作をさせるものである
rp
が0か否かで屈筋と伸筋のactuationを選択している(muscle activationは0~1の範囲で指定)