プチコン3号 13日目 本体を傾けてキャラクタを動かす

3DSは移動や傾きを検出するモーションセンサがついています。今回はこれを使って、9日目のプログラムを傾きでコントロールするように変更してみました。

3DSには加速度センサが搭載されていて、平行移動(前後上下左右)の「加速度」、および回転(ピッチ、ロール、ヨー)の「速度」を計測できます。
SmileBASICではその値を読み出すことができるほか、回転については、時間軸に沿って速度を積算することで、トータルの回転角も得られるようになっています。
今回は、このトータルの回転角を使って、下画面が水平のときはキャラクタは静止し、画面を傾けたときは傾いた方向へ移動するようなプログラムを作ってみました。

座標がX、Y、Zの3つの軸で表されるのと同様、角度も以下の3つの値で表されます。

(1)X軸の周りでの回転(ピッチ)
(2)Y軸の周りでの回転(ロール)
(3)Z軸の周りでの回転(ヨー)

いずれも、原点から座標軸の正の方向を見て左回りで角度を測ります。

pc13-1.jpg

SmileBASICで値を読み出すには、

GYROA OUT P,R,Y

とします。
P,R,Yにそれぞれピッチ、ロール、ヨーの値が入ります。

このとき、角度の値は「度」ではなく「ラジアン」という単位で与えられます。
ラジアンで計測すると、180度がπ(パイ)ラジアンになります。
πは円周率のπ、すなわち3.14159265…です。
逆方向へ傾けた場合は負の値になりますので、角度の値の範囲は-πからπまでです。

なおGYROAコマンドを使うには、あらかじめ

XON MOTION

でモーションセンサをオンにしておかなければなりません。

また、先に書いたようにGYROAで読み出すトータルの回転角は、実際には回転の速度を積算したものです。
そのため、長期間使っていると誤差が出てきます。
水平位置に戻しても、水平ではなく角度がついているように認識される、ということが起こります。
これをリセットするには

GYROSYNC

命令を使います。
この命令を実行すると、その時点で3つの角度が全てゼロにリセットされます。

それではプログラムリストです。
実行すると下画面にキャラクタが表示され、画面を傾けるとトコトコと歩きます。
表示関連は、9日目の記事で説明しましたので今回は説明は省略します。

pc13-2.jpg
XSCREEN 2,255,2
DISPLAY 1
GX=184:GY=104:GC=2904
C=GC+4:C_OLD=GC
SPSET 0,C
SPSCALE 0,2,2
XON MOTION
GYROSYNC
@LOOP
SPOFS 0,GX,GY
IF C != C_OLD THEN
SPANIM 0,"I",15,C+1,15,C+2,15,C+3,15,C,0
C_OLD = C
ENDIF
IF BUTTON(1) AND 16 THEN GYROSYNC
GYROA OUT P,R,Y
DX=0:DY=0
IF ABS(P) > 0.05 THEN DY=SGN(-P)
IF ABS(R) > 0.05 THEN DX=SGN(R)
GX=MAX(MIN(GX+DX,384),0)
GY=MAX(MIN(GY+DY,224),0)
C=(3-(DY>=0)*(DX+2))*4+GC
IF DY != 0 || DX != 0 THEN
SPSTART 255
ELSE
SPSTOP 255
ENDIF
VSYNC 1
GOTO @LOOP

初期設定として

XON MOTION
GYROSYNC

を実行しています。
そのあとループの中で

IF BUTTON(1) AND 16 THEN GYROSYNC

としていますので、Aボタンを押せばいつでも角度の誤差をリセットできます。

次にGYROAで角度を読み出していますが、そのあと

IF ABS(P) > 0.05

というように値の絶対値をチェックしています。
これは、水平からある程度傾いたときに初めて「傾いた」と認識させるためです。
0.05ラジアン以上傾いたときのみ、DXとDYに値を設定しています。
ちなみに0.05ラジアンは、180*(0.05/3.14)=2.87度くらいです。

また、ピッチについては、上の図からも判るとおり、画面を手前から向こうへ傾けたときに正の値になりますが、このときキャラクタを画面上に向かって(Y座標が小さくなる方向へ)歩かせるので、ピッチの値とDYは正負が逆になります。

今回はこれで終わりです。
角度での入力は、単純にパッドやタッチパネルの代わりに使うよりも、物理的な動きをシミュレートするときなどに使うと良さそうです。

コメント