강화학습을 이용하여 Unity에서 자동차 달리게하기(1/3)
Updated:
https://drive.google.com/file/d/1f-dbqqBJlTrF86loFFuDOgO7yAoC4qwR/view?usp=sharing 전체 게임파일입니다. 용량이 너무커서 깃허브에 안올라가 구글드라이브에 올립니다. 스크립트, 모델만 따로 깃허브에 올렸으니 바로 강화학습에 들어가고싶다면 게임파일을 다운로드 받아주시길 바랍니다.
** 학습환경 구축 **
유니티에서 제공하는 MLAgent를 이용해 강화학습으로 자율주행하는 자동차를 만들어본다. Checkpoints인 초록색 벽을 통과할때마다 보상이 주어지고, Fence에 닿을때마다 점수가 깍여서 최대한 도로안쪽으로 달리게끔한다.
유니티 프로젝트 생성하기
기본적으로 컴퓨터에 유니티가 깔려있음을 전제로 한다. 폴더 위치를 지정한 후 새 프로젝트 -> 3D를 클릭하여 프로젝트를 생성한다.
모델 준비하기
모델 준비과정을 생략하고싶다면 (https://github.com/dvpLeejh/AI-Game-Programming/blob/main/ch06/track.zip) 에서 다운로드 받으시면됩니다.
먼저 자신이 사용하고 싶은 자동차와 경주트랙을 유니티 에셋 스토어에서 다운로드한다.
이후 유니티에 자신이 사용할 트랙과 자동차를 임포트하고 적절하게 배치해준다.
이제 체크포인트인 벽을 원하는 진행방향대로 만들어준다. 또한 주행도로 양옆에 자동차의 충돌을 막아줄 Fence가 없다면 새로 만들어줘야한다.
빈오브젝트를 생성한뒤 Checkpoint라고 이름을 바꾼뒤 체크포인트 오브젝트들을 모두 담는다. Checkpoints -> checkpoint, checkcpoint (1), checkpoint(2) … 순으로 담겨있으면 된다.
다 만들면 다음과 같다.
하얀색의 plane 오브젝트는 자동차가 학습을 종료하고 다시 학습을 시작할때 위치가 랜덤으로 바뀌는데, 그 위치를 미리 지정해둔 것이다.
적절한 갯수를 정해서 사진처럼 적당히 만들어주자. 이름은 Spawnpoint로 바꿨다. 마찬가지로 빈 오브젝트를 생성해서 이름을 적당히 바꾸고(Spawnpoints) 만들어준 Spawnpoint 오브젝트들을 모두 넣는다. 그리고 이 오브젝트들은 물리충돌이 필요없으므로 Collider 컴포넌트를 삭제해준다.
개발환경 준비하기
STEP 1
기본적으로 MLAgent는 파이썬과 연계되기때문에 파이썬을 설치해야한다. 필자는 파이썬 3.8.4버전을 사용하였다. (MLAgent와 파이썬 버전간의 호환성이 있기때문에 잘 확인하여야한다.)
윈도우+R키를 눌러서 실행창이 나오면 cmd를 입력하여 cmd창을 연다.
cd “프로젝트경로” 커맨드를 입력하여 프로젝트가 설치된 폴더로 이동한다.
python -m -venv venv 를 입력하여 머신러닝에 사용할 가상환경 폴더를 만든다.
venv\Scripts\activate 를 입력하면 가상환경이 실행된다.
python -m pip install –upgrade pip 를 이용하여 pip를 설치한다.
pip install torch==1.7.0 -f https://download.pytorch.org/whl/torch_stable.html 를 입력하여 파이토치를 설치한다.
pip install mlagents 를 입력하여 mlagents를 설치한다.
mlagents-learn –help 를 입력하여 제대로 실행이 되는지 확인한다. (nvidia의 cuda 버전 10.1을 컴퓨터에 설치한후 다시 시도한다)
여기까지가 cmd창을 이용한 개발 환경 준비단계였다.
STEP 2
이제 유니티에서의 개발 환경을 준비한다.
먼저 Edit -> Project Settings를 클릭한다. 그다음 사진과 같이 Preview 패키지도 사용 가능하게 클릭해준다.
Window -> Package Manager를 클릭하여 패키지 메니저를 연 후 상단에 Packages를 Unity Registry로 변경해준다.
ML Agents 패키지를 찾아서 설치해준다. 여기에서는 2.1.0버전을 설치하였다.
Scripts
(https://github.com/dvpLeejh/AI-Game-Programming/tree/main/ch06/Scripts)
먼저 필요한 스크립트들을 다운로드 받는다. 위에서 모델생성을 직접하였다면 스크립트 적용 역시 직접해줘야한다.
CarController
먼저 자동차를 움직이려면 당연히 컨트롤 스크립트가 필요하다. Unity Wheel Collider 위의 사이트를 보고 자신이 선택한 자동차 모델에 맞게 적용한다. (프리팹을 사용하면 좋다.)
나의 경우 Rigidbody가 있는쪽으로 box collider를 옮겼고 모든 스크립트를 Rigidbody가 있는 오브젝트에 적용시켰다. CarController, Checkpoint Manager, Collider Control, DontGoBack 스크립트를 모두 추가해준다.
Agent 스크립트
CarAgent스크립트를 추가해주면 Behavior Parameters 스크립트가 자동으로 추가된다. (자동으로 추가가 안됐다면 직접 추가해준다.)
Behavior Parameters의 Name을 CarAgent 혹은 자신이 원하는 이름으로 바꿔준다. Vector Observation의 Space Size를 4로 바꿔준다. Actions의 Continuous Act값을 2로, Discrete Branch값을 0으로 바꿔준다. 이 둘의 차이는 가볍게 설명하면 연속적으로 값을 받느냐, 이산적으로 값을 받느냐의 차이다.
Add Component 버튼을 눌러 Decision Requester 스크립트를 추가해준다. 자동차는 움직이면서 끊임없이 어디를 가야할지 판단해야하므로, Decision Period를 1로 맞춘다.
Ray 스크립트
Add Component 버튼을 눌러 Ray Perception Sensor 3D를 추가해준다. Dectectable Tags는 자신이 인지할 오브젝트의 태그를 입력한다. 여기에서는 Fence, Checkpoint를 입력하였다.
Ray Layer Mask는 광선이 충돌할 오브젝트들의 레이어를 입력하는것이다. 여기에서는 벽과 체크포인트만 충돌이 필요하기때문에 Fence, Checkpoints 두개만 체크하였다. (아무 오브젝트나 선택한뒤, 위에 입력한 태그와 레이어를 입력하도록 하자. 이름은 자신의 취향에 맞게 변경해도 좋다.)
마지막으로 Start Vertical Offset과 End Vertical Offset을 1로 설정한다.
Checkpoint
Checkpoints 오브젝트에 Checkpoints 스크립트를 추가한다. 이후 스크립트에 있는 Check Points리스트에 자기가 만든 Chekcpoint의 오브젝트들을 순서에 맞게 모두 추가해준다.
Checkpoints
Checkpoints 오브젝트를 우클릭한뒤 Select Chilldern을 클릭하면 모든 Checkpoint오브젝트들이 선택된다. 이때 부모 오브젝트인 Checkpoints도 포함하고 있으므로 Ctrl+클릭으로 Checkpoints 오브젝트는 선택해제한다. 이러면 모든 Checkpoint만 선택이 되어있는데 여기에 Box Collider에서 Is Trigger가 체크표시가 되도록 한다. 이후 Checkpoint 스크립트를 추가해준다.
SpawnPointManager
위에서 만들어놓은 Spawnpoint들을 모두 담고있는 오브젝트에 SpawnPointManager스크립트를 추가한다. 이후 모든 Spawnpoint오브젝트들을 리스트에 담는다.
마무리
여기까지 준비되었으면 자동차의 레이어를 지정해야한다. 자동차 오브젝트를 클릭하여 적당히 레이어를 지정해주자. 여기에서는 Car라고 지정해줫다.
이제 자동차의 갯수를 설정할때다. 스크립트추가와 설정이 완료된 자동차 오브젝트를 원하는 만큼 Ctrl+D를 눌러서 복사한다. 여기에서는 16개까지 추가하였지만, 자신의 컴퓨터 사양에 맞춰서 더 늘릴수도 줄일수도 있다.
이제 자동차들이 서로 부딪히면 안되니 Eidt -> Project Settings -> Physcis에서 맨밑으로 스크롤을 내리면
와 같이 되어있는데 자동차끼리는 서로 부딪히지 않게 물리충돌을 해제해준다.
Leave a comment