How to set heading of agentset from nest in Netlogo - netlogo

What I'm planning to do is to ask a group of agentsets to flock from nest throughout world.
I'm using flocking codes and I have problem to identify heading for cohere part. Since all agents are moving from nest, how can I set their heading?
The error I got after editing my codes are :
No heading is defined from a point (0,0) to that same point.
error while turtle 1 running TOWARDS
called by procedure AVERAGE-HEADING-TOWARDS-FLOCKMATES
called by procedure COHERE
called by procedure FLOCK
Here is code for agentset:
to setup
clear-all
let number-of-groups 3
let turtles-per-group 4
create-turtles turtles-per-group * number-of-groups
[ set color red
set size 1.5
set pen-mode "down"
]
set groups [] ; empty list
repeat number-of-groups [
let new-group n-of turtles-per-group turtles with [
not is-agentset? my-group
]
ask new-group [ set my-group new-group ]
set groups lput new-group groups
]
reset-ticks
end
to go
ask turtles [flock]
end
Here is flocking part
to flock
find-flockmates
if any? flockmates
[
find-nearest-neighbor
ifelse distance nearest-neighbor < minimum-separation
[ separate ]
[ align
cohere ] ]
end
to find-flockmates ;; turtle procedure
set flockmates my-group
end
to find-nearest-neighbor ;; turtle procedure
set nearest-neighbor min-one-of flockmates [distance myself]
end
;;; COHERE
to cohere
turn-towards average-heading-towards-flockmates max-cohere-turn
end
to-report average-heading-towards-flockmates
let x-component mean [sin (towards myself + 180)] of flockmates
let y-component mean [cos (towards myself + 180)] of flockmates
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
I have problems to change code for to-report average-heading-towards-flockmates since towards myself + 180)] of flockmates cannot be use here. Can anyone help me?

Related

How to group turtles together depending on their colour and minimum distance

