Finding the distance to the next patch ahead of a given color in Netlogo - netlogo

I'm trying to model predators hunting prey through a world filled with obstacles. In an obstacle free world, the predators go on random walks until prey fall within a certain detection radius (react-D), and then move towards the prey to capture. I guess there may be several ways to handle obstacles that block line of sight, but my initial efforts are along the following lines:
ifelse any? prey in-radius react-D
[let target min-one-of prey in-radius react-D [distance myself]
face target
...move towards target if it's closer than the nearest obstacle (blue patch) ahead
]
[continue to random walk, avoiding obstacles
]
The first condition of ifelse may need another ifelse. In any case I think I just need a distance of the nearest blue patch ahead to compare with the target distance, but it's not clear to me how I can get that from patch-ahead.
It would be nicer if I could put all this into the test of the first ifelse, but something like the following doesn't allow for patches that aren't blocking line of sight to the prey:
ifelse any? prey in-radius react-D and min-one-of (patches in-radius react-D with [pcolor = blue])[distance myself] > min-one-of (prey in-radius react-D) [distance myself]

Line of sight is actually really tricky to model in NetLogo. At the moment I do it by creating a turtle (invisible, separate breed called crawler) where the agent is that is looking and have the crawler move ahead in small steps checking the colour of the patch that it is on. That goes inside a while loop and the crawler stops when it finds the wrong colour or when it gets to the target distance. the crawler has to take small steps because crossing over the corner of a patch should still block it and it's a trade-off between resolution (how small the crawler step is) against efficiency.
You can almost certainly do the same thing by creating a patch-set as the union of patches found with patch-ahead of multiple distances like 0.1, 0.2, .... and then checking any? over that patch-set

My current solution, giving patches-own [ ob ] values of 1 to all obstacle patches, then using while to detect obstacles ahead:
to detect-ahead
let dist 1
let last-patch patch-here
while [dist <= react-D] [
let p patch-ahead dist
if p != last-patch and [ob] of p = 1 [
ask p [ sprout-markers 1 [ set color yellow ] ]
set last-patch p
]
set dist dist + 1
]
end
Then it should simply be a case of comparing min-one-of the marker agent set with the target. Obviously smaller increments would be good, as JenB says.

Related

NetLogo: how to let turtles return after one tick

hope you can help me out! I have a NetLogo question about the following code:
breed [tourists tourist]
turtles-own [satisfaction]
to setup
clear-all
reset-ticks
end
to go
tick
ask n-of initial-number-tourists patches
[
sprout 1 [
set color white
set size 1
]
]
ask turtles
[ let nearest min-one-of turtles [distance myself]
if-else distance nearest < 0.0000001 [ set satisfaction 0 ]
[ set satisfaction 1 ]
]
ask turtles with [satisfaction = 0] [die]
end
The intention is to sprout "initial-number-tourists" at the start of each tick. Then, they calculate their 'satisfaction' based on the if there are turtles close and let the turtles that have a satisfaction of 0 die. Then, the turtles that remain (that are satisfied) will be sprouted again and their satisfaction will be calculated again.
The code is working, however, with unexpected outcomes. What happens is that the turtles are all sprouted, and they all die each tick. The next tick; they are sprouted again and all die again. Even if i set the distance threshold really low like i did in the code I provided.
Hopefully you can help me out!! Kind regards
The problem you are encountering is that the nearest turtle to each turtle is itself! Thus the distance to nearest is always zero and satisfaction will be set to zero for every turtle. What you want is the closest among the other turtles,
let nearest min-one-of other turtles [distance myself]
(Your distance threshold will mean that all turtles will have satisfaction of 1, but I assume that is what you wanted to accomplish in your testing. Since turtles are sprouted at the centers of the patches, a threshold of < 1.0 would accomplish the same thing.)
Minor point: the convention is to put tick at the end, not the beginning of the go procedure.

Tell agent to not cross a road in Netlogo model

