티스토리 뷰

주말은 또 쉬고 다시 Ready Set Go! 입니다!!

제가 다른 안드로이드나 아이폰 관련 SDK를 다뤄보지 못해서 잘 모르겠지만 윈폰 SDK를 보면서 신기하게 느꼈던건

바로 이 센서 부분을 디버깅을 할 수 있다는게 아닌가 싶네요. 물론 이전에 다뤘던 카메라도 어떻게 보면 폰에 붙어있는 디바이스를 다루는 면에서 신선했었지요 ㅎㅎ

이번 시간에는 폰에 붙어있는 센서를 다뤄보는 것에 대해 언급해보고자 합니다.

우선 사전에 인지되어야 하는 점은 윈폰의 스펙은 거의다 대동소이하다는 점입니다. 다만 플래그쉽급 폰과 같은 경우는 일반 보급형에 비해서 자이로스코프가 달렸다던가 하는 차이가 있겠지만, 그 이상의 것은 균일하다는 점이 특징입니다.
안드로이드야 기기가 천차만별이니까 언급할 것도 없고, 아이폰은 나오는게 하나니까 말할 것도 없겠지요..

제일 먼저 다룰 내용은 가속도계라는 겁니다.

이걸 응용한다면 폰을 움직여서 하는 게임도 구현할 수 있겠고 더 나아가서는 Argument Reality 같이 심오한 주제도 구현할 수 있을거라고 봅니다.

그 걸 표현하는 방법에는 위치로 지정하는 방법과 벡터로 표현하는 방법이 있습니다. 위치로 표현하면 그 점밖에 표현할 수 없지만, 벡터로 표현한다면 점까지의 방향과 세기까지 표현할 수 있다는 게 특징이겠지요. 물론 쓰임새가 각각 틀립니다. 그리고 실버라이트와 XNA내에서도 구현하는 방법이 조금 다르기도 하고요..

물론 읽으시는 분들이 물리 수업을 들으셨다면 벡터가 뭐고 위치가 뭐니 하는 개념이 있으시겠지만 이 글을 읽는 대상은 모두를 포괄해야 되기 때문에 그냥 예제로 설명해보고자 합니다.
무엇보다도 기억해야 되는 건 윈폰은 "3차원 좌표계를 갖춘 디바이스" 라는 겁니다. 책에도 언급이 되어 있네요.

우선 가속도계를 사용하기 위해선 using 지시자로 Microsoft.Devices.Sensors를 포함 시켜야 합니다.
거기에 기존에는 언급이 안되었던 WMAAppManifest.xml을 수정해야 합니다.

일단 SilverlightAccelerometer라는 이름으로 프로젝트를 만듭니다.
그리고 
WMAAppManifest.xml에 다음과 같이


Sensor에 관한 값을 받아올 수 있게끔 삽입해줘야 합니다.
 
 그리고 맨처음 helloworld때 했던 것처럼 txtblk를 삽입합니다. 중앙에 오도록 해야 되겠지요.

 
그리고 .cs파일을 다음과 같이 수정해줍니다.

엇 근데 들어가기에 앞서서 다음과 같은 오류가 출력되네요.


 Sensors라는 네임 스페이스를 못쓴다고 하네요. 이게 어떻게 된걸까요?

이는 reference가 삽입되어 있지 않기 때문입니다. 저만 겪는 현상일수도 있겠지만 저도 clean하게 설치한 이상 이 문제가 다른사람한테도 야기가 될거라 생각되네요. 다음과 같이 해주시면 됩니다. 일단 프로젝트속 reference에 마우스를 우클릭하시고 add a reference를 선택합니다.

 


그럼 아마 .net 탭 맨위에 보시면 다음과 같이



 Sensors에 대한 component가 있을 겁니다. 이를 삽입해줘야 합니다. 그러면 위와 같은 오류가 발생하지가 않지요. 책에는 이부분에 대한 설명이 빠진 것 같습니다.

일단 삽입하고 MainPage의 .cs파일을 다음과 같이 수정합니다.

 

이때 새롭게 나오는 개념이 바로 try catch 구문인데요. 이는 실행시 예외 구문에 대한 처리를 할 때 사용됩니다.

