コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

センサコマンドによる加速度センササンプル修正版

Luaridaにセンサ関連命令を追加したので、以前紹介したセンササンプルが動作不可になりました。そこで、修正したので、報告しておきます。

加速度サンプルの修正

加速度センサからデータを取得するには、sensor.setdevAccel(1)として、センサ使用可にする必要があります。また、今回、新たにsensor.getGdirection()という命令を追加しました。これは画面上の重力方向の角度を返すコマンドです。
加速度センササンプルはこちらからダウンロードできます(GsensorSample.apk)。
回転サンプルはこちらからダウンロードできます(RotateSample.apk)。
では、動画をどうぞ。

加速度センサ使用サンプル動画

使用コマンド

センサコマンドとして使用しているのは、sensor.setdevAccel()とsensor.getAccel()とsensor.getGdirection()です。

  • sensor.setdevAccel(ON/OFF設定)

setdevAccelは、加速度センサの使用可/不可の切り替えを行います。引数0の場合は不可、1の場合は使用可となります。
また、このコマンドは戻り値を持ち、センサの使用が可能であれば、0が返り、センサ使用不可の場合は、-1が返ってきます。よって、実際には下記のように記述した方がいいと思います。

if(sensor.setdevAccel(1)==-1)then
  toast("加速度センサが使用不可です。画面タッチで終了します", 0 )
  touch(3)
  return
end
  • sensor.getAccel()

従来のままです。X,Y,Z成分の加速度を返します。

x, y, z = sensor.getAccel()
  • sensor.getGdirection()

getGdirectionは、今回追加したコマンドです。戻り値を3つ持ちます。

gdirection, gcomp, zcomp = sensor.getGdirection()

第1戻り値は、画面上の重力の向きです。画面下方向が0度となるような角度が返ります。第2戻り値は画面上の重力成分です。X軸方向の加速度とY軸方向の加速度の合成値です。第3戻り値はZ軸方向の加速度成分です。
getGdirection()の戻り値を用いて、サンプルではドロイド君が常に足が下になるように移動しています。
下記が、全ソースです。

------------------------------------------
--加速度センササンプル
------------------------------------------
--関数宣言--------------------------------
main={}  --mainメソッド
--グローバル変数宣言----------------------
Path = "/sdcard/luarida/gsensorsample/"
------------------------------------------
mt={}
mt.__newindex=function(mtt,mtn,mtv)
 dialog( "Error Message", "宣言していない変数 "..mtn.." に値を入れようとしています", 0 )
 toast("画面タッチで実行を続けます", 1)
 touch(3)
end
mt.__index=function(mtt,mtn)
 dialog( "Error Message", "変数 "..mtn.." は宣言されていません", 0 )
 toast("画面タッチで実行を続けます", 1)
 touch(3)
end
setmetatable(_G,mt)
--------以下が実プログラム----------------
------------------------------------------
--メインプログラム
------------------------------------------
function main()
local ax, ay, az
local a, cl
local w, h, px, py
local x,y,s
local lx,ly
local gdir
local wb,hb
 --ワークエリア画面をクリアします
 canvas.workCls()
 --ワークエリアの(0,0)-(79,93)に、アンドロイド画像を読み込みます
 if( canvas.loadBmp( Path.."droidkun.png", 0, 0, 79, 93 )==-1)then
   dialog( Path.."droidkun.png", "ロードに失敗しました",1 )
   do return end
 end
 --ワークエリアの(80,0)-(559,299)に背景画像を読み込みます
 if( canvas.loadBmp( Path.."kareudon.png", 80, 0, 559, 299 )==-1)then
   dialog( Path.."kareuson.png", "ロードに失敗しました",1 )
   do return end
 end
 --画面サイズ取得
 w,h = canvas.getviewSize()
 w = w-1
 h = h-1
 wb = 80+w
 hb = h
 px = w/2
 py = h/2
 --背景を描きます
 canvas.putg( 0, 0, w, h, 80, 0, 559, 299 )
 --ドロイド君を描きます
 canvas.putg( px, py, px+79, py+93, 0, 0, 79, 93 )
 --フラッシュしないと画面に反映しません
 canvas.putflush()
 --加速度センサ起動
 sensor.setdevAccel(1)
 toast("ドロイド君をタッチすると終了します", 1 )
 lx = 0
 ly = 0
 while(true)do
   --加速度を取得
   ax, ay, az = sensor.getAccel()
   lx = lx + ay
   px = px + lx
   if(px<40)then
     px = 40
     lx = 0
   elseif( px>w-40 )then
     px = w-40
     lx = 0
   end
   ly = ly + ax
   py = py + ly
   if(py<47)then
     py = 47
     ly = 0
   elseif( py>h-47 )then
     py = h-47
     ly = 0
   end
   --背景描画
   canvas.putg( 0, 0, w, h, 80, 0, 559, 299 )
   --重力の向き取得
   gdir = sensor.getGdirection()
   --ドロイド君描画
   canvas.putrotg( px, py, gdir, 0, 0, 79, 93 )
   --画面更新
   canvas.putflush()
   --ドロイド君タッチで終了
   x,y,s = touch()
   if( s~=1 )then
     if( x>=px-40 and x<=px+40 and y>=py-46 and y<=py+46 )then
       break
     end
   end
 end
 --加速度センサ終了
 sensor.setdevAccel(0)