I'm trying to add a condition that doesn't allow an agent to cross over a road. The road patches are set to color red. I can't seem to figure out how to get this condition to work. I ultimately want the agent to turn around if the road is in the patch ahead. Here is my net logo code so far.
to go
ask turtles [
move
]
tick
if ticks >= 60 [stop]
end
to move
ifelse random-float 1 < q
[
ifelse random-float 1 < w
[let target-patch max-one-of neighbors [veg-suitability]
face target-patch]
[let target-patch max-one-of neighbors [pelev]
face target-patch]
]
[
ifelse [pcolor] of patch-ahead 1 = red
[lt random-float 180]
move-to one-of neighbors
ldd-normal
]
end
to ldd-normal
let ldd-distance (ldd-scale)
fd ldd-distance
end
The logic of your move procedure is a bit confused I think. First you have a random chance to either move to a patch with a higher value of a variable of interest (with the uphill primitive) or, if the random draw fails, it moves to a random neighbour. If you don't want it to move onto a red patch then you need to test if the patch that is chosen is red, but you just move it without checking.
After you have moved the turtle, you then check the colour of patch-ahead. Your problem here is that patch-ahead depends on the direction the turtle is facing, which has nothing to do with the direction it has already been moving. You either make it turn (though it may not turn enough) OR move forward. So it never actually moves away.
I can't give you an actual answer because I don't know what your logic is supposed to be. But you could look at structures like:
move-to one-of neighbors with [pcolor != red]
Or, if there are enough red patches that it is possible that there aren't any non-red neighbours (which would cause an error if you tried to move to one), you could use:
let okay-patches neighbors with [pcolor != red]
if any? okay-patches [move-to one-of okay-patches]
Another option is that you only meant to face rather than move to the patch in the first sections of code, then test whether it is facing a red patch and turn around if it is.

Turtles move to nearest patch of a certain color - how can this process be sped up?

I am trying to build a butterfly movement model in which butterflies are attracted to patches of their host plant. This attraction is expressed as a probability which is stored in a variable called "attr-prob". If a butterfly is located within 25 m of a host-plant patch (pcolor = 9.9), it will move to the nearest host-plant patch with the probability of attr-prob.
I wrote the following code:
if (distance (min-one-of (patches with [pcolor = 9.9]) [distance myself]) ) <= 25
[if random-float 1 < attr-prob [move-to min-one-of (patches with [pcolor = 9.9]) [distance myself]]]
This code seems to be doing what I want it to do, however, when I add this part into my model, it slows it down immensely. Does anyone have any alternative suggestions for coding this that might be quicker?
I am running Netlogo in 64-bit Java.
Try something like this:
if random-float 1 < attr-prob [
let target-patch min-one-of (patches in-radius 25 with [pcolor = 9.9]) [distance myself]
if target-patch != nobody [
move-to target-patch
]
]
This should be faster for a couple reasons.
First, the fastest code is the code that never runs. So, doing the probability check at the very beginning allows you to skip computing the closest patch whenever you can.
Second, using in-radius upfront rather than checking the distance at the end reduces the number of patches that you're looking over. Basically, you'll only be checking the color and distance of the patches in the radius, rather than all of the patches in the world.
Finally, in your original code, you were finding the closest patch twice. Instead, you can store the patch in a local variable (target-patch in the code I provided) so you only have to find it once. This alone should double the speed of the code (depending on the value of attr-prob). It also increases readability.

How to ensure turtles follow heading to leader's heading and avoid the obstacles at the same time