앞에서 나온 ReadingChanged라는 이벤트는 뒤에서 짜지겠지만 개체로 앞에서 언급한 벡터의 요소 X Y Z를 double형으로 가져오고 DateTimeOffset 형의 Timestamp를 갖습니다. 결과적으로 이벤트가 발생하면서 가속도계의 정보가 txtblk에 들어가는 text로 나오게 되는 거지요.


잠깐 책에 나온 배경지식에 대해서 인용을 해드릴게요.
- 실버라이트 앱에서 모든 사용자의 인터페이스 요소와 개체들은 메인 실행 스레드에서 생성되고 접근되어 사용된다 때로는 UI관련 스레드를 호출하기도 하는데 가끔 스레드가 동시에 한 정보에 접근하는 것을 실버라이트 내에서 허용하지 않는다.
결론적으로 개발자가 UI를 갖지핞은 스레드를 보유하고 있을때는 UI를 갖는 개체에 바로 접근하는게 안된다.

라는게 주요 내용인데.. 어렵네요.
그냥 핵심적인 내용은 UI를 가지지 않은 상태에서는 system.Windows.Threading에 정의되어 있는 dispatcher를 사용해서 해결하라는 점이네요. 말그대로 dispatcher는 붙였다 땠다하는 거로 Non-UI 스레드가 UI스레드로 데이터를 넘길때 정보를 변환해주는 정도로 보시면 될듯합니다. 예를 들면서 가기로 하겠습니다.


뭔가 복잡해보이는 format도 있고 수학식도 있네요. 거기에 전에 언급한 Dispatcher 개체도 포함되어 있군요.

밑에 있는 OnAccelometerReadingChanged는 중간의 SetTextBlockText를 호출하되 이전에 checkAccess를 써서 호출할 수 있으면 위의 Text를 부르고 아니면 밑에 있는 BeginInvoke라는 메서드를 부르게 되지요.

실행 결과는 다음과 같습니다.


보이는 것처럼 X,Y,Z에 대한 벡터값을 보여주는 겁니다.

위와 같은 코드를 조금더 간략하고 효율적으로 구현할 수 있다더군요.


조금 생소한 문법이 들어가있네요. 그렇긴 하지만 위의 코드처럼 delegate 관련 항목을 복잡하게 쓰지 않아도 되서 좋긴 하네요. 책에 언급된 바에 따르면 이전 코드는 스레드간 통신을 위한 코드이고 지금의 코드는 이벤트 핸들러에서 추가적인 메서드나 위임자를 사용할 때 사용한다고 합니다. BeginInvoke 호출시 익명 메서드를 생성하기 위함이고 또 다음과 같이 표현 하는 방법도 있다고 합니다.


차이가 거의 없어보이지만 실제로는 delegate라는 위임자가 사라졌습니다. 이처럼 익명 메서드를 정의하는 방식을 Lambda expression이라고 하는군요.

가만히 있어보니까 중간에 warning이 뜹니다.


글쎄요.. 이부분은 좀 확인해봐야 될거 같습니다. 확인해보고 수정하겠습니다.

이제 결과물입니다. 신기한 것도 같이 보여드릴게요.


다음과 같이 결과가 나옵니다. Y가 -1이 나오는 이유는 이 에뮬레이터는 폰이 누어져 있는 상태라고 인식하고 디버깅하기 때문입니다. 그런데 동영상 중간에 보면 갑자기 뭔가 딱 튀어 나와서 값이 변하는 것을 보실수 있었을 겁니다.
바로 Additional Tool이라는 겁니다.


에뮬레이터 옆에 마우스를 대시면 화살표가 있는데 이게 바로 Additional Tool을 활성화 시키는 버튼입니다. 그러면 


여기서 Orientation을 변화를 줘서 값이 변하는 것을 확인할 수 있었던 겁니다.

지금까지가 가속도계를 테스트 해본 앱이었습니다.
다음 포스팅에서는 가속도계를 이용한 간단하면서 유용한 툴인 bubble level 에 대해서 언급해보고자 합니다.

http://www.silverlightshow.net/items/XNA-for-Silverlight-developers-Part-6-Input-accelerometer.aspx 

참고로 영어가 능숙하신 분이라면 위 링크에 가보셔서 어떤식으로 가속도계가 형성되는지 확인해보시기 바랍니다. 
댓글