시리즈

Observation

Note: 현재, 기본 observation 형태는 project=True으로, list를 반환한다. 그러나, osim-rl의 다음 릴리스에서는 observation 이 project=False로 바뀌어서 dictionary를 반환할 것이다. 만약 project가 무엇인지 모른다면, 1주차 포스트를 확인해 보자!

Observation 은 크게 신체 부위, 관절, 근육, 힘, 무게중심 이렇게 5가지로 나눌 수 있다. 각 신체 부위마다 위치, 속도, 가속도, 각도, 각속도, 각가속도를 관측할 수 있고, 유사하게 각 관절마다 위치, 속도, 가속도를 관측할 수 있다. 또, 각 근육마다 activation, fiber force, fiber length, fiber velocity를 관측할 수 있고, 힘들은 신체 부위에 작용하는 힘들을 관측한 것을 나타낸다. 마지막으로, 무게중심 역시 위치, 속도, 그리고 가속도를 관측할 수 있다.

{
    'body_acc': {
        'calcn_l': [1253.688828798722, 453.4117256205009, -462.8844724817433],
        'femur_l': [3552.7596723666466, 102.32773696018921, -24.14590774460615],
        'femur_r': [3577.2392919297267, 97.2556003736695, -24.14590774460615],
        'head': [-2151.6179549639746, 247.21132544086612, -5.651007630868147],
        'pelvis': [3021.7003234669214, 680.8998459553628, -32.50184112628757],
        'pros_foot_r': [2097.069790884677, 407.6437699668757, 985.199411865104],
        'pros_tibia_r': [-7206.973998543474, 407.6437699668757, 459.98267021582114],
        'talus_l': [1326.619748123917, 365.89822770528855, -448.4463030305569],
        'tibia_l': [-5893.369348915658, 365.89822770528855, -227.17211746475732],
        'toes_l': [1250.10882643996, 148.06830447245676, -490.1229719729977],
        'torso': [2351.823145970354, -146.7888874667765, -15.265452971775463]
    },
    'body_acc_rot': {
        'calcn_l': [514.5911292227897, 146.58454828192848, -1710.8455233087516],
        'femur_l': [514.5911292227897, 146.58454828192848, -23292.824849203236],
        'femur_r': [-1221.434282905309, 146.5845482819343, -26557.63606714429],
        'head': [30.372075368382077, 146.58454828191628, 8219.35187112352],
        'pelvis': [30.372075368382077, 146.58454828191628, 8219.351871123528],
        'pros_foot_r': [-1221.434282905309, 146.5845482819343, 2218.8731787441284],
        'pros_tibia_r': [-1221.434282905309, 146.5845482819343, 21637.311138205005],
        'talus_l': [514.5911292227897, 146.58454828192848, -1710.8455233087516],
        'tibia_l': [514.5911292227897, 146.58454828192848, 16790.672318696685],
        'toes_l': [514.5911292227897, 146.58454828192848, -1710.8455233087516],
        'torso': [30.372075368382077, 146.58454828191628, 8219.35187112352]
    },
    'body_pos': {
        'calcn_l': [-0.123969856517536, 0.006129303551649576, -0.09142],
        'femur_l': [-0.0707, 0.8738999999999999, -0.0835],
        'femur_r': [-0.0707, 0.8738999999999999, 0.0835],
        'head': [-0.052764320996907754, 1.5694070821576522, 0.0],
        'pelvis': [0.0, 0.94, 0.0],
        'pros_foot_r': [-0.07519985651753601, 0.04807930355164958, 0.0835],
        'pros_tibia_r': [-0.07519985651753601, 0.47807930355164957, 0.0835],
        'talus_l': [-0.07519985651753601, 0.04807930355164958, -0.0835],
        'tibia_l': [-0.07519985651753601, 0.47807930355164957, -0.0835],
        'toes_l': [0.05483014348246398, 0.004129303551649576, -0.0925],
        'torso': [-0.1007, 1.0214999999999999, 0.0]
    },
    'body_pos_rot': {
        'calcn_l': [-0.0, 0.0, -0.0],
        'femur_l': [-0.0, 0.0, -0.0],
        'femur_r':[-0.0, 0.0, -0.0],
        'head': [-0.0, 0.0, -0.0872665],
        'pelvis': [-0.0, 0.0, -0.0],
        'pros_foot_r': [-0.0, 0.0, -0.0],
        'pros_tibia_r': [-0.0, 0.0, -0.0],
        'talus_l': [-0.0, 0.0, -0.0],
        'tibia_l': [-0.0, 0.0, -0.0],
        'toes_l': [-0.0, 0.0, -0.0],
        'torso': [-0.0, 0.0, -0.0872665]
    },
    'body_vel': {
        'calcn_l': [0.0, 0.0, 0.0],
        'femur_l': [0.0, 0.0, 0.0],
        'femur_r': [0.0, 0.0, 0.0],
        'head': [0.0, 0.0, 0.0],
        'pelvis': [0.0, 0.0, 0.0],
        'pros_foot_r': [0.0, 0.0, 0.0],
        'pros_tibia_r': [0.0, 0.0, 0.0],
        'talus_l': [0.0, 0.0, 0.0],
        'tibia_l': [0.0, 0.0, 0.0],
        'toes_l': [0.0, 0.0, 0.0],
        'torso': [0.0, 0.0, 0.0]
    },
    'body_vel_rot': {
        'calcn_l': [0.0, 0.0, 0.0],
        'femur_l': [0.0, 0.0, 0.0],
        'femur_r': [0.0, 0.0, 0.0],
        'head': [0.0, 0.0, 0.0],
        'pelvis': [0.0, 0.0, 0.0],
        'pros_foot_r': [0.0, 0.0, 0.0],
        'pros_tibia_r': [0.0, 0.0, 0.0],
        'talus_l': [0.0, 0.0, 0.0],
        'tibia_l': [0.0, 0.0, 0.0],
        'toes_l': [0.0, 0.0, 0.0],
        'torso': [0.0, 0.0, 0.0]
    },
    'forces': {
        'AnkleLimit_l': [0.0, 0.0],
        'AnkleLimit_r': [0.0, 0.0],
        'HipAddLimit_l': [0.0, 0.0],
        'HipAddLimit_r': [0.0, 0.0],
        'HipLimit_l': [0.0, 0.0],
        'HipLimit_r': [0.0, 0.0],
        'KneeLimit_l': [-0.0, 0.0],
        'KneeLimit_r': [-0.0, 0.0],
        'abd_l': [0.0],
        'abd_r': [0.0],
        'add_l': [0.0],
        'add_r': [0.0],
        'ankleSpring': [-0.0],
        'bifemsh_l': [6084.326590359711],
        'bifemsh_r': [6084.326590359711],
        'foot_l': [-1.7615592933859115e-12, -504.53063397142085, 0.0, -46.45915575255036, 1.622112753284362e-13, -4.943148065393853, 6.786660275561278e-13, 194.37767574636297, 0.0, 0.0, 0.0, 5.831330272390875, 1.0828932658297836e-12, 310.1529582250579, 0.0, 0.0, 0.0, 6.203059164501164, 1.0828932658297836e-12, 310.1529582250579, 0.0, 0.0, 0.0, 6.203059164501164],
        'gastroc_l': [0.0],
        'glut_max_l': [147037.7044007947],
        'glut_max_r': [147037.7044007947],
        'hamstrings_l': [0.0],
        'hamstrings_r': [0.0],
        'iliopsoas_l': [21479.14279626967],
        'iliopsoas_r': [21479.14279626967],
        'pros_foot_r_0': [-1.3573320551122304e-12, -388.7553514927188, 0.0, 32.46107184964201, -1.1333722660187127e-13, 3.726164264482634, 1.3573320551122304e-12, 388.7553514927188, 0.0, 0.0, 0.0, 25.50818238819416, 1.3573320551122304e-12, 388.7553514927188, 0.0, 0.0, 0.0, 25.50818238819416],
        'rect_fem_l': [0.0],
        'rect_fem_r': [0.0],
        'soleus_l': [0.0],
        'tib_ant_l': [0.0],
        'vasti_l': [0.0],
        'vasti_r': [0.0]
    },
    'joint_acc': {
        'ankle_l': [-18501.517842005436],
        'ankle_r': [-19418.437959460876],
        'back': [-1.000444171950221e-11],
        'back_0': [],
        'ground_pelvis': [8219.351871123528, 30.372075368382077, 146.58454828191628, 3021.7003234669214, 680.8998459553628, -32.50184112628757],
        'hip_l': [-31512.176720326766, -484.21905385440766, -1.2192913345643319e-11],
        'hip_r': [-34776.98793826782, -1251.806358273691, 1.801936377887614e-11],
        'knee_l': [40083.49716789992],
        'knee_r': [48194.947205349294],
        'mtp_l': [],
        'subtalar_l': []
    },
    'joint_pos': {
        'ankle_l': [0.0],
        'ankle_r': [0.0],
        'back': [-0.0872665],
        'back_0': [],
        'ground_pelvis': [0.0, 0.0, 0.0, 0.0, 0.94, 0.0],
        'hip_l': [0.0, 0.0, 0.0],
        'hip_r': [0.0, 0.0, 0.0],
        'knee_l': [0.0],
        'knee_r': [0.0],
        'mtp_l': [],
        'subtalar_l': []
    },
    'joint_vel': {
        'ankle_l': [0.0],
        'ankle_r': [0.0],
        'back': [0.0],
        'back_0': [],
        'ground_pelvis': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        'hip_l': [0.0, 0.0, 0.0],
        'hip_r': [0.0, 0.0, 0.0],
        'knee_l': [0.0],
        'knee_r': [0.0],
        'mtp_l': [],
        'subtalar_l': []
    },
    'markers': {},
    'misc': {
        'mass_center_acc': [-4.001157926055469e-13, 2.5708322099694465],
        'mass_center_pos': [-0.08466565561225976, 0.9952730567231536],
        'mass_center_vel': [0.0, 0.0]
    },
    'muscles': {
        'abd_l': { 'activation': 0.05, 'fiber_force': 1.547474121413317e-14, 'fiber_length': 0.1, 'fiber_velocity': -1.326540950462705 },
        'abd_r': { 'activation': 0.05, 'fiber_force': 1.547474121413317e-14, 'fiber_length': 0.1, 'fiber_velocity': -1.326540950462705 },
        'add_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -1.0367973163843414 },
        'add_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -1.0367973163843414 },
        'bifemsh_l': { 'activation': 0.05, 'fiber_force': 6738.484542501806, 'fiber_length': 0.1, 'fiber_velocity': 379.68284762694003 },
        'bifemsh_r': { 'activation': 0.05, 'fiber_force': 6738.484542501806, 'fiber_length': 0.1, 'fiber_velocity': 379.68284762694003 },
        'gastroc_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -3481.201038861244 },
        'glut_max_l': { 'activation': 0.05, 'fiber_force': 147037.7044007947, 'fiber_length': 0.1, 'fiber_velocity': 2608.0828361198787 },
        'glut_max_r': { 'activation': 0.05, 'fiber_force': 147037.7044007947, 'fiber_length': 0.1, 'fiber_velocity': 2608.0828361198787 },
        'hamstrings_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -5.221454250202676 },
        'hamstrings_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -5.221454250202676 },
        'iliopsoas_l': { 'activation': 0.05, 'fiber_force': 21769.687084250327, 'fiber_length': 0.1, 'fiber_velocity': 276.6184843761971 },
        'iliopsoas_r': { 'activation': 0.05, 'fiber_force': 21769.687084250327, 'fiber_length': 0.1, 'fiber_velocity': 276.6184843761971 },
        'rect_fem_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.4092974568990915 },
        'rect_fem_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.4092974568990915 },
        'soleus_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -190146.97438065815 },
        'tib_ant_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -16.394217173963888 },
        'vasti_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.427439106952905 },
        'vasti_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.427439106952905 }
    }
}