I'm trying to set turtles heading equal to leader's heading and at the same all turtles including leaders must avoid obstacle( avoid_obstacles function). My problem is, when i add the set heading code
in flock function:
[set heading [heading] of one-of nearby-leaders ]
it cause my avoid-obstacle code to break. if i comment out this code, avoid obstacle work fine. below is my complete code.
to go
set time-to-evacuate time-to-evacuate + 1
ask turtles [check fd 0.1]
ask turtles [avoid_obstacles fd 0.1]
ask turtles with [pcolor = red][die] ;;turtles exit thru red door will die
if all? turtles [ pcolor = red ] ;; stop simulation
[ stop ]
tick
end
to check
if not leader?
[let beings-seen patches in-cone vision vision-angle with [pcolor = red]
ifelse any? beings-seen
[let target one-of beings-seen face target fd 1 ]
[flock]]
if leader?
[let beings-seen patches in-cone leader-vision leader-vision-angle with [pcolor = red]
ifelse any? beings-seen
[let target one-of beings-seen face target fd 1 ]
[flock]]
end
to flock
let nearby-leaders turtles with [leader? ]
if any? nearby-leaders in-radius vision
[ set heading [heading] of one-of nearby-leaders ]
end
to avoid_obstacles ;; all obstacles set as green patches
let i 1
while [[pcolor] of patch-ahead i != green and i <= vision]
[set i (i + 1) ]
if ([pcolor] of patch-ahead i = green)
[
ifelse [pcolor] of patch-at-heading-and-distance (heading - 20) i + 1 = green
[
ifelse [pcolor] of patch-at-heading-and-distance (heading + 20) i + 1 = green
[
ifelse random 1 = 0
[ rt 30 ]
[ lt 30 ]
]
[ rt 60 ]
]
[lt 60]
]
end
can somebody point what wrong with my code
First of all, consider abandoning the concept of having "leaders" as such. In crowd escape panic situations, they don't stop and hold elections. LOL. I don't know what your model is trying to model, so I have no suggestions here. My model "
Anyway, what your "followers" need to do is integrate to desires, the desire to go the same way as the leader, and the desire to avoid obstacles.
For the first, the follower simply needs a place to remember the "desired" direction. So, rather than set heading directly, you store the heading of the leader./ Then you perhaps use that heading to influence the movement around obstacles.j
For the second, well, obstacle avoidance is a complex discussion on its own. Whatever you have put together, you need to modify it so that it takes the "desired" heading into account, while still effectively avoiding obstacles. This is can be very difficult to do simply.
My model "homing particles 2009" uses one method. This model is designed to explore a particular homing/avoidance behavior. When a particle can't move in the desired direction, it is allowed to move in a limited number of other directions, instead.
Here is the link: http://www.turtlezero.com/models/view.php?model=homing-particles_2009
Unless you have added http://www.turtlezero.com to your list of allowed sites in your Configure Java console (not recommended, but you can trust me, right?), you will not be able to run my models in the browser. I haven't checked what that model needs to run in NetLogo 5.
The ultimate solution to that problem may be to use a path-finding algorithm, like a* (a-star).
In that case you provide your follower with a preferred destination (and that can be vaguely defined as "a point somewhere in 'that' direction"), and the route-planner algorithm plots a route. You can make the route-planner unaware of obstacles until they are "visible" or whatever you define (for example, in a press of bodies, a follower might not be aware of an obstacle until stumbled upon).
Hope this helps!

Multi-variate turtle movement

I need some help with some coding that has me stumped!
I have flies (a turtle breed) on a field. The field has green patches (grass) and brown and grey patches (two types of dung). There is a "patches own" which is the age of the dung (green patches = 0 and brown and grey patches increase +1 per tick).
This is what I need to happen: the flies need to move to the freshest dung within a certain radius and remain there until the dung disappears. If there is no dung within the radius they must move about randomly.
The way I have been looking about it is to use some combination of an IF statement, radius function and the downhill function (however I am not sure if that lets me select a radius or not).
Any help would be greatly appreciated, thank you.
*I have recently made some advances. I can get the flies to move randomly within a radius, but I can't specify which patches within that area the flies are allowed to go to.
[move-to one-of patches in-radius 892]
I can also make it so the flies go to the patch with the lowest patches own, but cannot specify that this patch must be of a certain colour and within a certain radius.
[move-to min-one-of patches [dung-score]]*
It might help if you combine in-radius, min-one-of and with. eg:
move-to min-one-of patches in-radius 10 with [member? pcolor [brown green]] [dung-score]
if there's a chance that the with block might return an empty agentset, you might want to test for condition to avoid an error. eg:
let candidates patches in-radius 10 with [member? pcolor [brown green]]
if any? candidates [move-to min-one-of candidates [dung-score] ]