Preventing a NetLogo turtle from hitting a wall - netlogo

I'm trying to do something really simple, but for some reason I just can't get it to work.
My setup function creates a square wall from (-20, 20) to (20, 20), and generates a circular turtle of size 3 inside the wall. The square wall is simply made of patches colored blue.
Now I have a go function, which tells the turtle to rotate anywhere from -90 to 90 degrees, and moves it forward by 0.5 steps. It is not allowed to walk "into" the wall; when it hits the wall, it simply picks another direction to move in. The turtle cannot "sense" the wall until it actually walks into it.
The code I've been using is as follows:
ask turtle 0 [
let invalid true
let turn-degree (random(180) - 90)
rt turn-degree
let next-patch patch-ahead 1 ;; Declare next-patch before moving
while [invalid] [ ;; While invalid condition
ask next-patch [
;; Neighbors of the next patch are counted, because turtle is size 3
if ( count neighbors with [pcolor = blue] = 0 ) [
set invalid false
]
]
if (invalid) [
lt turn-degree ;; Turn the turtle back to the original direction
set turn-degree (random(180) - 90) ;; Randomize turn degree again
set next-patch patch-ahead 1 ;; Declare next-patch before moving again
]
]
;; Finally, jump 0.5 steps ahead in the chosen direction
jump 0.5
]
I'm sad to say that the above code doesn't work, because the turtle still somehow manages to overlap itself with the blue wall, which shouldn't happen. I suspect it is because of two reasons:
1) The 0.5 steps is screwing up the "patch-ahead" condition. However, I've tried with patch-ahead 0.5 to no effect.
2) The randomized turn degree is resulting in the blue wall being slightly more than 0.5 away from the turtle, but I have no workaround to this...
Any suggestions?

The problem is that when the turtle moves to the closer to the edge of a patch that is touching a patch that's touching the wall, the neighbors of the turtle's patch aren't part of the wall, but the turtle is still less than 1.5 away from the wall. Try this:
ask turtle 0 [
rt (random 180) - 90
fd .5
while [ any? patches in-radius 2 with [ pcolor = blue ] ] [
bk .5
rt (random 180) - 90
fd .5
]
]

I didn't exactly try Bryan's method, but what I had worked out for me just as well. I ended up using the following:
if (any? patches in-cone 3 60 with [pcolor = blue])
as my wall-detection condition. It worked well enough. :)

Related

How can I separate left- and right-vision field of a turtle in NetLogo?

I want to separate left- and right-vision fields of a turtle in NetLogo.
Left-vision field means angles are -179 to -1 degrees while right-vision field means angles are from 1 to 179 if an angle of front of a turtle is 0 degrees.
In NetLogo, patch-right-and-ahead and patch-left-and-ahead can separate left- and right-vision fields of a turtles, but those codes is only a angle incorporate a turtle.
And, in-cone can not separate the vision fields.
Is there any codes to program this in NetLogo?
You can save the turtle's current heading, turn it 90-degrees left and see what's on the left side of the original heading with
scan x 180
then turn it 90-degrees right from original heading and see what's on the right side of the original heading with
scan x 180
then turn it back to its original heading.
Here's code that illustrates this. Set the scan angle to something smaller than 180 to see more clearly what's happening. As you step through the go step it rotates and highlights what it is seeing.
globals [ scan-angle]
turtles-own [ actual-heading ]
to setup
clear-all
set scan-angle 180
create-turtles 1 [ set size 4 set heading 0 set actual-heading heading]
reset-ticks
end
to go
ask turtle 0 [ set heading (heading + 30) set actual-heading heading]
scansides scan-angle
tick
end
to scansides [ angle ]
ask patches [ set pcolor black]
ask turtle 0
[
;; scan left side
set heading (actual-heading - 90)
ask patches in-cone 10 angle [ set pcolor red]
;; scan right side
set heading (actual-heading + 90)
ask patches in-cone 10 angle [ set pcolor green]
set heading actual-heading
]
end

Netlogo: measure mean distance between start and end patches

