I want to let move my turtles forward, if there are no other turtles on patch ahead 1 with the same heading. the turtles slow down at some point until they don't move anymore and there are no turtles in front of them, but I don't know why.
Here is some code I have:
to movefd
ask turtles [
let car-ahead turtles-on patch-ahead 1
ifelse car-ahead with [heading = [heading] of myself] != nobody
[ slow-down-car ]
[ speed-up-car ]
if speed < speed-min [ set speed speed-min]
if speed > speed-limit [ set speed speed-limit ]
fd speed
]
end
to slow-down-car
set speed (speed - deceleration)
end
to speed-up-car
set speed speed + acceleration
end
I think (but am not sure as I can't test) that your problem is coming from the difference between agentsets and agents. The report turtles-on returns a turtleset, which can have any number of turtles. Even if it returns exactly one turtle, it returns that as a set of one turtle rather than as a turtle. On the other hand, nobody is a turtle, not a turtleset. A set can never be the same as a turtle.
Try this (note, I also changed 'car' to 'cars' as a reminder that it's a set):
ask turtles [
let cars-ahead turtles-on patch-ahead 1
ifelse any? cars-ahead with [heading = [heading] of myself]
[ slow-down-car ]
[ speed-up-car ]
...
]
end
Related
Recently I've been working on netlogo especially at Traffic Basic.
I want to modify the code and make a function to calculate distance between every turtle (car) with the one ahead of them.
How can I do this?
Maybe a to-report will do what you want. If you add this procedure to Traffic Basic:
to-report distance-car-ahead
; If there are any cars within 10 patches of me
ifelse any? other turtles in-cone 10 1 [
; Report the distance to the nearest one
report distance ( min-one-of ( other turtles in-cone 10 1 ) [distance myself] )
] [
; Otherwise, report that I am in the lead
report "I am the lead car"
]
end
Now as an example, you can modify go to check that this is working, like so:
to go
;; if there is a car right ahead of you, match its speed then slow down
ask turtles [
let car-ahead one-of turtles-on patch-ahead 1
ifelse car-ahead != nobody
[ slow-down-car car-ahead ]
[ speed-up-car ] ;; otherwise, speed up
;; don't slow down below speed minimum or speed up beyond speed limit
if speed < speed-min [ set speed speed-min ]
if speed > speed-limit [ set speed speed-limit ]
fd speed
show distance-car-ahead
]
tick
end
I recommend turning the number of cars down to 3 or 4 to evaluate the print statements to make sure it's doing what you expect.
When I run my code, I sometimes get the following error:
stack overflow (recursion too deep)
error while observer running ASK
called by procedure GO
called by Button 'go'
This only happens intermittently and I'm not sure what causes it.
to go
ask cars [
speed-up
fd speed
if([pcolor] of patch-ahead 1 = yellow)
[stay]
]
tick
end
to speed-up
let car-ahead one-of turtles-on patch-ahead 3
ifelse car-ahead != nobody
[ slow-down-car car-ahead ]
[ speed-up-car ]
if speed < speed-min [ set speed speed-min ]
if speed > speed-limit [ set speed speed-limit ]
fd speed
separate-cars
end
to separate-cars ;; turtle procedure
if any? other turtles-here [
fd 3
separate-cars
]
end
to stay
set speed 0
ask cars
[
ifelse count-up = 0 [speed-up
fd speed
set color green
] [ set count-up count-up - 1
stay ]
]
end
to slow-down-car [ car-ahead ] ;; turtle procedure
;; slow down so you are driving more slowly than the car ahead of you
set speed [ speed ] of car-ahead - deceleration
end
to speed-up-car ;; turtle procedure
set speed speed + acceleration
end
Readers,
I'm a beginner in NetLogo. Please help me in solving few issues with my code that is below:
I'm getting an error "You can't use tick in a turtle context, because tick is observer-only.
I need to get tick value updated after each turtle go all three of "arrive-reception, arrive-triage, go-drroom".
the rest of people is not moving around the arrive reception, arrive triage is running.
to setup-people
set-default-shape turtles "person"
set destination ( patch-set patch -2 34 patch 8 34 )
create-turtles uninfected
[ set color blue
allocate-turtles
]
create-turtles infected
[ set color red
allocate-turtles
]
end
to allocate-turtles
if (pcolor = 9.9 and any? turtles-here)
[
set size 1.5
set heading 0
setxy int random-xcor int random-ycor
]
end
to go
move-people
arrive-reception
arrive-triage
go-drroom
tick
end
to move-people
ask turtles [
rt 360
forward 1
]
end
to arrive-reception
ask n-of (random count turtles) turtles
[
if windows = 1
[
move-to patch -2 34
ifelse not any? turtles-here
[ wait wait-time ]
[ wait-in-queue ]
]
]
end
to wait-in-queue
set arrival-time ticks
bk 1
if any? other turtles-here
[ wait-in-queue ]
wait wait-time
if ticks - arrival-time > wait-time
[ set arrival-time 0
fd 1 ]
end
to arrive-triage
if triage = "Open"
[
move-to patch 26 11
if any? other turtles-here
[ wait-in-queue]
wait wait-time
move-to one-of patches with [pcolor = 109 and not any? other turtles-here ]
wait wait-time
]
end
to go-drroom
move-to one-of patches with [pcolor = 128]
if ( min-one-of other turtles in-radius 5 [distance myself] != nobody)
[
move-to one-of patches with [pcolor = 129]
if ( min-one-of other turtles in-radius 5 [distance myself] != nobody)
[
move-to one-of patches with [pcolor = 5]
if any? seats with [turtles = nobody]
[
move-to one-of max-n-of 6 neighbors [seats]
]
]
]
wait wait-time
die
end
Thanks.
First, some basic programming tricks - don't write so much before trying to debug. If you make a small change and check it, then it's easy to work out where the error is. The first draft of a procedure can be as simple as:
to go-drroom
end
and then fill in the details of what happens in the procedure later.
Typically this error is because you forgot to close a bracket somewhere. That is, one of the procedures starts with ask turtles [ ... and there is no ] so NetLogo is still thinking that the code applies to turtles. However, I can't see an obvious missing ].
But you do have a conceptual problem. The term context is used in NetLogo to refer to who is asking the code to be done and to whom. So ask turtles [ forward 1] is the observer asking the turtles to move and is an observer context procedure. You are not thinking about what context you are in when writing the procedures, and this is probably what is setting off your error.
In the go procedure, you first call move-people. This does ask turtles [ ] so is (appropriately) from the observer context. Then you call arrive-reception and it is also okay.
But then you call arrive-triage and go-drroom still from the observer context and have commands like move-to. Who is being asked to move? You don't have ask turtles .... On the other hand, the procedure wait-in-queue has commands like move-to, but it is fine because it is only called from within an ask turtles ... in the arrive-reception procedure.
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
I'm trying to model the avoidance of animal agents from human agents in NetLogo. First, I asked a single predator to avoid people using two behaviors, "wary" and "scared". This worked nicely. But then I asked the prey animals (168 individuals right now but potentially many more) to do the same and the model has slowed down to a snail's pace. As I'm pretty new to NetLogo I'm sure that there is a more efficient way to code this behavior. Any suggestions on how to streamline this process? I'm sure there is a better way to do it. Thanks!
to avoid-people ;; test if people too close to predator and prey and animals moves away if is.
ask predator [
ifelse ticks mod 24 >= 5 and ticks mod 24 < 18 [ ;makes sure the animals respond to people during the daytime
humans-near
ifelse any? wary
[ fd 0 ]
[ ]
humans-too-near
if any? scared
[run-away]
] [set wary 0 set scared 0]]
ask preys [
ifelse ticks mod 24 >= 5 and ticks mod 24 < 18 [
humans-near
ifelse any? wary
[ fd 0 ]
[ ]
humans-too-near
if any? scared
[run-away]
] [set wary 0 set scared 0]]
end
;;Humans-near and humans-too-near are functions
;;Alert-distance and flight initiation distance are sliders for the predator but are set values for prey
to humans-near ;;adds all humans in alert-distance radius of animal to an agent subset for that agent.
ask predator [
set wary humans in-radius alert-distance]
ask preys [
set wary humans in-radius 10]
end
to humans-too-near ;;adds all humans in flight-initiation-distance radius of animal to an agent subset for that agent.
ask predator [
set scared humans in-radius flight-initiation-distance]
ask preys [
set scared humans in-radius 5]
end
to run-away ;;Make animal avoid the human closest to it.
set nearest-human min-one-of scared [distance myself]
turn-away ([heading] of nearest-human) max-separate-turn
end
;;this keeps the animals inside the tropical forest and away from human settlement.
;;Max-separate-turn is a slider dictating the angle that the predator runs away from the human
to turn-away [new-heading max-turn]
turn-at-most (subtract-headings heading new-heading) max-turn
ifelse [habitat = typeTrop] of patch-ahead run-distance
[fd run-distance] [turn-away ([heading] of nearest-human) max-separate-turn]
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
I did not understand your code, but this is one way to do what you want, I am not sure how agents should behave if they are scared or they move with wary, but you can change these easily :
Breed [predators predator]
Breed [Humans Human]
Breed [Preys Prey]
turtles-own [
wary
scared
]
to setup
Clear-all
Create-humans 5 [Set color orange set shape "person" move-to patch random 30 random 30]
Create-Preys 5[Set color white Set shape "Sheep" move-to patch random 30 random 30]
Create-predators 5 [set color red Set shape "wolf" move-to patch random 30 random 30]
ask turtles
[set Wary false
Set Scared False
]
reset-ticks
end
to go
ask turtles
[rt random 5
fd 0.3]
avoid-people
tick
end
to avoid-people
ifelse is-day?
[
ask predators
[ if humans-near?
[
set wary true
if humans-too-near? [Set Scared true]
set label (word wary "," Scared )
]
]
Ask Preys
[ if humans-near?
[
set wary true
if humans-too-near? [Set Scared true]
set label (word wary "," Scared )
]
]
]
[; what they should do when its night time
]
end
to-report humans-too-near?
report any? humans in-radius 2
end
to-report humans-near?
report any? humans in-radius 5
end
to-report is-day?
report (ticks mod 24 >= 5 and ticks mod 24 < 18)
end
*Update:
Your problem was in having 2 ask inside each other , I am glad your model now runs faster.