2016년 8월 29일 월요일

MPU-6050/9250 다루기

IMU 혹은 AHRS 센서라 불리는 자세 인식 센서는 재미있는 효과를 보여주기에 적합한 좋은 도구입니다.
현재, 여러 종류의 제품이 나와있지만 그 중에서도 가장 많이 알려진 MPU-6050과 MPU-9250을 다루는 법에 대해 기술하겠습니다.
MPU-6050 보드

MPU-6050은 아두이노에서 가장 많이 알려진 IMU센서입니다. 이것은 값도 저렴하고 DMP라 부르는 센서 융합 기술을 내장하고 있기에, 기존의 칼만 필터 등으로 센서 융합 알고리즘을 구현하느라 애쓰지 않아도 되는 장점을 갖고 있습니다.
MPU-9250은 6050에 비해 잘 알려져있지는 않지만, 매우 유용한 센서입니다.
MPU-9250 보드

MPU-6050과 9250의 가장 큰 차이는 지자기 센서 포함 유무입니다. MPU-6050은 지자기 센서를 포함하지 않기때문에 지면과 수평인 Yaw 방향에 오차가 생깁니다. 반면에, MPU-9250은 지자기 센서를 포함하고 있기때문에 Yaw 방향에 대해서도 정확한 각도를 추출합니다.
Yaw 방향의 필요성에 따라 6050 혹은 9250을 선택해서 사용하면 됩니다.

MPU-6050/9250을 아두이노 보드에 연결하려면 다음과 같은 회로를 구현합니다.

이 회로를 이해하려면 I2C 통신에 대해 알아야 합니다.
대부분의 아두이노 부품은 Digital In/Out 혹은 Analog In/Out을 통해 제어했습니다. 그러나, 좀 더 복잡한 제어를 하기 위해서는 서로 정보를 교환하는 통신이란 방법이 필요합니다.
IC 칩과 칩 사이의 통신을 위해 만들어진 규약이 I2C(Inter Intergrated Circuit)입니다. I2C는 SCL과 SDA라는 핀을 통해 서로 연결할 수 있습니다.
아두이노 보드는 Analog 입력 핀으로 사용되는 A4와 A5가 각각 SDA, SCL로 사용될 수 있기에 I2C 연결을 위해서 이 핀을 사용합니다.

회로 연결을 하고 아두니티에서 Wire Editor를 작성한다면 다음과 같이 표현됩니다.

아두이노 스케치를 만들기 전 MPUSeries의 Sketch Option을 잘 설정해야 합니다. (설정 방법 참고)
MPU 보드의 Orientation을 맞추는 것은 중요합니다. 왜냐하면 MPU 보드의 방향과 유니티의 방향이 일치해야 쉽게 제어할 수 있기 때문입니다.
MPU보드에는 좌표계가 있습니다.

주의할 점은 MPU 보드에서 Z는 위 방향을 의미하지만, 유니티에서는 Y가 위 방향이란 것입니다. 그리고, 만들다보면 MPU 보드의 방향과 유니티 방향을 맞추기 어려운 경우가 생깁니다.
이런 경우 MPU보드와 유니티 방향을 재 설정하는 아두이노 스케치 옵션을 통해 맞추면 됩니다.

MPU 보드로 GameObject 회전시키기
MPU 보드는 Roll, Pitch, Yaw라는 3차원 공간의 각도를 알려줍니다. 이것을 GameObject Transform의 Rotation에 사용한다면 MPU 보드로 GameObject의 회전을 제어할 수 있습니다.
RotationReactor는 보드로부터 수집된 회전 정보를 GameObject Transform의 Rotation에 적용하는 기능을 갖고 있습니다.



RotationReactor를 사용하기 위해서는 다음과 같은 설정이 필요합니다.

  • smoothFollow: GameObject 회전이 보다 부드럽게 연결됨

RotationReactor와 MPUSeries를 연결하면 MPU 보드로 회전되는 GameObject를 볼 수 있습니다.

동영상을 통해 작동 모습을 직접 확인하시기 바랍니다.




2016년 8월 26일 금요일

MPUSeries

ArdunityController중 MPUSeries에 관해 기술하겠습니다.
이것에 대해 이해하려면 먼저 IMU(Inertial Measurement Unit) 혹은 AHRS(Attitude and Heading Reference System) 센서를 알아야 합니다.
3차원 공간에서 물체의 위치를 표현하려면 위치와 각도 정보가 필요합니다. 위치 정보를 수집하기 위해 가장 많이 쓰이는 기술은 GPS(Global Positioning System)입니다. GPS기술은 네비게이션 등에서 활용되는 매우 유용한 기술입니다.
3차원 공간에서 각도는 오일러(Euler) 각도라 불리는 Roll, Pitch, Yaw라는 3가지 값으로 표현됩니다.
Euler 각도의 이해

