[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lpylajp@psychology.nottingham.ac.uk: Fly Vision and Swarm quality.]



Here's a hack-in-progress that approximates visibility by preloading
line-of-sight data into each patch.

They way the demo works, you can draw obstacles in any color, and then
move your mouse around like a light, seeing what shadows it casts.

I simulated an array patch variable by writing a few long repetitive
procedures. Apparently this can be avoided by using some undocumented
indexing functions, but I haven't yet gone further with this. Another
issue is that currently you can only test visibility between turtles,
although logically you should be able to ask if any patch is visible
from any other patch. Once Starlogo allows patches to execute the
towards-nowrap function, this will be easier to implement. At that point
one could also look at recursively bisecting lines-of-sight between
turtles to get more accurate results when turtles are more distant from
each other.

I realize the foregoing comments may be cryptic. Try the demo (see the
info window for instructions and comments) and then we can talk if
you're still interested.

Cheers /Chris

Mitchel Resnick wrote:
> 
> Isn't this the same problem you were working on (with Bill flocking
> program)?
> 
> ------- Start of forwarded message -------
> Resent-From: Ilya Kaplun <ilya@mit.edu>
> Date: Thu, 12 Feb 1998 13:02:10 +0000 (GMT)
> From: Andy Pope <lpylajp@psychology.nottingham.ac.uk>
> X-Sender: lpylajp@upsyc
> To: Starlogo-users <starlogo-users@media.mit.edu>
> Subject: Fly Vision and Swarm quality.
> Mime-Version: 1.0
> Content-Type: TEXT/PLAIN; charset=US-ASCII
> X-UIDL: b9f96ecb4f3bca3b8b46745ac3526e65
> 
> Hello,
> 
> I am updating the Poggio + Poggio fly swarming algorithm as a university
> project, building on the previously existing Starlogo simulation.  I have
> already added a graph of swarm-size and a slider allowing the control of the
> flies' field-of-view angle (previously set at 360).  This is for an AI
> project looking into how much information about each other agents need to
> swarm/perform group tasks effectively.
> 
> What I would like is some advice (in algorithmic form if not actual code)
> on how to update the program to include obstacles, ie. so flies cannot see
> each other if a wall is in the way.
> 
> Thankyou!
> 
> Andrew Pope
> ------- End of forwarded message -------

application/applefile

patches-own [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15]
; the vn variables encode how far one can see, looking out in
; each of 16 directions, from this patch
turtles-own [dist iline interpolator tmp]
globals [count]
to vn :num
if :num = 0 [output v0]
if :num = 1 [output v1]
if :num = 2 [output v2]
if :num = 3 [output v3]
if :num = 4 [output v4]
if :num = 5 [output v5]
if :num = 6 [output v6]
if :num = 7 [output v7]
if :num = 8 [output v8]
if :num = 9 [output v9]
if :num = 10 [output v10]
if :num = 11 [output v11]
if :num = 12 [output v12]
if :num = 13 [output v13]
if :num = 14 [output v14]
if :num = 15 [output v15]
end
to vn-at :num :x :y
if :num = 0 [output v0-at :x :y]
if :num = 1 [output v1-at :x :y]
if :num = 2 [output v2-at :x :y]
if :num = 3 [output v3-at :x :y]
if :num = 4 [output v4-at :x :y]
if :num = 5 [output v5-at :x :y]
if :num = 6 [output v6-at :x :y]
if :num = 7 [output v7-at :x :y]
if :num = 8 [output v8-at :x :y]
if :num = 9 [output v9-at :x :y]
if :num = 10 [output v10-at :x :y]
if :num = 11 [output v11-at :x :y]
if :num = 12 [output v12-at :x :y]
if :num = 13 [output v13-at :x :y]
if :num = 14 [output v14-at :x :y]
if :num = 15 [output v15-at :x :y]
end
to setvn :num :val
if :num = 0 [setv0 :val stop]
if :num = 1 [setv1 :val stop]
if :num = 2 [setv2 :val stop]
if :num = 3 [setv3 :val stop]
if :num = 4 [setv4 :val stop]
if :num = 5 [setv5 :val stop]
if :num = 6 [setv6 :val stop]
if :num = 7 [setv7 :val stop]
if :num = 8 [setv8 :val stop]
if :num = 9 [setv9 :val stop]
if :num = 10 [setv10 :val stop]
if :num = 11 [setv11 :val stop]
if :num = 12 [setv12 :val stop]
if :num = 13 [setv13 :val stop]
if :num = 14 [setv14 :val stop]
if :num = 15 [setv15 :val stop]
end
to tsetvn :num :val
if :num = 0 [tsetv0 :val stop]
if :num = 1 [tsetv1 :val stop]
if :num = 2 [tsetv2 :val stop]
if :num = 3 [tsetv3 :val stop]
if :num = 4 [tsetv4 :val stop]
if :num = 5 [tsetv5 :val stop]
if :num = 6 [tsetv6 :val stop]
if :num = 7 [tsetv7 :val stop]
if :num = 8 [tsetv8 :val stop]
if :num = 9 [tsetv9 :val stop]
if :num = 10 [tsetv10 :val stop]
if :num = 11 [tsetv11 :val stop]
if :num = 12 [tsetv12 :val stop]
if :num = 13 [tsetv13 :val stop]
if :num = 14 [tsetv14 :val stop]
if :num = 15 [tsetv15 :val stop]
end
to set-every-v :value
setv0 :value setv1 :value setv2 :value setv3 :value setv4 :value
setv5 :value setv6 :value setv7 :value setv8 :value setv9 :value
setv10 :value setv11 :value setv12 :value setv13 :value
setv14 :value setv15 :value
end
to compute-visibilities
set-every-v screen-size * 2
setcount 0
repeat 16 [scanvis count  
           setcount 1 + count]