end
main()

ドロイド君回転サンプルの修正

センサコマンドの変更により、RotateSampleも動作しなくなりました。そこで、修正したソースを書いておきます。変更箇所は、sensor.setdevAccel()を追加しただけです。

------------------------------------------
--回転サンプル
------------------------------------------
--関数宣言--------------------------------
main={}     --mainメソッド
filter={}   --一次フィルタ
moveave={}  --移動平均
rawdata={}  --生データ
------------------------------------------
Path="/sdcard/luarida/rotatesample/"	--luaファイルを保存しているPath
------------------------------------------
mt={}
mt.__newindex=function(mtt,mtn,mtv)
 dialog( "Error Message", "宣言していない変数 "..mtn.." に値を入れようとしています", 0 )
 toast("画面タッチで実行を続けます", 1)
 touch(3)
end
mt.__index=function(mtt,mtn)
 dialog( "Error Message", "変数 "..mtn.." は宣言されていません", 0 )
 toast("画面タッチで実行を続けます", 1)
 touch(3)
end
setmetatable(_G,mt)
--------以下が実プログラム----------------
------------------------------------------
-- 移動平均
------------------------------------------
function moveave()
local ax={}
local ay={}
local az
local axt, ayt
local i
local n = 10
local aax,aay
local w,h
local wb, hb
local kaku
local cx, cy
local pi = 3.141592
local x,y,s
local angle
local moji
 moji,s = editText("移動平均を取る数を入力してください(n=1〜)")
 if( s==nil or moji==nil or moji=="" or tonumber(moji)==nil )then
   n = 4
 elseif( s==1 )then
   n = tonumber( moji )
 else
   n = 4
 end
 toast( n.."個の移動平均を取ります", 0 )
 --画面サイズ取得
 w,h = canvas.getviewSize()
 w = w-1
 h = h-1
 wb = 80+w
 hb = h
 cx = w/2
 cy = h/2
 axt = 0
 ayt = 0
 for i=1,n do
   ax[i], ay[i] = sensor.getAccel()
   axt = axt + ax[i]
   ayt = ayt + ay[i]
 end
 toast("ドロイドをタッチすると終了します", 0 )
 i = 1
 while(true)do
   axt = axt - ax[i]
   ayt = ayt - ay[i]
   --加速度を取得
   ax[i], ay[i] = sensor.getAccel()
   axt = axt + ax[i]
   ayt = ayt + ay[i]
   --kaku = math.atan2( -(ayt/n), (axt/n) )
   kaku = math.atan2( -ayt, axt )
   angle = math.floor(kaku/pi*180)
   x = math.sin(kaku)
   y = math.cos(kaku)
   i = i + 1
   if( i>n )then i=1 end
   canvas.putg( 0, 0, w, h, 80, 0, wb, hb )
   canvas.putrotg( cx, cy, angle, 0, 0, 79, 93 )
   canvas.drawTextRotate("θ="..angle, cx-70*x, cy+70*y, angle, 24, color(255,0,0))
   --画面タッチで終了
   x,y,s = touch()
   if( s~=1 )then
     if( x>=cx-79/2 and x<=cx+79/2 and y>=cy-93/2 and y<=cy+93/2 )then
       break
     end
   end
 end
