상세 컨텐츠

본문 제목

[2023년 1학기 게임공학] 강화학습과 Motion VAE를 활용한 감정기반 모션 생성

Portfolio

by J2on 2023. 7. 10. 22:55

본문

본 게시물은 2023년도 1학기 게임공학 팀 프로젝트 결과물입니다.

 

프로젝트 주제 : 다양한 상황에 맞게 사용할 수 있는 감정 기반 모션 생성

Variational Auto Encoder와 강화학습을 이용해 여러 Task와 감정기반의 Motion Style을 혼합하는 방식으로 진행했습니다.

 

주제선정 이유 :

 * NPC나 캐릭터가 감정이 담긴 모션을 상황에 맞게 보여줄 수 있다면, 게임의 플레이가 더 현실적으로 느껴질 것이다.

 

Target Paper  : Character Controllers Using Motion Vaes

https://github.com/electronicarts/character-motion-vaes

 

GitHub - electronicarts/character-motion-vaes: Character Controllers using Motion VAEs

Character Controllers using Motion VAEs. Contribute to electronicarts/character-motion-vaes development by creating an account on GitHub.

github.com

https://www.youtube.com/watch?v=Zm3G9oqmQ4Y 

 

EA에서 작성한 해당 논문을 바탕으로 작업을 진행했습니다.

 

 

아래는 논문을 정독하며 나름대로의 해석과 이해를 작성한 글입니다.

 

https://quilt-knight-fc6.notion.site/Character_Controllers_using_Motion_VAEs-dcd77e9976c04e7bb945b6a0ccef4f10?pvs=4 

 

Character_Controllers_using_Motion_VAEs 정리 (게임공학)

1. Introduction

quilt-knight-fc6.notion.site

 

 

Sub Target Paper - MotionClip : Exposing Human Generation to CLIP Space

https://guytevet.github.io/motionclip-page/

 

MotionCLIP: Exposing Human Motion Generation to CLIP Space

We introduce MotionCLIP, a 3D human motion auto-encoder featuring a latent embedding that is disentangled, well behaved, and supports highly semantic textual descriptions. MotionCLIP gains its unique power by aligning its latent space with that of the Cont

guytevet.github.io

 

VAE에 감정요소 추가를 위해 해당 논문을 참조하였습니다.

 

 

사전 공부 

아래는 VAE 기초개념을 정리한 글입니다.

https://quilt-knight-fc6.notion.site/VAE-ELBO-9a8b1d8ff2ec4c968a6203103c618c5a?pvs=4 

 

VAE와 ELBO 정리

원본

quilt-knight-fc6.notion.site

 

간단히 정리하자면

 

Encoder에 들어온 input에서 feature를 추출하여 정보를 압축

→ 압축된 정보는 Latent Space의 Latent Variable에 저장

→ Decoder에서 Latent Variable의 정보를 바탕으로 Output을 생성.

 

의 형태로 이루어집니다.

 

이를 Motion VAE에서는 Motion Data를 Input으로 받아 feature를 추출하고, 이를 바탕으로 새로운 Motion을 생성합니다.

 

 

프로젝트 진행 과정 :

1. 코드 분석

 프로젝트의 조건이 "Unreal Engine"에서의 시각화이기 때문에,

 

타겟논문에서 제공된 코드의 gym에서 학습하여 Bullet으로 시각화하는 방식을 수정할 필요가 있었습니다.

 

이를 위해 파트를 나누어 코드를 분석하고 정리하여 팀원끼리 공유하는 작업을 했습니다,

 

  저는 "common" 폴더의 코드분석을 맡았습니다.

https://quilt-knight-fc6.notion.site/6a1d065158814857834124ddc27874d3?pvs=4 

 

common 파트 코드 분석

A new tool for teams & individuals that blends everyday work apps into one.

quilt-knight-fc6.notion.site

 

해당 논문은 Joint의 Position(x,y,z)를 지정하는 방식으로 Motion을 생성합니다.

 

이 Data를 파악하기 위해 아래와 같은 과정을 거쳤습니다.

https://quilt-knight-fc6.notion.site/Joint-Position-x-y-z-a0d2a5f6cc864eada67581051b895d1d?pvs=4 

 

Joint의 Position(x,y,z)값 구하기

논문에서 구현한 Motion을 언리얼에서 구현하기 위해선 일단 각 motion의 데이터를 얻어야 한다.

quilt-knight-fc6.notion.site

 

2. VAE 학습

