Unity/Unity ML-Agents

Unity를 활용한 UAV 시뮬레이션 및 강화학습 (ML-Agents) #1 구상 및 환경 구현

pnltoen 2022. 6. 30.
반응형

UAV 시뮬레이션

Unity Simulation + Unity ML-Agents


서론

 

유한요소해석
CAE 연구실에서 자연스럽게 Ansys를 활용한 유한요소해석을 접하게 되었다. 간단하게 설명하면 좌측의 사진과 같이, 유한요소해석 (나무위키)이란 해석하고자 하는 대상을 n개의 유한한 Mesh로 나누고 각각의 Mesh를 해석하는 방법이다. 단 이 방법은 장시간이 소요되고, 해석의 타깃이 거시적 관점보다 미시적 관점에 국한된다.

자료조사

자연스럽게 거시적관점에서 사용할 수 있는 개념 및 지식에 대해 자료조사를 진행하였다.
이 후 강화학습, Unity, Unity ML-Agents에 관심을 갖고 프로젝트 및 학습을 진행하였다.

 

구글링 및 유튜브 서칭을 한 결과, Unity ML-Agents는 새로운 방법을 찾는 탐색 프로그램으로 사용되는 것을 확인하였다. 개인적으로 이 부분에 어느정도 역학을 고려하여 에이전트를 학습하고자 하였다. 따라서 Unity에서 물리학을 고려한 게임 또는 시뮬레이션이 진행된적이 있는지 자료를 선행조사 하였고, 유니티에서 제공하는 기본 물리엔진의 성능을 조사하였다.

유니티 Physics Docs를 보면, 기본적으로 제공하는 물리계를 알 수 있다. 다만 이 부분을 유니티에서 공식적으로 모든 물리계의 Default Unit에 대해 밝히고 있지는 않다. Unity의 기본 물리계는 SI 물리계를 따르며, 중요 단위를 정리해보면 다음과 같다.

 

구분 Unity Physics SI 단위 (Unity Default Settings)
1 질량 (Mass) kg
2 위치 및 거리 (Length) m
3 속도 m/s
4 가속도 m/s^2

여기까지는 기존 물리학에 관한 지식이 있는 사람들에게 익숙할 것이다. 하지만 Unity에서 제공하는 기본물리엔진 중 UAV에 관련한 Drag, Thrust 개념은 조금 이상하다고 느꼈다.

Unity Manual, Rigidbody, Properties

 

Unity Docs를 참고하면, Drag=0일 경우, 공기 저항이 없는 상태이고 무한으로 설정할 경우 즉각적으로 멈춘다는 것을 알 수 있다. 이 부분이 매우 이상하여 고찰을 진행해보았다.

다양한 항력공식이 있지만 형태와 개념은 각각의 공식이 파생적이기에, 가장 널리 사용되는 항력공식을 고려하였다.

 

$$F_D=C_D\frac{\rho AV^2}{2}$$

 

Drag가 0 일 때 Unity Docs에 기재된 것과 같이, 저항력이 없다. 하지만 Drag가 infinity할 때, 즉각적으로 멈춘다는 내용은 전적으로 이해가 되지 않았다. 항력계수 또는 항력 자체가 무한일 경우 비행체의 추력보다 항력이 크기 때문에 운동 반대 방향으로 비행기는 움직여야 한다. 이에 추가적으로 구글링을 진행한 결과, 여러 가설 혹은 실험적 결과를 알 수 있었다 (참고한 포스트) 다양한 의견 및 버전 업데이트에 따른 차이점이 존재하였지만, 궁극적으로 Unity에서의 항력은 질량과 관계없이 속도와 시간에 관련있음을 알 수 있었다.

 

선행 프로젝트​

물리 시뮬레이션 관점에서, Unity와 Alogoryx같이 사용할 경우 어느정도의 성능 및 시뮬레이션이 가능한지, 궁금하였지만 라이센스 가격 문제로 구매하지 못하였다. 따라서 다른 방법을 찾아보던 중 Youtube에서 Jump Trajectory 유튜브 채널에서 Realistic Aircraft Physics for Games 영상 및 소스 코드를 찾을 수 있었다.

(본 소스코드 사용 및 수정은 MIT라이센스, 그리고 원작자이신 Jump Trajectory 유튜브에서 허락을 받고 진행하였습니다)

 

프로젝트 구현

W. Khan and M. Nahon, "Real-time modeling of agile fixed-wing UAV aerodynamics,"

 