end
------------------------------------------
-- 生データ
------------------------------------------
function rawdata()
local ax,ay,az
local aax,aay
local w,h
local wb, hb
local kaku
local cx, cy
local pi = 3.141592
local x,y,s
local angle
 --画面サイズ取得
 w,h = canvas.getviewSize()
 w = w-1
 h = h-1
 wb = 80+w
 hb = h
 cx = w/2
 cy = h/2
 toast("ドロイドをタッチすると終了します", 0 )
 while(true)do
   --加速度を取得
   ax, ay, az = sensor.getAccel()
   kaku = math.atan2( -ay, ax )
   angle = math.floor(kaku/pi*180)
   x = math.sin(kaku)
   y = math.cos(kaku)
   canvas.putg( 0, 0, w, h, 80, 0, wb, hb )
   canvas.putrotg( cx, cy, angle, 0, 0, 79, 93 )
   canvas.drawTextRotate("θ="..angle, cx-70*x, cy+70*y, angle, 24, color(255,0,0))
   --画面タッチで終了
   x,y,s = touch()
   if( s~=1 )then
     if( x>=cx-79/2 and x<=cx+79/2 and y>=cy-93/2 and y<=cy+93/2 )then
       break
     end
   end
 end
end
------------------------------------------
-- 一次フィルタ
------------------------------------------
function filter()
local ax,ay,az,axo,ayo
local aax,aay
local w,h
local wb, hb
local kaku
local omomi = 0.85
local cx, cy
local pi = 3.141592
local x,y,s
local angle
local moji
 --画面サイズ取得
 w,h = canvas.getviewSize()
 w = w-1
 h = h-1
 wb = 80+w
 hb = h
 cx = w/2
 cy = h/2
 moji,s = editText("フィルタ係数を入力してください(0<=〜<1)")
 if( s==nil or moji==nil or moji=="" or tonumber(moji)==nil )then
   omomi = 0.8
 elseif( s==1 )then
   omomi = tonumber( moji )
   if( omomi<0 or omomi>=1 )then omomi = 0.8 end
 else
   omomi = 0.8
 end
 toast( "フィルタ係数を "..omomi.."に設定しました", 0 )
 toast("ドロイドをタッチすると終了します", 0 )
 axo, ayo, az = sensor.getAccel()
 while(true)do
   --加速度を取得
   ax, ay, az = sensor.getAccel()
   axo = axo*omomi + ax*(1-omomi)
   ayo = ayo*omomi + ay*(1-omomi)
   kaku = math.atan2( -ayo, axo )
   angle = math.floor(kaku/pi*180)
   x = math.sin(kaku)
   y = math.cos(kaku)
   canvas.putg( 0, 0, w, h, 80, 0, wb, hb )
   canvas.putrotg( cx, cy, angle, 0, 0, 79, 93 )
   canvas.drawTextRotate("θ="..angle, cx-70*x, cy+70*y, angle, 24, color(255,0,0))
   --画面タッチで終了
   x,y,s = touch()
   if( s~=1 )then
     if( x>=cx-79/2 and x<=cx+79/2 and y>=cy-93/2 and y<=cy+93/2 )then
       break
     end
   end
 end
end
------------------------------------------
--メインプログラム
------------------------------------------
function main()
local w,h
local wb, hb
local k
 --ワークエリアをクリアする
 canvas.workCls()
 --ワークエリアの(0,0)-(79,93)に、アンドロイド画像を読み込みます
 if( canvas.loadBmp( Path.."droidkun.png", 0, 0, 79, 93 )==-1)then
   dialog( Path.."droidkun.png", "ロードに失敗しました",1 )
   do return end
 end
 --画面サイズ取得
 w,h = canvas.getviewSize()
 w = w-1
 h = h-1
 wb = 80+w
 hb = h
 --背景を白にする
 canvas.drawCls( color(255,255,255) )
 --画面を背景にするために、ワークエリアに取り込む
 canvas.getg( 0, 0, w, h, 80, 0, wb, hb )
 --加速度センサ起動
 sensor.setdevAccel(1)
 while(true)do
   item.clear()
   item.add( "一次フィルタ", 0 )
   item.add( "移動平均", 0 )
   item.add( "フィルタ無し", 0 )
   item.add( "終 了", 0 )
   k = item.list( "どのフィルタを選びますか" )
   if( k==1 )then
     filter()
   elseif( k==2 )then
     moveave()
   elseif( k==3 )then
     rawdata()
   elseif( k==4 )then
     break
   end
 end
 --加速度センサ終了
 sensor.setdevAccel(0)
end
main()