die
end
to scanvis :num
die ; clear out any old turtles
if not pc = black 
  [sprout []
   sprout [setheading (90 + (:num * 22.5)) fd 0.3]
   ; extra turtles, shifted sideways, to catch gaps
   ]
setheading (:num * 22.5) + 180
setdist 1 ; slop factor: as though one can see into the barrier
          ; but not through it
repeat screen-size * 4
  [fd 0.4
   setdist dist + 0.4
   tsetvn :num (min dist vn :num)
   die-near-edge]
end
to die-near-edge
if (screen-edge < abs xcor) or (screen-edge < abs ycor) [die]
end
to can-see-location? :x :y
; a stringent version
setiline ((round ((towards-nowrap :x :y) / 22.5)) mod 16)
setdist distance-nowrap :x :y
output (dist < vn iline) and
       (dist < vn-at ((iline + 8) mod 16) (:x - xcor) (:y - ycor))
end
to can-see-location2? :x :y
; a more tolerant version
setiline ((int ((towards-nowrap :x :y) / 22.5)) mod 16)
setdist distance-nowrap :x :y
output ((dist < vn iline) or
        (dist < vn ((iline + 1) mod 16))) and
       ((dist < vn-at ((iline + 8) mod 16) (:x - xcor) (:y - ycor)) or
        (dist < vn-at ((iline + 9) mod 16) (:x - xcor) (:y - ycor)))
end
to can-see-location3? :x :y
; a compromise between 1 and 2: satisfy 3 out of 4 conditions
setiline ((int ((towards-nowrap :x :y) / 22.5)) mod 16)
setdist distance-nowrap :x :y
output ((dist < vn iline) +
        (dist < vn ((iline + 1) mod 16)) +
        (dist < vn-at ((iline + 8) mod 16)
                      (:x - xcor) (:y - ycor)) +
        (dist < vn-at ((iline + 9) mod 16)
                      (:x - xcor) (:y - ycor)))
        <= 1
end
to can-see-location4? :x :y
; use weighted average of nearest sightlines
settmp ((towards-nowrap :x :y) / 22.5)
setiline int tmp
setinterpolator tmp - iline
setdist distance-nowrap :x :y
output (dist < ((1 - interpolator) * vn iline)
             + (interpolator * vn ((iline + 1) mod 16))) and
       (dist < ((1 - interpolator) * 
                 vn-at ((iline + 8) mod 16)
                       (:x - xcor) (:y - ycor))
             + (interpolator *
                vn-at ((iline + 9) mod 16) 
                      (:x - xcor) (:y - ycor)))
end
to show-mouse-visibility
ifelse can-see-location? mouse-xcor mouse-ycor
  [setcolor white]
  [setcolor 2]
end
to show-mouse-visibility2
ifelse can-see-location2? mouse-xcor mouse-ycor
  [setcolor white]
  [setcolor 2]
end
to show-mouse-visibility3
ifelse can-see-location3? mouse-xcor mouse-ycor
  [setcolor white]
  [setcolor 2]
end
to show-mouse-visibility4
ifelse can-see-location4? mouse-xcor mouse-ycor
  [setcolor white]
  [setcolor 2]
end
to prepare-demo
die
if pc = black [sprout [setcolor gray]]
end
@#$#@#$#@
BUTTON
30
93
140
122
button2
prepare-demo
NIL
2
NIL
BUTTON
20
225
165
259
button5
show-mouse-visibility3
T
5
NIL
BUTTON
17
172
166
209
button4
show-mouse-visibility2
T
4
NIL
BUTTON
10
6
166
41
clear in order to draw obstacles
die setpc black
NIL
7
T
BUTTON
18
272
161
302
button6
show-mouse-visibility4
T
6
NIL
BUTTON
15
129
160
162
button1
show-mouse-visibility
T
1
NIL
BUTTON
33
49
145
81
button3
compute-visibilities
NIL
3
NIL
@#$#@#$#@
Directions
The world is already set up to run a demo, so to begin with
you can just press one of the show-mouse-visibility buttons
(my favorite is #3). Then move the mouse around to see the
"shadows" cast by the obstacles.
To play with it some more:
- change the settings to make a bigger world (it's small
in order to transmit quickly)
- clear the screen and draw obstacles in any nonblack color
- press "prepare-demo," which creates indicator turtles
- try out any of the show-mouse-visibility buttons, one at a time
Obviously the algorithm isn't perfect. However..
(1) I think it's adequate for a flocking/swarming type of 
    application, where objects are in motion and the
    algorithm's errors tend to get averaged out.
(2) It can be improved by brute force by saving more
    sightline data, e.g. going from 16 directions
    to 24 or 36. This costs precomputation time and
    memory, but not runtime speed.
(3) There may also be ways to improve the
    approximation even with the 16-angle data. This is
    just as far as I got.
Hopefully it's also possible to speed up the initial computation.
@#$#@#$#@
StarLogo 2.0
@#$#@#$#@
(install-shapenames 'NIL)
@#$#@#$#@
@#$#@#$#@