Netlogo: obstacle avoidance--tell turtles to take shortest path around - netlogo

Model Details I'm attempting to code territory selection in NetLogo. Turtle 0 selects a territory center, and builds a territory. It select patches based on value of food, discounted by the distance away (food / # patches away from center of the territory), selecting patches in order of discounted value. It stops when it meets total food requirements. Patches selected don't have to be connected to the territory, but should become connected as the turtle walks to the selected patch. These patches crossed are added as travel corridors so that the territory remains contiguous. After Turtle 0 has finished building its territory, Turtle 1 sprouts and repeats the process to select its own territory, then Turtle 2, and so on. Patches belonging to a turtle's territory are unavailable to other turtles.
The Problem Existing territories should be seen as obstacles. Turtles need to identify and go around these obstacles to reach their destination patch using the shortest path possible.
In my current code, turtles will select patches on the other side of an existing territory because they just travel across it. They won't have added a travel corridor to get there, however, because the patches on the way there were already owned.
What are some ways I might tell turtles that if they encounter owned patches (existing territories), they must go around using the shortest distance possible so they can build a travel corridor to the selected patch? I realize this is a complex question, made even more so if actual distances are calculated in (connected question: NetLogo: measure real travel distances around obstacles before choosing destination). I've been racking my brain on this one, so any ideas are helpful. Thanks in advance!
patches-own [
benefit ;; ranges 0.1-1 and represents food available in the patch
owner ] ;; patches are owned once selected for a territory
turtles-own
[ sum-value ] ;; sum of values of patches in my territory
globals [threshold = 25]
to setup
ask patches [ set owner nobody ]
end
to go
ask turtles [build-territory]
tick
end
to build-territory
if sum-value > threshold [stop] ;; keeps picking patches for territory until I've met my threshold
pick-patch
reproduce ;; sprouts a new hatchling when done building territory
end
to pick-patch
let _destination highest-value ;; this is calculated in reporters, below
ifelse _destination != nobody [
face _destination forward 1
if patch-here = _destination ;; add the patch once reached
[ claim-patch _destination ]
if patch-here != _destination
[ if owner = nobody [claim-travel-patch ]] ;; add a travel patch while walking to selected patch
[ if owner != nobody [avoid-obstacle]] ;; or avoid the obstacle of existing territories
]
[stop] ;; if there is no _destination
end
to claim-patch [_patch]
ask _patch [set owner myself]
set sum-value sum-value + (benefit / (distance start-patch))
set pcolor [color] of self
;; etc....
end
to claim-travel-patch [_patch]
ask _patch [set owner myself]
set pcolor [yellow]
;; etc....
end
to avoid-obstacle
;; need to identify some means of going around owned patches
;; ideally this will use the shortest route possible....
;; but even if not shortest route, any ideas for identifying a new path
;; to avoid the obstacle and reach the destination patch?
end
to reproduce
if sum-value > threshold [ ask patch 75 75 [sprout 1 ] ]
end
;;;; --reporters for calculations:--
to-report highest-value ;; calculates value, benefit / cost.
let available-destinations patches with [owner = nobody]
report max-one-of available-destinations [benefit-to-me / cost-to-me]
end
to-report benefit-to-me
report mean [benefit] of patches in-radius 1 ;; this is basically a moving windows analysis to find a cluster of high-benefit patches.
end
to-report cost-to-me
report distance myself ;; later, this will hopefully account for actual travel costs (non-euclidean distance), including around other territories. I think this is complicated, so ignoring for now in this question.
end

Related

Finding the distance to the next patch ahead of a given color in 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.

How to Check if the Two Turtles are on the Same Y Coordinate in NetLogo

I am working on a NetLogo project and I want my pupil turtles to move straight until they come to be on the same Y coordinate as their relevant link neighbour and from there move towards them (the link neighbour).
Note that each pupil has only one link neighbour.
This is the code that I have come up with,
to go
ask pupils [
let target one-of link-neighbors
ifelse [ycor] of myself != [ycor] of target
[
set heading 0
fd 1
]
[
face target
fd 1
]
]
tick
end
This does not work, the turtles keep moving straight. Can someone please help. I just want the turtles to get to their link neighbours, but there are walls that they must avoid.
Your issue is that ycor is a decimal value. So, For example turtle 1 may be on 3.2 and turtle 2 may be on 3.3.
Instead, I think you want to use turtles-here.
to go
ask pupils [
let target one-of link-neighbors
ifelse member? target turtles-here
[set heading 0]
[face target]
fd 1
]
tick
end
On a side note, how many link-neighbors does each target have? My concern is that let target one-of link-neighbors will reset the target each tick.

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.

