2012年7月31日火曜日

[ドリトル] センサー

センサー付きのタートルを作ってみよう。
  • 自身から伸びるアンテナ(ヒゲ?)を持つ
  • アンテナは周期的に自身の周りを回転する。
  • 何かがアンテナに触れるとタートルはその時のアンテナの方を向く。
周りにエサを配置してアンテナがそれに触れたらそちらに向かう感じで。

SENSOR_LENGTH = 150.
t1 = Turtle ! create.
t1:sensor = t1 ! 1 linewidth (SENSOR_LENGTH) forward makeFigure.
t1 ! penup movetocenter (blue) lineColor pendown.
t1:sensor:body = t1.
t1:sensor:collision = [ | object |
  [object != self:body] ! then 
  [self:body ! (self!direction?) direction ] execute.
].
t1:start = [ | ; timer1 |
   self:timer = Timer ! create.
   self:timer ! 0.05 interval 600 duration.
   self:timer ! [
     self:sensor ! 10 leftturn. ] execute.
]. 
t1:forward = [ | x ; forward |
   ! (x) forward.
   self:sensor! (self ! xPosition?) (self ! yPosition? ) moveto.
   self.
].
t1:moveto = [ | x y ; moveto |
   ! (x) (y) moveto.
   self:sensor! (x) (y) moveto.
   self.
].

t1 ! start. 

[ Turtle ! create "apple.png" setShape penup (random(300) - 150) (random(300) - 150) moveto.
] ! 10 repeat.

t1 ! penup -200 -100 moveto pendown 0 direction.
//t1 ! penup -200 forward pendown.
timer1 = Timer ! create.
timer1 ! 0.1 interval 600 duration.

t1:collision = [ |object| 
   [object != sensor ] ! then [ object ! hide ] execute.
]. 
timer1 ! [ t1 ! 5 forward. ] execute.  

アンテナは左回りに回転している。
タートルはとにかくアンテナが触れた方向に向きを変えるので、目の前に標的があってもアンテナが他のエサに触れるとためらいなく向きを変えてそちらに向かっていく。超目移り型。

アンテナが左回転している関係で、複数のが隣接して存在する場合には必ず向かって左側に向かうことになる。先に触れた右側に向かうのだがすぐにそのあとに触れる左側の隣接に向きを変えてしまう。
少し離れた2つの隣接の間に入り込むと、永遠にそれらの間を往復する動きになる。

いろいろと改善の余地がありそうだがとりあえずはこの辺で。



先ほどは静止目標だったが今度は移動体に対する追随を試してみよう。

SENSOR_LENGTH = 150.
t1 = Turtle ! create 0.7 scale.
t1:sensor = t1 ! 1 linewidth (SENSOR_LENGTH) forward makeFigure.
t1 ! penup movetocenter (blue) lineColor pendown.
t1:sensor:body = t1.
t1:sensor:collision = [ | object |
  [object:target == true] ! then 
  [self:body ! (self!direction?) direction ] execute.
].
t1:start = [ | ; timer1 |
   self:timer = Timer ! create.
   self:timer ! 0.03 interval 600 duration.
   self:timer ! [
     self:sensor ! 5 leftturn. ] execute.
]. 
t1:forward = [ | x ; forward |
   ! (x) forward.
   self:sensor! (self ! xPosition?) (self ! yPosition? ) moveto.
   self.
].
t1:moveto = [ | x y ; moveto |
   ! (x) (y) moveto.
   self:sensor! (x) (y) moveto.
   self.
].

t1 ! start. 
target = Turtle ! create "apple.png" setShape penup 0 -20 moveto 0.7 scale.
target ! 1 linewidth (red) linecolor pendown.
target:target = true.

t1 ! penup -200 0 moveto pendown 0 direction.
//t1 ! penup -200 forward pendown.
timer1 = Timer ! create.
timer1 ! 0.1 interval 600 duration.

t1:collision = [ | object | 
   [object != sensor ] ! then [ object ! hide ] execute.
].
timer1 ! [ 
  t1 ! 5 forward.
  target ! 4 forward 2 leftturn. 
] execute.

標的に対するあたり判定を小さくするためにタートル/標的ともに小さくしたのだが、 センサーがすり抜けてしまうことがあるのでセンサーの判定密度を少し上げてある。
タートルのほうが多少速いのでこのくらいであれば一周せずに標的に到達する。

標的の速度をタートルと同じにするとついては行くが追いつかない。
標的の初期位置がさっきと同じだと逃げられるので少し調整してある。

...
target = Turtle ! create "apple.png" setShape penup 0 -50 moveto 0.7 scale.
...
  target ! 5 forward 2 leftturn. 
] execute.

センサーのタイマーのインターバルを小さくすると標的への追随性がよくなる。
またこの場合は左回りに逃げる標的なので実はセンサーは右回りにしたほうが軌道修正が早くなるので追随性がよくなるようだ。右回り左周りの2本のセンサをつけてやればもっと追随性がよくなるかもしれない。

0 件のコメント:

コメントを投稿