I am teaching myself how to create ABMs in Netlogo using the book of Railsback & Grimm 2012. I am having trouble with one book exercise which is on butterflies following "virtual" corridors. Basic idea is that butterflies go uphill for mating using the differences in height as guide. I need to calculate the width of the corridors dividing the number of patches used by the butterflies over the average distance the butterflies fly from the start patch to the end patch. I am
struggling with plotting this corridor width, which I am coding like this:
to-report corridor-width
let patches-visited count patches with [used?]
let mean-distance mean [distance start-patch] of turtles
report patches-visited / mean-distance
I then created a plot in the interface with the command:
plot corridor-width
The error message I get reads:
Division by zero. error while observer running / called by procedure
CORRIDOR-WIDTH called by plot 'Corridor width' pen 'default' update
code called by procedure SETUP called by Button 'setup'
I believe there is something wrong with the way I am coding distance start-patch but I have surfed the web and looked at several codes and I cannot spot my mistake. My whole code looks like this:
globals [ q ] ;; q is the probability that butterfly moves directly to highest patch
turtles-own [ start-patch ]
patches-own [ elevation used? ] ;; patches property of elevation and whether the patch has been used by butterfly or not.
to setup
ca
;; Let's create patches and asign them an elevation and color by using ask patches statement
ask patches
[
;; Elevation decreases linearly with distance from the center of hills. Hills are at (30,30) and
;; (120,120) coordinates. The first hill is 100 units high whereas the second one is 50
let elev1 100 - distancexy 30 30
let elev2 50 - distancexy 120 100
ifelse elev1 > elev2
[ set elevation elev1 ]
[ set elevation elev2 ]
set pcolor scale-color green elevation 0 100
set used? false
]
;; Create 50 butterflies
crt 50
ask turtles [
set size 6
;; set their initial location as their initial patch
setxy random-pxcor random-pycor
set start-patch patch-here
;; have the butterfly draw its path with the pen-down statement
pen-down
]
reset-ticks
;; Initialize the q parameter
set q 0.4
end
;; The master schedule
to go
ask turtles [ move ]
plot corridor-width
tick
if ticks >= 1000
[
let final-corridor-width corridor-width
write "Corridor width: " print final-corridor-width
;export-plot "Corridor width" (word "Corridor-width-output-for-q-" q ".csv")
stop
]
end
;; let's code the butterfly procedure of movement
to move
if elevation >=
[ elevation ] of max-one-of neighbors [ elevation ]
[ stop ]
ifelse random-float 1 < q ;; Decide whether to move to the highest sorrounding
;; patch with p=q
[ uphill elevation ] ;; move deterministically uphill
[ move-to one-of neighbors ] ;; or move randomly
set used? true
end
to-report corridor-width
let patches-visited count patches with [used?]
let mean-distance mean [distance start-patch] of turtles
report patches-visited / mean-distance
end
What happens when the mean-distance is 0?
let mean-distance mean [distance start-patch] of turtles
Essentially, in your setup, you set all the turtle's start-patch to their current patch. So, if you ask all the turtles how far away they are from their start patch, they will all tell you 0 units away.
So, [distance start-patch] of turtles is filled with a list of all 0's.
Thus, a mean of a list of all 0s is 0 causing your divide by 0 error.
Maybe in this situation, you want to report 0 instead...so
ifelse mean-distance = 0
[ report 0]
[report patches-visited / mean-distance]

unable to make non-stationary turtles change their direction if an obstacle a patch ahead

