Boids lab

advertisement
Boids in Motion: Designing NetLogo Models
NetLogo Professional Development Workshop for Teachers
Marie desJardins, UMBC, October 21, 2011
This activity is based loosely on the NetLogo Tutorial #3, available at
http://ccl.northwestern.edu/netlogo/docs/
In this activity, you’ll write some simple “boids” (flocking agents) and write
programs to control their behavior, creating increasingly more complex and
beautiful patterns of behavior. I’ve tried to go step-by-step while trying not to
include unnecessary detail (for example, if you are supposed to type something into
a command box and there’s an “OK” button, you should use your initiative to go
ahead and click that button when you’re done!) The exercise becomes increasingly
open-ended as you go through it. At the end, we’ll share our boid flock patterns with
each other!
You may wish to refer to the one-page handout of NetLogo commands that I’ve given
you. Also, the single most useful NetLogo reference page is the NetLogo Dictionary:
http://ccl.northwestern.edu/netlogo/docs/dictionary.html – this document has an
alphabetical listing of every built-in NetLogo command with a brief explanation of
how the command works.
NetLogo Agents
NetLogo agents include patches, turtles, links, and the observer. The patches are
the individual grid locations that you see in the visual display. Turtles are mobile
objects that can move around within the grid, from patch to patch. Links connect
two turtles (but we won’t be using them in this exercise). The observer is a sort of
“superagent” that manages all of the activity in the simulation (and performs actions
that the patches, turtles, and links aren’t allowed to).
Any agent can run NetLogo commands (i.e., the built-in actions that NetLogo
provides) and procedures (new commands or modules that we will learn how to
write in this exercise).
In addition to agents in the view window, you can also create buttons, monitors,
sliders, and plots to initialize and control the simulation, and to see output
summaries of the simulation.
Making a Setup Button
The first thing you need to do is launch NetLogo. If you already have a model
running, you should create a new model (File… New). Now you’ll build the top-level
controller for your model, the “Setup” button:
1


Make sure you’re in the Interface tab.
Click “Add” in the toolbar, then select “Button” in the dropdown menu to the
right of “Add.”
 Click where you want the button to appear, type “setup” in the box labeled