I am writing a model in NetLogo where I start with a 5 turtles populations in colours (blue, green, yellow, red, white) with random starting co-ordinates. When I run the model, I want when the white turtle meets the green or yellow or red turtle, they become joined with it and move together as a group. And when the white turtle meets the blue turtle, it separates from it and both continue moving randomly. I saw the example model for bird flocking in the model library and I have been trying to modify it for my model (see code attached).
In the 'flocking example' from the models' library, turtles are set to align, cohere and separate when too close to each other (depending on the distance for the nearest-neighbour and minimum-separation). This works well and I was able to use it to tell turtles to flock, keeping them intact as a group as they continue to move. My question is how to get only the (green, yellow, red) turtles to flock when they meet the white turtles and leaving the blue turtles moving randomly.
turtles-own [
flockmates ;; agentset of nearby turtles
nearest-neighbor ;; closest one of our flockmates
]
;Setting up the 5 turtles here
to setup
clear-all
create-turtles pop1
[ set color blue ; all pop
set size 1.5 ;; easier to see
setxy random-xcor random-ycor
set shape "person"]
create-turtles pop2
[ set color green ; stage1
set size 1.5 ;; easier to see
setxy random-xcor random-ycor
set shape "person"]
create-turtles pop3
[ set color yellow ; stage2
set size 1.5 ;; easier to see
setxy random-xcor random-ycor
set shape "person"]
create-turtles pop4
[ set color red ;stage3
set size 1.5 ;; easier to see
setxy random-xcor random-ycor
set shape "person"]
create-turtles pop5
[ set color white ; chv
set size 1.5 ;; easier to see
setxy random-xcor random-ycor
set shape "person"]
reset-ticks
end
to go
ask turtles [ flock ]
;ask turtles [ meet]
;; the following line is used to make the turtles ;; animate more smoothly.
repeat 5 [ ask turtles [ fd 0.2 ] ] ;this seems much faster
;; for greater efficiency, at the expense of smooth
;; animation, substitute the following line instead:
;ask turtles [ fd 1 ] ;than this
tick
end
;How do I make to get only the (green, yellow, red) turtles to flock when
;they meet the white turtles. Leaving the blue turtles moving randomly. How can do that?
; find-samecolor
; if any? flock
; ifelse separate
;end
;If green, yellow, red meets white turtle, they move together; nearest distance
to flock ;; turtle procedure
find-flockmates
if any? flockmates
[ find-nearest-neighbor
ifelse
distance nearest-neighbor < minimum-separation
[ align ]
[ cohere ]
;[separate]
]
end
;If blue meets white turtle, they move together; nearest distance
to find-flockmates ;; turtle procedure
set flockmates other turtles in-radius vision
end
to find-nearest-neighbor ;; turtle procedure
set nearest-neighbor min-one-of flockmates [distance myself]
end
;;; SEPARATE
;to separate ;; turtle procedure
; turn-away ([heading] of nearest-neighbor) max-separate-turn
;end
;;; ALIGN
to align ;; turtle procedure
turn-towards average-flockmate-heading max-align-turn
end
to-report average-flockmate-heading ;; turtle procedure
;; We can't just average the heading variables here.
;; For example, the average of 1 and 359 should be 0,
;; not 180. So we have to use trigonometry.
let x-component sum [dx] of flockmates
let y-component sum [dy] of flockmates
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
;;; COHERE
to cohere ;; turtle procedure
turn-towards average-heading-towards-flockmates max-cohere-turn
end
to-report average-heading-towards-flockmates ;; turtle procedure
;; "towards myself" gives us the heading from the other turtle
;; to me, but we want the heading from me to the other turtle,
;; so we add 180
let x-component mean [sin (towards myself + 180)] of flockmates
let y-component mean [cos (towards myself + 180)] of flockmates
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
;;; HELPER PROCEDURES
to turn-towards [new-heading max-turn] ;; turtle procedure
turn-at-most (subtract-headings new-heading heading) max-turn
end
;to turn-away [new-heading max-turn] ;; turtle procedure
; turn-at-most (subtract-headings heading new-heading) max-turn
;end
;; turn right by "turn" degrees (or left if "turn" is negative),
;; but never turn more than "max-turn" degrees
to turn-at-most [turn max-turn] ;; turtle procedure
ifelse abs turn > max-turn
[ ifelse turn > 0
[ rt max-turn ]
[ lt max-turn ] ]
[ rt turn ]
end
Sorry about the delay, for some reason I didn't see this question when you first asked it. The key procedure in this code is:
to find-flockmates ;; turtle procedure
set flockmates other turtles in-radius vision
end
What this does is says that any turtle that the source turtle can see is considered a flockmate. What you want to do is say that blue turtles cannot be flockmates (that is, they don't create flocks themselves and are not considered flockmates by other coloured turtles). Try this:
to find-flockmates ;; turtle procedure
if color != blue
[ set flockmates other turtles with [color != blue] in-radius vision
]
end
The first line makes it so that blue turtle don't find flockmates. The second line excludes blue turtles from the flocks of others.
-----UPDATE----
You actually have this procedure within a turtle procedure about flocking. This procedure sets the variable 'flockmates' to the set of turtles found but, if the turtle is blue, there are no flockmates and it doesn't return an empty turtleset. The best way to fix it is to use a to-report procedure, so all turtles will have an appropriate data type (a turtle set) for their variable.
to-report find-flockmates ;; turtle procedure
ifelse color = blue
[ report no-turtles ] ; this is an empty turtle-set
[ report other turtles with [color != blue] in-radius vision ]
end
Then, to use this procedure, you need to change:
to flock ;; turtle procedure
find-flockmates
if any? flockmates
to this:
to flock ;; turtle procedure
set flockmates find-flockmates
if any? flockmates
You can make two different types of turtles-own with their own rules. I did a multi agents works and everyone has their owns rules and with deafferents turtles-own group everything works like a charm.
ant-own[ velocita-ant metabolismo-ant sf ;;scorta ants massimo_sf] killer own[velocita-killer metabolismo-killer sk ;;scorta killers massimo_sk]

How to make agent flock in their group using BOIDS rule in Netlogo?

Here is what I want to do:
I need all agents move forward in a group by using BOIDS rule
I want them to be able to turn around after they meet the wall (my world is not wrap, they can't penetrate the wall to reach the other side of the world)
here is my code:
globals [nearest-teammates teammmembers]
turtles-own [ myteamset teamID myID teammatesID ]
to setup-groups
let teamCounter 1
ask turtles [
if myteamset = nobody [
let possible-teammates other turtles with [ myteamset = nobody ]
ifelse count possible-teammates > 1 [
set myteamset ( turtle-set self n-of 2 possible-teammates )
let ids sort [myID] of myteamset
set teammmembers myteamset
set nearest-teammates min-one-of myteamset[distance myself]
let tempteam teamCounter
set teamCounter teamCounter + 1
ask myteamset [
set teammatesID ids
set myteamset teammmembers
set teamID tempteam
]
] [
show "Not enough turtles to make a new team!"
]
]
]
end
flocking part:
to move-in-groups
let teamNumbers remove-duplicates [teamID] of turtles
foreach teamNumbers [
ask one-of turtles with [ teamID = ? ] [
if myteamset != nobody [
ask myteamset [
set heading mean-heading [ heading ] of myteamset
ifelse distance one-of turtles with [ teamID = ? ] < 3
[separate]
[align
cohere]]
fd 1 ]]]
end
helpers code
to-report mean-heading [ headings ]
let mean-x mean map sin headings
let mean-y mean map cos headings
report atan mean-x mean-y
end
to align
turn-towards average-flockmate-heading max-align-turn
end
to cohere
turn-towards average-heading-towards-flockmates max-cohere-turn
end
to separate
turn-away ([heading] of nearest-teammates) max-separate-turn
end
to turn-away [new-heading max-turn]
turn-at-most (subtract-headings heading new-heading) max-turn
end
to-report average-heading-towards-flockmates
let x-component mean [sin (towards myself + 180)] of nearest-teammates
let y-component mean [cos (towards myself + 180)] of nearest-teammates
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
to-report average-flockmate-heading
let x-component sum [dx] of nearest-teammates
let y-component sum [dy] of nearest-teammates
ifelse x-component = 0 and y-component = 0
[ report heading ]
[ report atan x-component y-component ]
end
to turn-at-most [turn max-turn]
ifelse abs turn > max-turn
[ ifelse turn > 0
[ rt max-turn ]
[ lt max-turn ] ]
[ rt turn ]
end
to turn-towards [new-heading max-turn]
turn-at-most (subtract-headings new-heading heading) max-turn
end
The error I get:
SUM expected input to be a list but got the number -0.961261695938319 instead.
error while turtle 4 running SUM
called by procedure AVERAGE-FLOCKMATE-HEADING
called by procedure ALIGN
called by (command task from: procedure MOVE-IN-GROUPS)
called by procedure MOVE-IN-GROUPS
called by procedure GO
called by Button 'go'
What should I do? I need help... .·´¯(>▂<)´¯·.
Thank you for your time.
The error you are getting happens on this line:
let x-component sum [dx] of nearest-teammates
NetLogo is telling you that you tried to pass a single number to sum instead of passing it a list. How could that happen? It would happen if nearest-teammates contained a single agent instead of an agentset.
So let's look at where you define nearest-teammates:
set nearest-teammates min-one-of myteamset[distance myself]
Can you see the problem? You're using min-one-of, which does give you a single agent!
How could you get, for example, the 10 closest agents instead of just the closest one? Fortunately, NetLogo has a primitive that does just that: min-n-of. Here is how you would use it:
set nearest-teammates min-n-of 10 myteamset [ distance myself ]
Replace 10 with the number of teammates you want, of course.

Netlogo Flocking model turtles are bored

I'm new to programming in Netlogo and I need to adapt the code so that turtles get bored after 50 ticks of flying in formation and make a right turn of 90 degrees. I modified the code while looking at some other examples but I get a very strong hunch it doesn't do what it's supposed to do. Can you please help me or give me a hint? Here's the code in question:
turtles-own [
flockmates ;; agentset of nearby turtles
nearest-neighbor ;; closest one of our flockmates
flock-tick
]
to setup
clear-all
create-turtles population
[ set color yellow - 2 + random 7 ;; random shades look nice
set size 1.5 ;; easier to see
setxy random-xcor random-ycor
set flockmates no-turtles
set flock-tick 0 ]
reset-ticks
end
to go
ask turtles [ flock ]
;; the following line is used to make the turtles
;; animate more smoothly.
repeat 5 [ ask turtles [ fd 1 ] display ]
;; for greater efficiency, at the expense of smooth
;; animation, substitute the following line instead:
;; ask turtles [ fd 1 ]
tick
end
to flock ;; turtle procedure
find-flockmates
if any? flockmates
[ find-nearest-neighbor
ifelse distance nearest-neighbor < minimum-separation
[ separate ]
[ align
cohere ] ]
end
to find-flockmates ;; turtle procedure
set flockmates other turtles in-cone vision 90
end
to find-nearest-neighbor ;; turtle procedure
set nearest-neighbor min-one-of flockmates [distance myself]
end
to flock-timer
if any? flockmates [
set flock-tick 50
while [ flock-tick > 0 ] [
set flock-tick ( flock-tick - 1 ) ]
if flock-tick = 0
[ set heading ( heading - 90 ) ] ]
end
The rest of the code is still the same as the the model in the library.
I must admit I'm not really sure of what I'm doin and the northwestern website is also not very helpfull to me (probably my own fault).
Thanks!
If we add comments to your code, we can see the logic problem.
to flock-timer
if any? flockmates [
;the next line sets `flock-tick` to 50
set flock-tick 50
;the next line sets `flock-tick` to 0
while [flock-tick > 0] [set flock-tick (flock-tick - 1)]
;so the next condition will always be satisfied
if (flock-tick = 0) [
;and so the heading will always be changed
set heading (heading - 90)
]
]
end
You might break things up to make it easier to follow the logic.
to flock-timer ;turtle proc
update-flock-tick
if (flock-tick = 0) [get-bored]
end
to update-flock-ticks ;turtle proc
;you can add additional logic here if you wish
if (flock-tick > 0) [
set flock-tick (flock-tick - 1)
]
end
to get-bored ;turtle proc
set heading (heading + one-of [-90, 90])
end
This is not a complete solution, but it should get you started.

How to set myheading equal to leader's heading in Netlogo

what i'm trying to do is:
Pseudo code
to flock
check flockmates
if find any leader inside the flockmates
change myheading to leader's heading
else
follow flocking rule [separate, allign, cohesion]
end
Below is code that I use.
turtles-own
[ flockmates
nearest-neighbor
leader?
leader
]
to setup
__clear-all-and-reset-ticks
ask n-of population patches with [ pcolor = blue]
[sprout 1
[set color white
set size 0.6
set leader? false]
]
choose-leaders
end
to choose-leaders
ask n-of ((percent_of_leader / 100) * population ) turtles
[set leader? true
set color black
set size 0.6
set leader self
]
end
to go
ask turtles [flock]
end
to flock
find-flockmates
let nearby-leaders turtles with [leader? ]
ifelse any? nearby-leaders
[ set heading [heading] of nearby-leaders]
[ find-nearest-neighbor
ifelse distance nearest-neighbor < minimum-separation
[separate]
[ if any? flockmates
[align
cohere ]]]
end
to find-flockmates ;; turtle procedure
set flockmates other turtles in-cone vision vision-angle
end
to find-nearest-neighbor ;; turtle procedure
set nearest-neighbor min-one-of flockmates [distance myself]
end
however when I run the code, this error message pop-up can't set turtles variable HEADING to non-number [147]. and it point to this code [set heading [heading] of nearby-leaders]. what did i do wrong here? really appreciate if someone can help.
Because nearby-leaders in your code is a turtle-set, you should use one-of:
set heading [heading] of one-of nearby-leaders

How to avoid turtles revisiting the patch on which they were last time?

Turtles stay on patches for 60 ticks, and then move to another target patch. How to avoid turtles revisiting the patch on which they were last time? Thanks
Hi Seth and Frank,
Thank you very much for your reply. I am sorry I did not describe the questions in detail.
Turtles will not visit the patch that they were on the last tick, and will move to another nearest patch instead in next tick. The following codes mean they find the nearest patch, and move on to it.
What I would want to do is the turtle will find the nearest patch again in the next tick. They will move to other alternative that is nearest to themselves, if the nearest patch is still the same one that they were on the last tick. Thanks
let closest-leaf min-one-of (patches in-radius 1 with [pcolor = lime]) [distance myself]
face closest-leaf
fd distance closest-leaf
A good way is to have a turtles-own variable of patches visited that can be maintained (remember to initialize it to the empty list when you create the turtle).
turtles-own [ patches-visited ]
to setup
...
ask turtles [ set patches-visited [] ]
...
end
to move
let potential-targets filter [ not member? ? patches-visited ] target-patches
let target-patch one-of potential-targets
if target-patch != NOBODY [
set patches-visited fput target-patch patches-visited
; move to target patch
]
end
Add a get-target reporter.
to-report get-target ;;turtle proc
let %close patches in-radius 1 with [pcolor = lime and self != [patch-here] of myself]
ifelse (any? %close) [
report min-one-of %close [distance myself]
] [
report nobody
]
end
Now you can easily change your mind about how to pick a target. You can then move to the target (if one exists).
to move ;; turtle proc
let %target get-target
ifelse (%target = nobody) [
;handle this case
] [
face %target move-to %target
]
end