위의 dictionary는 첫 state (상태)의 observation dictionary인데, 숫자들의 크기가 무척 차이가 난다는 것을 알 수 있다. 신체 부위의 y축 포지션은 대부분 0과 1 사이인 것에 반해, 신체부위의 가속도는 몇만의 큰 숫자를 가지고 있다. 이렇게 큰 숫자가 나타나는 이유는 근육들이 제대로 초기화되지 않아서일 수도 있지만 (Issue #133), 그렇다고 하더라도 observation을 normalize (표준화)하는 것도 충분히 에이전트의 학습속도에 유의미한 영향이 있을 수 있다.

또, observation에서 위치를 나타내는 모든 숫자는 절대적인 값인데, 에이전트는 이러한 절대적인 값보다 pelvis의 x, z축에 대한 상대적인 값이 더 유용할 것이라 추측된다. 예를 들어, 만약 머리가 허리 뒤에 있다면, 에이전트는 뒤로 넘어질 확률이 높고, 머리가 허리 앞에 있다면, 에이전트는 앞으로 넘어지거나 뛸 확률이 높다.

참고로, 현재 무게중심은 2개의 숫자밖에 없는데, 이것은 곧 수정될 버그이다 (Issue #129).

만약 observation 에 대해 더 세부적으로 알고 싶다면, 공식 문서를 확인하는 것을 추천한다.

osim-rl-helper

DictToList

기존의 DictToList wrapper 는 osim-rl 패키지의 ProstheticsEnv.get_observation() 를 이용해서 dict 형태의 observation을 list 형태로 바꾸었다. 그러나, 이 함수는 $z$축의 정보를 전혀 쓰지 않는 버그가 있다. 그러므로, 기존의 DictToList wrapper는 DictToListLegacy라는 이름으로 바뀌었다. 그 대신, 전처리 없이 단순히 형태만 list로 바꾸는 DictToListFull wrapper를 추가하였다.

def _dict_to_list(self, state_desc):
    res = []

    # Body Observations
    for info_type in ['body_pos', 'body_pos_rot',
                      'body_vel', 'body_vel_rot',
                      'body_acc', 'body_acc_rot']:
        for body_part in ['calcn_l', 'talus_l', 'tibia_l', 'toes_l',
                          'femur_l', 'femur_r', 'head', 'pelvis',
                          'torso', 'pros_foot_r', 'pros_tibia_r']:
            res += state_desc[info_type][body_part]

    # Joint Observations
    # Neglecting `back_0`, `mtp_l`, `subtalar_l` since they do not move
    for info_type in ['joint_pos', 'joint_vel', 'joint_acc']:
        for joint in ['ankle_l', 'ankle_r', 'back', 'ground_pelvis',
                      'hip_l', 'hip_r', 'knee_l', 'knee_r']:
            res += state_desc[info_type][joint]

    # Muscle Observations
    for muscle in ['abd_l', 'abd_r', 'add_l', 'add_r', 
                   'bifemsh_l', 'bifemsh_r', 'gastroc_l',
                   'glut_max_l', 'glut_max_r', 
                   'hamstrings_l', 'hamstrings_r',
                   'iliopsoas_l', 'iliopsoas_r', 'rect_fem_l', 'rect_fem_r',
                   'soleus_l', 'tib_ant_l', 'vasti_l', 'vasti_r']:
        res.append(state_desc['muscles'][muscle]['activation'])
        res.append(state_desc['muscles'][muscle]['fiber_force'])
        res.append(state_desc['muscles'][muscle]['fiber_length'])
        res.append(state_desc['muscles'][muscle]['fiber_velocity'])

    # Force Observations
    # Neglecting forces corresponding to muscles as they are redundant with
    # `fiber_forces` in muscles dictionaries
    for force in ['AnkleLimit_l', 'AnkleLimit_r',
                  'HipAddLimit_l', 'HipAddLimit_r',
                  'HipLimit_l', 'HipLimit_r', 'KneeLimit_l', 'KneeLimit_r']:
        res += state_desc['forces'][force]

        # Center of Mass Observations
        res += state_desc['misc']['mass_center_pos']
        res += state_desc['misc']['mass_center_vel']
        res += state_desc['misc']['mass_center_acc']

    return res

상호작용 모니터

에이전트와 환경의 상호작용을 모니터링할 수 있는 Jupyter Notebook을 추가하였다. 이것은 agent.act(observation)이라는 함수가 있는 모든 agent에 쓸 수 있고, 무엇을 모니터링할 지 설정할 수도 있다. 현재 지원하는 것은 observation, reward, 그리고 action이다. 아래의 비디오는 pelvis의 포지션, reward, 총 reward, 그리고 첫번째 근육에 주는 힘을 관측한 것이다.

다음 주 예정

이번 주와 저번 주에는 연구를 하고 블로그를 리디자인하느라 상당히 바빠서 생각보다 이 대회에 많은 시간을 낼 수 없었다. 다음 주에는 reward space에 대해서 알아보는 것을 끝으로 환경을 살펴보는 것을 끝낼 것이다.

아마 몇 주 후에 대회가 2라운드로 진행될 텐데, 그러면 에이전트는 현재처럼 3 m/s의 속도로 달리는 것이 아니라, 무작위로 바뀌는 속도 벡터를 따라가야 한다. 현재 환경에 존재하는 몇 가지 버그 또한 그 때 수정될 것 같다 (Issues #129, #133). 그러므로 2라운드가 시작되면 첫 주는 바뀐 점을 소개하면서, osim-rl-helper를 업데이트한 것에 대해 포스트를 쓰고, 그 이후 본격적으로 에이전트를 학습시키는 것을 시작할 것 같다.