“Commands,” and press OK.
Notice that the label “setup” is red. That’s because we don’t yet have a procedure
named “setup,” so we’ll go make one.
Defining a Setup Procedure
Go to the Procedures tab, and enter the following text:
to setup
clear-all
create-turtles 100
ask turtles
[ setxy random-xcor random-ycor ]
end
“to” is the NetLogo command that lets you define a new procedure (in this case,
named “setup”. (Procedures can also take parameters, as we’ll see later.) Notice
that there are no brackets to start and end the procedure; instead, the indentation
levels indicate block structure. If you retype this code by hand, instead of cutting
and pasting, you’ll notice that the text editor indents and unindents (when you type
“end”) automatically. “clear-all” initializes the simulation to be empty: any existing
turtles are deleted; all global variables are set to zero; all patches, plots, drawings,
and outputs are cleared.
“create-turtles #” creates # new turtles, with random headings, a random color
(from NetLogo’s 14 primary colors), and location [0,0]. Since we don’t want all of
our agents stacked on each other, we need to move them. But since NetLogo is very
object-oriented, we actually ask the agents (but they can’t say no!).
“ask turtles [cmd]” will send the specified command to each of the turtles (in a fixed
order, which sometimes matters, depending on the interactions you’re trying to
model).
Finally, “setxy x-loc y-loc” is a turtle-specific command – that is, since it is always
executed by a turtle, it only applies to that turtle (and therefore does not need a
turtle as a parameter), moving it (teleporting, not moving continuously) to the
specified location. “random-xcor” and “random-ycor” are referred to as reporters
(as opposed to commands) – they are essentially functions, so they return a value; in
this case, a random location along the x or y axis, respectively.
Check your code using the “√” button, which should have turned green (meaning
there is something new to check) as soon as you started typing your commands. If
all is well with the code, the “√” will turn gray. If there is an error, you’ll see a
2
yellow highlighted bar, with a red X, and some indication of your error. (Just to see
what happens, try inserting some errors and spurious text into your code. As with
most programming languages, some syntax errors result in very clear error
messages, whereas others are a bit harder to decipher. Generally, though, you’ll find
that the error output is quite clear.) Once you’ve checked your code, go back to the
Interface tab and click Setup.
Congratulations – you’ve created your first turtle environment!
Creating Behaviors
Let’s make the turtles move around randomly. First we need a way to tell the turtles
to move, so you should create a button labeled “go” in the Interface tab. When you
do this, click the “forever” checkbox in the edit window before closing it. Notice the
little “recycle” icon in the corner of the “go” button you’ve created – that means this
is a looping command, that will make the commands run repeatedly when you press
the button (until you press it again).
The “go” button probably didn’t land in the right place, so try moving it: right-click
(control-click on the Mac), click “Select,” and you should see a gray border with
resizing handles (black dots) appear. Now you can move and resize the button.
(You probably noticed that this is how you can delete buttons you don’t want, as
well.) Click anywhere on the background to unselect the button.
Go to the Procedures tab, and create the “go” procedure (you can add it below the
“setup” procedure):
to go
move-turtles
end
This refers to a “move-turtles” procedure, which doesn’t exist, so we have to create
it:
to move-turtles
ask turtles [
right random 360
forward 1
]
end
We could, of course, just have put the “ask turtles…” command in the “go” function,
but by making new commands, we have a more modular program that will be easier
to extend and modify later.
3
Thought Question: What is this procedure going to do? Talk amongst
yourselves! Look up the commands in the NetLogo dictionary if you’re not
sure what they might do.
Check your code, then return to the Interface window and start your turtles!
Thought Question: What happens when you slow the simulation down by
sliding the speed slider to the left? Why do they all move simultaneously
initially, but as the simulation gets slower, they slow down? What happens
when you speed up the simulation by sliding the speed slider to the right?
Does the behavior seem counterintuitive? Let’s talk…
Creating Turtle Art
Let’s turn our turtles into drawing turtles. Turtles have the ability to leave a “trail”
behind them using a feature called the pen. Inside the setup function, change the
command
ask turtles
[ setxy random-xcor random-ycor ]
to
ask turtles
[ setxy random-xcor random-ycor
pen-down]
Go back to the Interface tab. Be sure you’ve set the slides back to normal. Try
running the model. Pretty cool, huh? Reset (by clicking “go” again to stop the
model, then “setup” to re-initialize) and try slowing and speeding up the model to
really see what’s going on.
This is pretty but a bit chaotic. Let’s see whether we can get some pattern going on,
by making our turtles all move in the same direction. First we want to make sure
the turtles are all initially pointed in the same direction. We can do this inside the
“ask turtles” command in “setup” by adding:
set heading 45
(Headings are in degrees, starting at north, so this makes all of the turtles point to
the northwest.) Of course, we had our turtles turning in random directions, so we
need to keep them facing the same way. You can do that by simply commenting out
the “right” command in “move-turtles” – just put semicolons in front of it:
;; right random 360
4
Creating Variations
It would be fun to play around with this simulation, trying some different settings,
but it’s a pain to keep going back and forth between the Interface and Procedures
tab. Let’s add some parameter settings and interface controls.
First, in the Interface, create three switches. Each switch will create a binary
(on/off, or true/false) global variable. Call your switches/variables
“randomheading”, “randomdirection”, and “leavetrails.” We’re also going to make
two sliders, which define integer variables. You should call one of them
“defaultheading”; in the dialog box, set it to have a minimum value of 0, increment of
1, maximum value of 360, and default value of 45. The second slider, “anglerange,”
should have minimum 0, increment 1, maximum 360, and default 30.
In Procedures, we can now use these five global variables to control the behavior of
our program.
“randomheading” will tell the program whether to use a random heading (i.e., the
randomly selected heading that turtles are created with) or a default heading (which
will be defined by the “defaultheading” slider value). To implement this option,
change the line
set heading 45
to
if not randomheading [ set heading defaultheading ]
“randomheading” and “randomdirection” are going to interact with each other a bit.
“randomdirection” tells the turtle whether it should move in a random direction, or
just stay on the heading it’s on. But if we started off with the default heading, we
don’t want to just start turning randomly, or our flock won’t maintain any
coherence. So if we’re not using a random heading, instead of turning randomly,
we’ll choose a random direction within “anglerange” of the original heading
(actually within ½ anglerange in either direction). We do this by replacing the
commented-out “right random 360” with:
if randomdirection
[ ifelse randomheading
[ right random 360 ]
[
set heading defaultheading +
(random anglerange - (anglerange / 2)
]
]
Thought Questions: How can you use “leavetrail” to put the pen down only if
this option is turned on?
5
Try Your Own Variations!
See what other variations you can come up with. You could experiment with
flocking behavior by trying to get the boids to move in the same direction as its
neighbors. I made a model that sets up several “species” of boids (shown as
different colors) and has the boids flock with their species (and away from the other
species). I’ve included a copy of the code for that model below so you can perhaps
get some ideas. (I added a “flocking” slider, and use something called agentsets to
identify the nearby boids with certain properties, then the “mean” operator to take
the mean heading of those agents, and average it with the boid’s previous heading.)
turtles-own [ flock-x flock-y flock-heading enemy-x enemy-y
enemy-heading prev-heading ]
globals [flock-radius buffer]
to setup
clear-all
set flock-radius 7
set buffer 3 ;; don't move towards/from agents that are too close
create-turtles 100
ask turtles
[ setxy random-xcor random-ycor
if flocking
[
set color (random numtypes) * 20 + 5
]
if not randomheading [ set heading defaultheading ]
set prev-heading heading
if leavetrails [ pen-down ]
]
end
to go
move-turtles
end
6
to move-turtles
ask turtles [
ifelse flocking
[
set flock-heading heading
;; in case no neighbors
set enemy-heading heading
;;
or enemies
if any? my-neighbors [
set flock-heading mean [prev-heading] of my-neighbors
]
if any? my-enemies [
set enemy-heading mean [(prev-heading + 180) mod 360]
of my-enemies
]
set prev-heading heading
set heading (heading + flock-heading + enemy-heading) / 3
]
[
if randomdirection
[ ifelse randomheading
[ right random 360 ]
;; really random: go anywhere
[ set heading defaultheading + (random anglerange) (anglerange / 2) ] ;; only a little random
]
]
forward 1
]
end
to-report my-neighbors
report other turtles with
[ color = [color] of myself and (distance myself < flock-radius)
and (distance myself > buffer)]
end
to-report my-enemies
report other turtles with
[ color != [color] of myself and (distance myself < flock-radius)
and (distance myself > buffer)]
end
7
Download