2015 International Conference on Unmanned Aircraft Systems (ICUAS), Denver, CO, 2015, pp. 1188-1195, doi: 10.1109/ICUAS.2015.7152411.

 

해당 소스 코드는 위 논문의 아이디어를 적용 및 구현한 코드로써 기존 유한요소해석법이 갖는 시간적 한계를 극복하기 위해, 간단한 평면으로 경비행기가 받는 물리력을 계산 후 적용하였다. 논문의 결과에 나와있는 Fig. 6 그리고 Fig. 7을 본다면 실험적 데이터와 시뮬레이션 데이터가 대략 10~20%의 오차로, Real-Time에서 사용가능하다고 생각하였다 (이 부분을 보는 관점에 따른 차이가 있겠으나, FEM이 아닌 Simple Plain으로 이정도의 유사치를 얻을 수 있다는 것은 주목할만하다고 생각한다)

gasgiant, Aircraft-Physics-Components

 

단순 완성된 코드에 Unity ML-Agents를 사용하는 것은 지양하고, 소스코드의 개선 및 수정을 통해 내 입맛에 맞춘 후 Unity ML-Agents를 적용하고자 하였다. 크게 다음과 같은 4가지 부분을 개선하고자 하였고, NASA 및 여러 논문을 참고하여 구현 및 진행하였다. 그 중 대외비 및 광고성 글로 인해, 정확한 값을 얻을 수 없는 경우가 많아 아헨공대의 논문을 참고하여 유사 모델을 참조하여 진행하였다.

 

모델 선정 (MQ-9 Reaper)

널리 알려져 그나마 데이터를 얻을 수 있고, 스토어에서 적당한 가격에 구할 수 있는 MQ-9 Reaper 모델을 구매 후 사용하였다.

이 후 아헨공대의 논문을 필두로, 정확한 물성치 계산 및 환경을 수정하였다.

 

Full configuration drag estimation of short-to-medium range fixed-wing UAVs and its impact on initial sizing optimization

Götten, F., Finger, D.F., Havermann, M. et al,CEAS Aeronaut J 12, 589–603 (2021). https://doi.org/10.1007/s13272-021-00522-w

 

1. 추력계산

 

$$\textrm{746kW = 1000(=THP) =}\frac{Thrust*300(=mph)}{375}->Thrust=1250lb=5.56kN$$​

 

무인 항공기 가스터빈 추진기관의 현황 및 특성 연구

주미리, 최성만, 조하나.(2020).한국추진공학회지,24(2),61-72.

무인 항공기 가스터빈 추진기관의 현황 및 특성 연구 논문을 통해 조사한 결과 MQ-9의 출력을 알 수 있었다. 이를 이용해서 추력을 계산하였고, MQ-9 Reaper 제원을 고려하였을 때, 최고 속도 300mph으로 계산하였다. 최종적으로 이를 통해 추력을 5.56kN으로 선정하였다.

순항속도(172~195mph)를 고려할 경우 대략 8.34kN의 추력을 계산할 수 있다. 이 경우 SFC(Specific Fuel Consumption)를 계산할 수 없었고, 실 운용 속도와 최고속도의 차이고려로 인한 오차 발생 및 전파에 기여하였다.

2. 항력계수

정찰, 감시 목적으로 UAV에 부착되는 Sensor, 및 Turret의 경우 그 형상 및 존재로 인하여 유해(기생)항력(Parasite Drag)을 증가시킨다. 따라서 이를 적용하기 위해 본 논문의 Fig.2의 UAV10번 모델을 택하였다. 10번 모델이 MQ-9의 모델 형상과 길이가 가장 유사하였고, 다른 참고문헌을 고려해보았을 때, UAV의 경우 기존 항력계수가 비슷한 형상의 경비행기와 비교할 때 1.6~2배 가량 증가한다는 점을 고려, 10번 모델을 선정하였다.

drag_scale 추가

 

3. 연료소비에 따른 중력 계산

 

$$TSFC=\frac{f}{F_{Specific Thrust}}=\frac{\dot{m}}{F_{Thrust}}$$

 

계산을 위해 Nasa의 Thrust Specific Fuel Consumption을 참고하였다. 우리는 이미 앞전에 추력을 8.34kN으로 선정하였고, MQ-9 Reaper의 엔진인 TPE331-10에서 SFC(=TSFC)를 325g/hKW 조사하였음으로 다음과 같이 계산할 수 있다.

 