NetLogo: measure real travel distances around obstacles before choosing destination

I'm modeling territory colonization in Netlogo. Turtle 0 selects a territory center, then builds a territory by adding patches in order of value. Value is based on benefit / cost, where benefit is amount of food in the patch and cost is the distance from the territory center. Turtle 0 finishes building its territory once the summed patch values meets a threshold. Next, Turtle 1 sprouts and repeats the process to select its own territory, then Turtle 2, and so on. Importantly, new turtles should avoid traveling across other territories and cannot picked already-owned patches.
The Problem: Turtles need to travel around patches that are already owned. A patch's value (benefit/cost) should account for costs accurately based on the real travel distances required, not euclidean distance.
IMAGE: As a visual, here is one result from running this model. The turtle in lime green has a huge territory that required traveling over other territories and did not account for actual travel costs around what should be considered obstacles.
How might I code this to account for actual travel distance required (i.e., around obstacles of the existing home ranges) to have turtles pick patches in order of real value? Some code is below. Any ideas? Thanks in advance!
patches-own [
benefit ;; ranges 0.1-1 and represents food available in the patch
owner ] ;; patches are owned once selected for a territory
turtles-own
[ sum-value ] ;; sum of values of patches in my territory
globals [threshold = 25]
to setup
ask patches [ set owner nobody ]
end
to go
ask turtles [build-territory]
tick
end
to build-territory
if sum-value > threshold [stop] ;; keeps picking patches for territory until I've met my threshold
pick-patch
reproduce ;; sprouts a new hatchling when done building territory
end
to pick-patch
let _destination highest-value ;; this is calculated in reporters, below
ifelse _destination != nobody [
face _destination forward 1 ;; turtle will need to avoid obstacles here, haven't figured that out yet.
if patch-here = _destination
[ claim-patch _destination ]
]
[stop] ;; if there is no _destination
end
to claim-patch [_patch]
ask _patch [set owner myself]
set sum-value sum-value + (benefit / (distance start-patch))
set pcolor [color] of self
;; etc....
end
to reproduce
if sum-value > threshold [ ask patch 75 75 [sprout 1 ] ]
end
;;;; --reporters for calculations:--
to-report highest-value ;; calculates value, benefit / cost.
let available-destinations edge-patches
report max-one-of available-destinations [benefit-to-me / cost-to-me]
end
to-report edge-patches ;; constrains to searching along edge of territory so it remains contiguous.
report (patch-set [neighbors4] of territory) with [owner = nobody]
end
to-report benefit-to-me
report mean [benefit] of patches in-radius 2 ;; this is basically a moving windows analysis to find a cluster of high-benefit patches.
end
to-report cost-to-me
report distance myself ;; this is where turtle needs to account for actual travel costs (non-euclidean distance), including around other territories. how to accomplish?
end

NetLogo continue search under specific criteria

I'm simulating female animals dispersing from their mother's territory to search for their own territory. Essentially they need to find areas that are unoccupied by other female territories. Patches have a variable owner-fem that identifies which female it belongs to. Ideally, I'd like to have females:
move to a patch,
search within some radius around that patch for any other territory, and if there is another female's territory within that radius to
move to another patch to start the search process again. Below is what I have so far but I don't think I'm using the in-radius correctly.
I'm not sure what the best way is to tell the female to continue searching until the condition is met. Any help would be much appreciated.
to female-disperse
move-to one-of patches with [owner-fem = nobody]
if [owner-fem] of patches in-radius 3 != nobody
[
move-to one-of patches with [owner-fem = nobody]
]
end
If you want to it in "one shot", you could have them move directly to a suitable patch:
to female-disperse
move-to one-of patches with [
not any? patches in-radius 3 with [owner-fem != nobody]
]
end
Note that patches in-radius includes the patch that the turtle is on so there is no need for a separate move-to one-of patches with [owner-fem = nobody].
I don't know what your model requires, but if I were you, I might try to have them disperse a little more gradually. Here is another version that you could call from your go procedure (or any other procedure that runs "forever"):
to female-disperse
ask females with [owner-fem != self ] [
move-to one-of neighbors ; or however you want them to move
if not any? patches in-radius 3 with [owner-fem != nobody] [
set owner-fem self
]
]
end
In this version, all females that are not on a patch where they are the owner move to one of the neighboring patches. They then check if that new patch is suitable. If it is, they become the owner of it. If it is not, they just stop there for now: they will continue searching at the next iteration of go. You don't have to do it exactly this way; it could just be something loosely along those lines.