If any one please give some time.
I have an area(say a colony) with boundary wall as black patches and at some point within the boundary there is one building with building wall as blue patches. People(breed) are normally moving inside boundary and the building as well. Also they are entering and going out of the boundary. Due to some reason (suppose rumor) and after certain condition (if more than 15 person hears the rumor) they starts moving randomly with any of the headings 0, 90, 180 and 270. So, the problem I am unable is, to apply check on the turtles(people) randomly moving to change their heading or turn back if they sense the boundary or wall a patch ahead.
I tried following ways but not working, they simple passes form these patches
1) Asked the turtles if heard-rumor? and times-heard > 1 [
if [pcolor] of patch-ahead 1 = blue [set heading [heading] of self - 180]
if [pcolor] of patch-ahead 1 = black [set heading [heading] of self - 180] ]
2) set patches with boundary-wall [set pcolor black] and building-wall [set pcolor blue] and then set patch variables boundary-wall? And building-wall? true on these patches. Further asked the turtles
if heard-rumor? and times-heard > 1 [
if boundary-wall? or building-wall? [ set heading [heading] of self - 180 ] ]
The procedure sequence is
to go
ask people [ ;breed
fd speed
spread-rumor
people-wander ]
end
So after spread-rumor function,
to people-wander
if heard-rumor? and times-heard > 1 and inside-boundary?
[
if people-heard-rumor > 10 [ set heading one-of (list 0 90 180 270) ] ];random 360
;people-heard-rumor is a count how many have received rumor
if heard-rumor? or fear-worst? [
; if [pcolor] of patch-ahead 1 = blue [set heading [heading] of self - 180]]
; if [pcolor] of patch-ahead 1 = black [set heading [heading] of self - 180]]
boundary-wall? or temple-wall? [set i? true set heading [heading] of self - 180 show 5] ]
end
I don’t know what wrong I am doing. But surely I am not using proper way. Any help is deeply thankful.
You start out with fd speed so your people will go right through the barriers on that command without ever testing for a barrier. Note that even if you were to test 1 patch ahead before doing that, if speed can be greater than 1, you could still go right through the barriers. Furthermore, in a corner a person might have a barrier both in front of it and behind it, so reversing course can also be a problem.
Btw, [heading] of self is the same as heading, and to turn around it is more natural to say rt 180.
EDIT (in response to comment):
Here is a simple example of moving step by step, checking along the way:
to fd-with-checks [#speed]
repeat #speed [
ifelse (isbarrier? patch-ahead 1) [
stop
] [
fd 1
]
]
end
to-report isbarrier? [#patch]
report pcolor = blue or pcolor = black
end

Trying to get factions to arrange in segments? NetLogo code advice

I've made a model that aranges factions (turtles in different colours) in a circle.
At the moment they arrange randomly, was wondering if someone could help me arrange them so, for example, red occupies the first 90 degrees, blue the next 90 degrees, etc (on setup).
Here's my code...
ask patch 0 0
[ ask patches in-radius ( max-pxcor * .9) with [ random-float 100 < density ]
[ sprout 1
[ set breed cons
set shape "circle"
set faction random factions
set heading random 360
set size 1
]
]
]
.. guessing I will have to do 360 / fractions, but not sure how to phrase it, if someone could help me out that'd be great. Thanks!
The NetLogo primitive that's the closest to what you want to do is in-cone, which reports the set of turtles that are in the "cone of vision" of another turtle. But your "pie slices" should just be relative to patch 0 0, not to another turtle! No problem: just make a temporary turtle at patch 0 0, use it to get turtles in-cone with the appropriate angle, and kill your temporary turtle.
The following procedure can be used "as is" with your code (just call it from your setup procedure after creating your turtles exactly as you were doing before):
to assign-factions
let angle 360 / factions
foreach n-values factions [?] [
ask patch 0 0 [
sprout 1 [
set heading ? * angle
ask turtles in-cone max-pxcor angle [ set faction ? + 1 ]
die
]
]
]
end
The code is pretty straightforward, except for maybe the more obscure n-values. You could replace it with a while loop if you prefer, but it's really just counting from 0 to factions.
Here is what you'd get with 5 factions:

netlogo move turtle nearest patch

I want to move my turtle to the nearest red or green color patch in its vision.I tried this code but it doesnt move.What is wrong?
while [collectedDirt = 5]
[
ask turtle 0 [
let nearest-patch min-one-of (patches with [pcolor = red or pcolor = green] in-cone 15 20)[distancemyself]
face nearest-patch
fd distance nearest-patch
]
set collectedDirt collectedDirt + 1
search-dirt ;; research whether there is red patch in-cone because of new position
]
You might want to provide us with a little bit more context, but my guess would be that you need something like while [collectedDirt < 5] instead of while [collectedDirt = 5]. If this block is the only way your turtles can "collect dirt", the code probably never even gets executed...
Edit:
You also might want to add a condition in case there is no red/green patch in the cone of vision:
if is-patch? nearest-patch [
face nearest-patch
fd distance nearest-patch
set collectedDirt collectedDirt + 1
]