CMSC 491 – Spring 2016Boids in Motion: Designing NetLogo Models

Prof. Marie desJardins, March 9, 2016

This activity is based loosely on the NetLogo Tutorial #3, available at

THERE IS NO ASSIGNMENT TO SUBMIT FOR THIS LAB! HAVE FUN TODAY AND ENJOY YOUR SPRING BREAK!

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. The exercise becomes increasingly open-ended as you go through it. At the end, we’ll share our boid flock patterns with each other!

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:

  • 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.) Noticethat there are no brackets to start and end the procedure; instead, the indentation levels indicate block structure (like Python). 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 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 brand-new 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.

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?

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 sliders 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 disorganized. 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

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?

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 their 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” (average)operator to take the mean heading of those agents, and average it with the boid’s previous heading.) This model is posted at the course website, if you want to cut and paste:

If you open a browser window, go to the website, and click on the link instead of downloading it, it should show you the procedures text.

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

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

1