$$TSFC=\frac{\dot{m}}{F_{Thrust}}=325\frac{g}{h\times kW}->242450\frac{g}{h}=0.067347\frac{kg}{s}$$

여기서 어떤 Time Step을 기준으로 연료 소모를 계산해야하는지 결정하여야 한다. 본 시뮬레이션에서는 Unity Fixed Update의 Default Step인 0.5를 기준으로 작성하였다.

 

$$0.067347\frac{kg}{s}=0.0336763\frac{kg}{0.5s}$$

 

연료를 소비함에 따라서 무게가 줄어들고, 무게가 달라진 UAV는 중력의 영향을 덜 받게 될 것이다. 이 부분또한 구현하고자 해 식을 써서 정리한 후 코드화하였다. 하지만, 소비되는 연료의 양은 시간에 비례하는 것이 아니다. 모터의 구동동력과 같이 점화시 더 많은 연료를 소비하게 되는데, 차량의 경우 어느정도 선형화 된 데이터가 있었지만, 비행체의 경우에는 이러한 데이터를 구할 수가 없었다.

 

따라서 초당 연료 소비량을 계산하였는데 여러 행동을 택하면서 학습하는 강화학습 특성 상 이는 초기부터 현실과 맞지 않는 환경에서 학습을 진행하는 것이기 때문에 결과의 신뢰성을 떨어트리는 중요한 요소가 되었다.

 

연료소모량 구현

 

이 후 기체중량 2223kg와 최대 연료량 1800kg을 합한 무게인 4023kg을 고려하여 질량을 계산하였고, 0.5초 단위로 질량에서 소모되는 연료무게를 빼주었다.

 

4. 고도 밀도 계산

 

밀도공식이 있다. Nasa의 Earth Atmosphere Model자료를 보면 다음과 같은 공식임을 알 수 있는데, MQ-9 Reaper의 작전고도인 25.000ft (7.5km)를 고려 했을 때 다음과 같은 공식이 적용됨을 알 수 있다.

 

$$\rho=101.29\times[\frac{T+273.1}{288.08}]^{5.256} (h<11000m)$$

 

하지만 본 시뮬레이션에서는 온도 고려를 피하기 위해 US Standard Atmosphere, 1976 -NASA Technical Reports, 실제 Raw 데이터를 사용하였다. Datasheet가 아닌 이미지로 작성된 파일임으로 수기로 excel에 작성하였고, 2차 추세선을 사용하여 2차 방정식을 얻었다.

Density=(3e-09)y^2-0.001y+1.2234

 

5. 바람 구현

위키백과의 보퍼트 풍력계급을 기준으로 구현하였고, Wind Area을 생성하여 10초 주기로 변화되는 바람 영역을 구현하였다.

보상 설계 (Reward Shaping) - Changing

 

비행기의 속도, 맵의 크기를 고려했을 때 맵을 최대한 크게 만들었다. 기존에 진행한 방법은 각각의 노란 박스를 Trigger Collider로 만들고, 각각을 지나갈 때 마다 점수를 주는 방식이였다.

전체 환경

 

 

하지만 이러한 방식은 몇가지 문제가 있다. 한 예로 RuntimeError: probability tensor contains either `inf`, `nan` or element < 0 오류가 발생하였다. 관련되어 내용을 잘 모르겠어서 RLKorea Slack을 통해 민규식 Unity mlagents 마스터님께 질문을 드렸고, 짧은 시간동안 너무 자주 보상을 받아 알고리즘이 기대하는 가치의 값이 너무 크게 되고, 학습이 발산할 수 있다는 답변을 받았다.

출처 : RLKorea Drone_Challenge Github Docs

 

RL_Korea DroneChallenge Episode Length

 

이후 현재 RLKorea의 Drone Challenge를 참여하면서 Distance Reward와 같은 방법으로도 정상적인 학습이 가능함을 확인하여, 해당 방법으로 재구성하고 있다. 다만 비행기의 경우 드론과 달리 즉각적인 전진 및 후퇴가 불가능하기 때문에, 절대거리를 기준으로 보상을 구현 후 재학습할 예정이다.

현재 생각한 방법은 특정 고도 및 위치에 랜덤으로 생성되는 Object를 생성하고 비행기가 그 오브젝트에 다가가면 정수의 보상을 얻고, 소수의 보상의 경우 1-Timer를 통해 게임 종료 직전에 보상을 얻는 것으로 구현할 예정이다.

 

Agent Action