이 논문에서는 VAE와 Task를 수행하는 RL, 이 두 가지의 학습을 진행합니다. 

 

 

VAE 학습은 Motion을 생성할 pool을 만드는 것이라 설명할 수 있을 것 같네요.

 

Motion Clip 논문에서 제공하는 감정 기반 Motion의 Pre-trained model을 사용하여 VAE에 학습시켰습니다.

 

이 과정에서 문제가 되었던 것이 Motion Clip 논문과 타겟 논문에서 사용한 캐릭터의 Joint간 거리가 다르다는 것입니다.

 

이 때문에 학습이 제대로 이루어지지 않았고, Joint간 거리를 비율을 통해 새로 지정해 주는 과정을 거쳤습니다.

 

https://quilt-knight-fc6.notion.site/joint-b2937131932a4619a0f45d67cd310e54?pvs=4 

 

논문에서 사용된 캐릭터 joint간 거리

import math def distanceFinder(list1, list2): x1 = list1[0] y1 = list1[1] z1 = list1[2] x2 = list2[0] y2 = list2[1] z2 = list2[2] return math.sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2) a = [[3.1386814, 0.277193, 0.08254603], [2.1889591, 0.31586248, 0

quilt-knight-fc6.notion.site

 

 

계산된 Joint간 거리 

left foot - left shin:  0.181231826252177
right foot - right shin:  0.179435966552883
left leg - left shin  :  0.4341290686848694
right leg - right shin  :  0.43468630782554935
left leg - left hip  :  0.4594834999116311
right leg - right hip  :  0.45323948642285894
left hip - mid hip  :  0.12351826257394533
right hip - mid hip  :  0.1234592698815102
hip mid - column4  :  0.07884714685605296
column4 - column3  :  0.10849441332894769
column3 - column2  :  0.09845556822468127
column2 - column1  :  0.11158304816413661
column1 - left torso  :  0.08678085891558338
column1 - right torso  :  0.08683946191712376
left torso - right torso :  0.05512396047752375
left shoulder - left torso  :  0.15996723969185847
left shoulder - left upper arm  :  0.2738004025634447
left lower arm - left upper arm  :  0.2732645728469619
right shoulder - right torso  :  0.16054000316834088
right shoulder - right upper arm  :  0.27058324665577665
right lower arm - right upper arm  :  0.27446997234322357
left torso - head :  0.09451574530422174
right torso - head :  0.09440966792218954
column1 - head :  0.16992434048998073

 

3. RL 학습

이 논문에서는 단순히 Motion의 생성이 아닌 특정 Task를 수행하기 위해 캐릭터를 움직이는 방법으로 Motion을 생성합니다.

 

Motion을 만들어 재생하는 것보다는,

Task를 달성하기 위해 캐릭터가 강화학습을 통해 Joint를 움직이는 형태로 Motion을 만들어냅니다.

 

저희는 논문에서 제공된 Random walk, Maze Runner, Target 등의 Task를 Uneral에서 구현했으며,

 

새로운 Task로 Player를 추격하는 'Player Tracking'을 만들어냈습니다.

플레이어를 무섭게 따라오는 모습

 

이 Task의 경우 강화학습을 진행하는 파이썬 환경에서 언리얼 엔진에 존재하는 플레이어의 위치를 알아야 한다는 문제가 있었습니다.

 

이를 해결하기 위해 후술 할 TCP 통신에서 단방향 통신을 양방향 통신으로 전환하여 플레이어의 위치를 파이썬 환경으로 보내는 방법을 사용했습니다.

 

4. 소켓 통신

앞서 언급했듯이 파이썬 환경에서 동작하는 코드의 정보를 언리얼에서 시각화하기 위해 소켓통신 과정이 필요했습니다.

 

각 23개 Joint의 Position값을 List로 묶어 Unreal 엔진으로 보내고,

 

이를 Unreal에서 생성한 캐릭터의 Joint의 Position값에 넣어주는 방법을 사용했습니다.

 

그리고 다시 플레이어의 위치를 Python 환경으로 넘겨주어 Tracking Task의 학습을 진행했습니다.

 

 

5. 프로젝트 결과 영상 :

https://www.youtube.com/watch?v=XDkqxWq-E28

 

6. 후기

처음으로 논문을 바탕으로 프로젝트를 진행하여 논문을 이해하는 것부터 어려운 점이 많았지만, VAE와 강화학습에 대하여 이해도를 높일 수 있어 좋은 기회였습니다.

관련글 더보기

댓글 영역