이 값을 알아내기 위해 사용되는 장치가 IMU 혹은 AHRS라 불리는 센서입니다.
다른 센서와 달리 IMU는 3가지 센서를 융합해서 사용해야 하는 복잡한 시스템입니다. 그래서, 이 장치는 주로 전투기나 항공기 등의 매우 고가 시스템에서만 사용되어 왔습니다.
IMU 센서에서 사용되는 센서는 3가지가 일반적입니다.
  • Gyroscope (자이로 센서)
  • Accelerometer (가속도 센서)
  • Magnetic Sensor (지자기 센서)

자이로 센서
자이로 센서는 자이로 효과(Gyro effect)를 측정하기 위한 센서로 회전력을 알아낼 수 있습니다. 자이로 효과란 회전하는 물체는 그 자세를 유지하기 위한 힘이 발생하는 것을 말하며 팽이가 그 효과를 보여주는 좋은 예입니다.
자이로 효과를 보여주는 장치

자이로 센서를 이용하면 물체가 기울어지는 힘을 측정할 수 있기에 이 값을 적분(Integral)하여 자세를 추출할 수 있습니다. 그러나, 적분은 오차가 누적되는 문제가 있어서 자이로 센서만으로는 정확한 각도를 알아내기 어렵습니다. 자이로 센서의 적분 오차 문제를 드리프트(Drift) 현상이라 부릅니다.

가속도 센서
가속도 센서는 정확히 말하면 중력 가속도를 측정할 수 있습니다. 이 말은 중력의 방향을 알 수 있다는 말입니다. 중력 왜곡이 일어나지 않는 한 가속도 센서는 지면에 대해 기울어짐을 정확하게 알려줍니다. 문제는 빠르게 움직이는 물체의 경우 운동 방향의 힘으로 인해 중력 왜곡이 일어나서 정확한 각도를 알 수 없게 됩니다.

지자기 센서
지자기 센서는 마치 나침반과 같이 지구의 자기장 방향을 측정할 수 있습니다. 지면에 대한 수평 회전의 경우 중력 변화가 없기때문에 이를 측정하려면 지자기 센서가 있어야 합니다. 지자기 센서는 자력에 매우 큰 영향을 받기 때문에 모터와 같이 자성이 있는 물체가 근처에 있으면 정확한 값이 추출되지 않는 문제가 있습니다.