본 경비행기의 Controller는 roll, pitch, yaw의 Sensitive Value를 통해 조종하는 방식이었다. 하지만 이러한 방법은 Agent Action에 적용할 수 없었다. 한 예로 Value 값은 -1에서 바로 1로 변경한다면, 시뮬레이션 상에서 비행기는 순간적으로 임의의 한 축을 기점으로 180도 회전하게 될 것이다. 따라서 이 부분을 해결하기 위해 합 또는 곱 방식으로 Discrete Action, Continous Action 모두 사용해보았지만 아직 정확하게 맘에 드는 방법을 찾지는 못하였다.

기존에 사용한 방법은 3개의 Actions을 할당하고 [0]의 경우 Value에 1을 곱하고 [1]의 경우 Value에 *0.9 [2]의 경우 Value에 *1.1을 통해 구현하였지만, ML-Agents 2.1.0이 정식 릴리즈 된 상태에서 더 좋은 방법이 있는지 Github 및 포럼에서 찾아보고 진행할 예정 (이 부분 좋은 아이디어 있으면 댓글 부탁드립니다!)

 

고찰

학부연구생으로 있는 연구실이, CAE 그리고 3D Printer 관련 연구를 주로하기에, 관련 부분에 대해 조언을 얻기가 사실상 불가능하였다. 따라서 논문 및 구글링을 통해 조사를 진행하였는데, 정보의 출처마다 세세한 내용이 조금씩 차이가 있었다. MQ-9 Reaper의 제원만 하더라도 위키, 미 공군 등 사이트 별로 내용에 차이가 있었고, 신뢰도가 높은 데이터를 얻는 것이 가장 힘들었다. 아무래도 기업 및 연구소에 재직하지 않는 이상... 대외비 또는 광고성 데이터가 아닌 정확한 데이터를 얻는 것은 불가능해보였고, 따라서 계속 유사모델 선택을 강제받게 되었다.

이러한 상황이 결과적으로 시뮬레이션 신뢰성에 매우 큰 악역향을 끼치게 되었고, 찾아본 MQ-9 정보를 통해 시뮬레이션 비행을 테스트 해봐도 정확한 데이터가 없기에 "비슷하네? 맞는 것 같긴한데...." 라는 생각만 주구장창 갖게 되었고 그 이상을 테스팅하지는 못하였다 ㅠ.ㅠ

 

마무리 및 소감

강화학습과 ML-Agents를 공부하는 많은 사람들과 달리 나의 경우에는 FEM에 사용되는 Ansys 과목을 연구실 그리고 학교에서 수강 후 더 넓은 계(System)에서 거시적관점 해석 또는 더 나은 방법을 찾는 학문에 관하여 관심이 생겼다. 이에 여름 방학부터 ML-Agents와 강화학습에 대해 전반적인 개념을 학습했고 배운 내용을 토대로 2가지 프로젝트를 진행하였다. 강남대로를 구현한 차량 주행 시뮬레이션의 경우 개인적인 목표 수준에는 달성하지 못하였지만, 학습 및 환경 구현 자체는 완료하였다.

이 후 위와 같은 자료조사 및 구현을 통해 UAV를 역학을 고려한 환경에서 시뮬레이션 하고자 하였고, 당시에 환경 구현 문제, 학업, 다수의 공모전, 국가과제, 면접 일정이 겹쳐 잠시 멈춘 상태로 추가적으로 진행하지 못하였다. 12월이 되어 슬슬 대부분의 프로젝트가 마무리 단계에 접어들었고, 이에 잠시 멈춰놓았던 UAV 시뮬레이션 및 강화학습을 다시 진행해보고자 한다. 해당 부분에서 RL_Korea Drone Challenge에 참가한 경험이 정말 도움이 많이 되었다 (관련된 내용은 추 후 포스팅 작성예정)

하이퍼 파라미터 튜닝을 계속 진행하면서 하이퍼 파라미터에 대한 실험적 그리고 경험적 역량이 많이 개선되었다. 추가적으로 RLKorea에서 제공한 Github의 Docs를 수차례 읽으면서 내가 비록 환경 파일은 없지만, 기존 유니티 구현 경험과 비교해 어떠한 부분이 부족하고 어떠한 부분이 개선이 가능한지, 보상 환경 설계를 어떻게 하는 것이 좋은지 등의 새로운 시각을 열 수 있었다. RLKorea의 Drone Challenge가 2일 남은 시점에서... 좋은 성적은 얻지 못했지만 많은 시도를 해보았고... 많은 것을 배울 수 있었다!!!

반응형

댓글