센서 융합 기술
센서 융합 기술(Sensor Fusion)은 IMU와 같이 정보를 추출하기 위해 여러가지 센서의 정보를 종합적으로 활용해야 하는 경우 쓰는 기술입니다. IMU 센서 융합 기술의 대표적 예는 칼만 필터(Kalman's Filter)입니다. IMU센서를 쓰기 어려웠던 이유는 바로 센서 융합 기술 때문이었습니다.
 칼만 필터의 개념

IMU 센서의 대중화
IMU 센서는 가격 문제와 센서 융합의 어려움으로 쉽게 사용되지 못하다가 스마트 폰 및 드론 등으로 널리 대중화되게 되었습니다.
스마트 폰의 기울기 인식

드론의 자세 제어

이렇게 된데에는 바로 IMU기술을 IC칩으로 만들고 그 가격을 매우 저렴하게 하며 사용법이 쉬워짐에 있습니다. InvenSense사의 MPU 시리즈는 대표적인 IMU 센서 장치입니다.


아두이노와 MPU-XXXX
아두이노에서 MPU 시리즈가 활용되기 시작했는데, 모듈 형태인 Breakout 보드로 보급되고 수 많은 예제들이 나오게 되었습니다.
MPU-6050 Breakout Board

아두이노에서 가장 많이 사용되는 MPU시리즈는 다음과 같습니다.
  • MPU-6050/6500: 지자기 센서 미 포함
  • MPU-9150/9250: 지자기 센서 포함

따라서, 아두니티에서는 IMU 혹은 AHRS 기술을 유니티에서 사용하기 위해 가장 대중적으로 널리 알려진 MPU 시리즈를 선택했으며 이것을 제어하기 위한 ArdunityController를 MPUSeries라 부르는 것입니다.


MPUSeries의 설정은 다음과 같습니다.

  • id: ArdunityApp이 ArdunityController를 구분하기 위한 식별자
  • model: 현재 사용중인 MPU 모델 명
  • secondary: 2개를 동시 사용할 경우 선택 (두번째 MPUSeries에만 체크)
  • forward: MPU 보드의 전방 방향
  • up: MPU 보드의 위 방향
  • Enable update: 보드로부터 정보 갱신 여부
  • OnStartCalibration: 캘리브레이션 시작 이벤트
  • OnCalibrated: 캘리브레이션 완료 이벤트
MPUSeries를 사용하려면 유니티와 좌표계를 일치시켜야 합니다.
MPU보드의 좌표계

유니티의 좌표계

MPUSeries의 Sketch Option에서 유니티의 Forward와 Up방향을 어떻게 맞출 지에 대한 설정을 해야 합니다.

캘리브레이션(Calibration)
MPU 보드는 전원이 켜지고 초기화된 이후 센서 융합을 원활히 하기 위해 일정 시간동안 Calibration을 진행합니다. Calibration이 완료되기 전에는 값을 사용하지 않는 것이 좋기때문에 유니티에서 Calibration 완료 여부를 알 필요가 있습니다.
MPUSeries는 OnStartCalibration과 OnCalibrated 이벤트를 통해 이 시점을 알려줍니다.
MPUSeries는 보드와 연결되었을 때, Calibration 중인지를 메시지를 통해 알려줍니다.
MPUSeries의 Calibrating 안내문

MPUSeries가 Calibration 진행 중일 때에는 움직이지 않고 가만히 놔두는 것이 좋습니다. 움직이게 되면 Calibration이 빨리 끝나지 않습니다.
Calibration이 끝나게 되면 사용자 Calibration을 할 수 있는 메뉴가 나타나게 됩니다.
MPUSeries의 사용자 Calibration 메뉴

사용자 Calibration이란, MPU보드의 현재 Heading방향을 유니티의 기준 방향과 일치시켜주는 것을 의미합니다.
MPUSeries에서 이루어지는 Calibration은 2종류로써 다음과 같이 정리할 수 있습니다.
  • MPU Calibration: 보드가 초기에 자동 진행하며 유니티는 이벤트로 시점을 알 수 있다.
  • 사용자 Calibration: 유니티에서 필요에따라 현재 방향을 수정할 때 사용함. MPU Calibration이 완료되기 전에는 이 기능을 사용할 수 없다.



C# Script로 MPUSeries를 제어하는 예제는 다음과 같습니다.

using UnityEngine;
using System.Collections;
using Ardunity;

public class MyComponent : MonoBehaviour
{
 public MPUSeries mpu;
 
 void Awake ()
 {
   mpu.OnStartCalibration.AddListener(OnStartCalibration);
   mpu.OnCalibrated.AddListener(OnCalibrated);
 }

 void Update ()
 {
   Quaternion rot = mpu.rotation;
 }

 public void MPUCalibration()
 {
   mpu.Calibration();
 }

 void OnStartCalibration ()
 {
 }

 void OnCalibrated ()
 {
 }
}





2016년 8월 25일 목요일

구부림 센서 다루기

구부림 센서(Flex Sensor)는 구부러지는 정도에 따라 저항이 달라지는 특성을 갖고 있는 부품입니다.

이 센서의 아두이노 회로는 다음과 같습니다.

구부림 센서는 2 pin만 가지고 있으므로 변화된 저항 값을 측정하려면 전압 분배 회로를 만들어야 합니다.

이 회로를 유니티에서 다룰려면 아두니티 Wire Editor에 다음과 같이 연결하면 됩니다.

위 정보를 아두이노 스케치로 Export하고 보드에 업로드하면 유니티에서 구부림 센서를 다룰 수 있는 준비가 끝납니다.
실제로 보드와 유니티를 연결하여 실험을 해보면 구부림 정도에 따라 AnalogInput 값이 달라지는 것을 확인할 수 있지만, 그 변화 값이 제멋대로여서 쓰기가 쉽지 않습니다.

InputFilter
측정된 센서 값이 불안정할 때 사용되는 것이 바로 InputFilter입니다.


InputFilter 사용법에 대해서는 빛 센서 다루기에 자세히 나와있으니 참고하시기 바랍니다.
AnalogInput과 InputFilter를 연결하면 다음과 같습니다.


3D 물체 구부리기
구부림 센서는 손가락 구부림을 통해 여러 장치를 제어하는 데이터 글로브(Data Glove)란 장치로 활용될 수 있습니다.
이런 아이디어를 실현하기 위해 3D 모델로 손가락 모양을 만든 후 구부림 정도에 따라 같이 움직이면 재미있는 효과를 만들어 낼 수 있습니다.
먼저 Cube를 3개 만들어서 손가락의 3 마디를 표현합니다.

이 모양을 위한 GameObject 구조는 다음과 같이 표현됩니다.

나중에 한번 깊게 내용을 다루겠지만, 다관절 구조의 3D 모델을 표현할 때는 모양을 나타내는 GameObject와 관절을 나타내는 GameObject를 분리해서 표현하는 것이 좋습니다. 그 이유는 모양을 표현할 때 Transform의 Scale을 조정하게 되는데, Scale이 1이 아닌 경우 Parent가 회전하면 Child가 일그러지는 문제가 발생하기 때문입니다.

입력되는 값을 회전 각도로 변환하기 위해서는 MappingInput을 이용하면 됩니다. 단 MappingInput은 손가락의 관절 별로 따로 만들어야 합니다.
그 이유는 손가락의 움직임을 잘 관찰해보면 구부러짐에 따라 각 관절의 꺾임 정도가 다른 것을 확인할 수 있습니다.
MappingInput을 통해 각도가 추출되면 이것을 RotationAxisReactor로 GameObject를 회전시키면 됩니다.


구부림 센서 활용 영상을 통해 이 결과를 확인하시기 바랍니다.


 

온도 센서 다루기

온도 센서는 정말 종류가 많지만, 이 포스트에서는 TMP36이란 부품을 가지고 응용해보겠습니다.
TMP36

이 부품을 아두이노에서 사용하려면 다음과 같이 회로를 꾸밉니다.

TMP36은 온도에 따라 전압이 달라지기 때문에 Analog Pin의 값이 변하게 됩니다. TMP36의 데이터시트(Datasheet)를 확인하면 온도와 측정되는 전압 사이의 관계가 나와있습니다.

이 회로를 유니티에서 다루려면 아두니티 Wire Editor에 다음과 같이 연결하면 됩니다.

위 정보를 아두이노 스케치로 Export하고 보드에 업로드하면 유니티에서  TMP36을 다룰 수 있는 준비가 끝납니다.
실제로 보드와 유니티를 연결하여 실험을 해보면 0 ~ 1 사이의 값이 전달되는 것을 확인할 수 있지만, 이 값을 온도로 환산해야 뭔가 활용할 수 있을 것 같습니다.


MappingInput
AnalogInput의 값을 온도로 환산할 때 유용하게 사용할 수 있는 것은 MappingInput입니다.


MappingInput은 다음과 같은 설정이 필요합니다.
  • sourceName: 입력 항목의 이름
  • resultName: 출력 항목의 이름
  • mapCurve: 변환에 사용될 Mapping curve

Mapping Curve를 만들기 위해서는 TMP36의 특성 곡선을 잘 분석해야 합니다. 테이블 형태로 AnalogInput의 값과 온도 사이의 관계를 정의해보면 다음과 같습니다.
TMP36 특성곡선에 근거한 AnalogInput과 온도 사이의 관계

이것을 유니티 Curve Editor로 표현하면 다음과 같습니다.
AnalogInput과 온도 사이의 관계 Curve

이제 MappingInput을 AnalogInput에 연결하여 온도 값이 잘 변환되어 나오는 지 봐야 합니다.


온도를 텍스트로 보여주기
TextReactor는 Unity UI를 이용해서 측정된 온도를 텍스트로 보여주는 기능을 갖고 있습니다.


TextReactor는 다음과 같은 설정이 있습니다.

이것을 MappingInput과 연결하면 Unity UI의 Text로 온도가 표현됩니다.



여기까지의 응용을 영상으로 확인하시기 바랍니다.





유니티 물리 효과

3D 모델을 화면에 보여주는 기술은 렌더링(Rendering)이라 부르며, 이것을 처리해주는 소프트웨어를 렌더링 엔진(Rendering Engine)이라 부릅니다.
화면에 보이는 3D 모델을 움직이게 하기 위해서는 애니메이션(Animation) 효과를 줘야 합니다. 일반적으로 애니메이션을 만드는 방법은 다음과 같습니다.
  • 수치 해석적 방법(Numerical Method)으로 움직임을 만든다.
  • 키 프레임(Key Frame)을 정해주고 이를 연속적으로 재생(Playback)하여 움직임을 만든다.
수치 해석적 방법은 매우 부드럽게 움직일 수 있는 장점이 있지만, 복잡한 움직임의 경우는 표현하기가 매우 어려운 단점이 있습니다.
반면에 재생 방식은 어떤 움직임이든 표현할 수 있는 장점이 있지만, 키 프레임을 만들기가 어려운 단점이 있습니다.
수치 해석적 방법으로 애니메이션을 만드는 예
키 프레임을 재생하여 애니메이션을 만드는 예

3D 애니메이션 분야에서는 이 문제를 해결하기 위해 오랫동안 방법을 연구해왔습니다.
키 프레임 재생 방식 분야는 애니메이션을 보다 자연스럽고 편리하게 만들 수 있도록 도구가 발달했습니다. 3ds Max나 Maya등 애니메이션 전문 도구가 등장하여 키 프레임 생성의 어려움을 많이 극복했습니다.
3ds Max의 애니메이션 제작 모습

수치 해석적 방법은 자연 현상을 재현하는 방향으로 발전했는데, 이것이 바로 시뮬레이션(Simulation)입니다. 자연에 존재하는 여러 힘(중력, 마찰력 등)을 고려하여 어떤 물체가 움직이는 경로를 계산하는 것이 시뮬레이터(Simulator)입니다.
군사 훈련에 활용되는 시뮬레이션 기술

초기에는 이 시뮬레이션 기술이 군사, 산업 등 전문 분야에서만 활용되었습니다. 그러나, 이 기술이 점차 게임이나 영화등에 활용되기 시작했습니다.
이렇게 3D 모델을 현실과 비슷하게 움직이게 만드는 효과를 물리(Physics) 효과라 부르고, 이것을 처리해주는 소프트웨어를 물리 엔진(Physics Engine)이라 부릅니다.
유니티에는 이 물리 엔진이 내장되어 있고, 여러분들은 이 기술을 이용해서 3D 모델을 현실감있고 자연스럽게 움직일 수 있습니다.


RigidBody
유니티에서 GameObject를 물리 엔진에 의해 움직이게 하려면 강체(RigidBody)라는 Component가 추가되어야 합니다.

Rigidbody Component의 설정에 관해 자세히 알고 싶다면 유니티 공식 튜토리얼을 보기 바랍니다.
Rigidbody만 추가한다고 바로 3D 모델이 힘의 영향을 받아 움직이는 것이 아닙니다. 반드시 유니티를 재생(Play) 모드로 만들어야 그때부터 물리 엔진이 Rigidbody들을 움직입니다.


Collider
충돌체(Collider)는 물리 엔진이 Rigidbody들이 서로 부딪치는 효과를 내기 위해 필요합니다. 만약, Rigidbody가 Collider를 갖고있지 않다면 그냥 뚫고 지나가는 모습을 보게 될 것입니다.
3D 그래픽 외형의 모습은 Mesh 데이터를 이용해서 보여주지만, 충돌을 계산하기 위한 Collider는 계산량을 줄이기 위해 단순한 모양을 많이 사용합니다.

물론, 3D 모델의 모양과 최대한 근접하게 표현할 수 있는 Collider 사용도 가능하지만, 꼭 필요한 경우가 아니라면 추천하지는 않습니다.

Collider에 대한 더 자세한 이해가 필요하다면 유니티 공식 튜토리얼을 보시기 바랍니다.


Physic Material
마찰력이나 탄성력 등은 두 물체가 부딪칠 때 많은 영향을 주는 요소입니다. 유니티 물리 엔진에서도 이 요소를 표현하여 더 자연스러운 움직임을 만들 수 있습니다.
Collider는 Physic Material이란 것을 사용해서 마찰력과 탄성력을 표현합니다.
Physic Material은 Project Window에서 만들 수 있고, 만든 Physic Material을 반드시 Collider에 적용해야 효과가 나타납니다.
Physic Material 생성 메뉴

Physic Material 속성

Physic Material에 대한 더 자세한 이해가 필요하다면 유니티 공식 튜토리얼을 보시기 바랍니다.


Physics Joint
유니티 물리 엔진은 Rigidbody들이 서로 연결되어 움직이는 조인트(Joint) 효과를 지원합니다.
이 기능을 이용하면 사슬이나 문 등을 표현할 수 있고, 심지어 깨지는 창문 등도 만들 수 있습니다.

 유니티 공식 튜토리얼을 통해 Physics Joint로 뭘 할 수 있는지 확인해 보시기 바랍니다.