What is the most efficient way to ask other turtle who can see the caller turtle in NetLogo? - netlogo

I was wondering if anyone has a good idea to filter turtles who have the caller turtle in their vision and in their cone of vision with the least computational cost?
Now I am using something like this:
Member? Caller-Agent agents in-cone 5 100
or just who are agents who can see me?
I was wondering if anyone knows how can I check if heading of other agents in some radius X is toward the caller agent ?

So , this is the way I did it:
I used abs( towards myself - heading) < 50
I thought it might include cone with angle of 100 since it uses absolute value.
This is just a test program to see if it works:
ask turtles[set label "" set color green]
ask turtle 7 [
set color red
set label "Caller"
ask other (turtles with [distance myself <= 3 and abs( towards myself - heading) < 50 ])
[
set color yellow
]
ask other turtles [
set label (Member? turtle 7 Other turtles in-cone 3 100)
]
]
and this one cone 80 and abs( towards myself - heading) < 40 :
There is a problem with this approach:
if an agent is as same location of the caller then I will get the error that there is no heading defined to same point or something like that!
Error is : No heading is defined from a point (7,7) to that same point. error while turtle 28 running TOWARDS
Update:
[(distance myself <= 3 and distance myself > 0 and abs( subtract-headings towards myself heading ) < 60) or distance myself = 0 ]

Related

Specifying dispersal distances for turtles in Netlogo

So for part of my model, I want my turtles (in this case, deer, specifically juvenile female deer) to "disperse" according to certain criteria. Here is what I have so far:
to move-dispersing-femjuvs
ask femjuvs [
let natal-range patches in-radius 5
let density (count femadults-on natal-range + count maleadults-on natal-
range + count femjuvs-on natal-range + count malejuvs-on natal-range +
count infants-on natal-range)
let chance-disperse 1 / (1 + exp(2.051 - (0.002605 * density)))
if (random-float 1.001 < chance-disperse) [
let mean-distance (18.703 + (0.02533 * density))
I believe this will give me the proportion of the female juveniles that will disperse, as well as the mean dispersal distance, taken from literature (I realize the if statement is incomplete, this is where I'm stuck). My question is, how do I get the "femjuvs" who are dispersing to actually move? They would move until they reach an unoccupied patch in a radius that does not overlap the "natal range". Ideally, I would want all of the distances of the femjuvs who do disperse to have a mean of "mean-distance". I have "dispersal-distance" as a "femjuvs-own" variable, but I haven't set it to any value.
Any help with any part of this problem is appreciated. Thank you!
Possibly use: "setxy" or "forward"
setxy
If the aim is to update a deer position over time, calculating its coordinates, setxy might be a good option. This isn't so much moving as it is adjusting its coordinates.
ask femjuvs [ setxy <xcor> <ycor> ] ; example
ask femjuvs [ let x-coordinate <some-long-computation>
let y-coordinate <some-longer-computation>
setxy x-coordinate y-coordinate ]
forward
To move a deer, there is a function called "forward" that can be invoked by femjuvs (turtle/breed context):
ask femjuvs [ forward <number> ]
It would move femjuvs n spaces in the direction it is facing, where is the number specified.
Possible additions: (* - relevant functions)
to move-dispersing-femjuvs
ask femjuvs [
let natal-range patches in-radius 5
let density (count femadults-on ...) ; shortened for space
* forward 1 ; move forward one
]
...
end
Also, if dispersing from a given point or coordinate is necessary, having the deer face the point and turn it 180 degrees could work.
ask femjuvs [ face <random-point> ; or facexy <xcor> <ycor>
left 180 ] ; turn the opposite direction
ask femjuvs [ forward 1 ] ; disperse
One thing to note is that if the direction is not set by the developer, NetLogo will store a direction beforehand, which may or may not be helpful.
More details in : https://ccl.northwestern.edu/netlogo/docs/dictionary.html

Keeping agents in visual range while moving

I have a model whereby the agents are moving around looking for resources. The individuals move according to:
to move
set energy energy -1
fd v
if random 300 = 1 [
ifelse random 2 = 0
[rt 45][lt 45]]
end
What I would like them to do in addition to this is keep in visual range of each other or at least keep a certain group size in range.
In my head this would take the form of ifelse count turtles in-radius vision < 5 [move-towards-group][move]
I've tried a few things but the agents end up moving towards each other or losing contact while they enact some other routine causing an error.
I've looked at the flocking model as well but that's a bit too over parameterised for what I'm trying to achieve.
Hope you can help.
EDIT: Based on #JenB's advice I've come up with the following working model. But the agents here tend to swarm and can, on occasion, break off where they get stuck around a group < 5
to setup
clear-all
reset-ticks
crt 20
end
to go
ask turtles [move
group]
tick
end
to move
fd 0.01
if random 333 = 1 [
ifelse random 2 = 0
[rt 45][lt 45]]
end
to group
let midx mean [xcor] of other turtles in-radius 10
let midy mean [ycor] of other turtles in-radius 10
ifelse count other turtles in-radius 5 < 5 [facexy midx midy set color red][move set color blue]
end

Find the presence of other turtles in a given direction upto a distance

I wish to find out whether in a given turtle's heading there is another agent present upto a given distance.
Here the Distance is "D".
Note:
Any agent present before D in the given direction should be also considered.
Even the direction doesn't coincide with the other's agent centre but just touches it ,even then that agent should be considered.
Problem:
No turtle-ahead procedure available. Combination of patch-ahead and turtles-on not applicable due to patch-size>> turtle-size.
Possible approach:
1.Represent the turtle's heading by the equation of a line.
to-report calculate-line[x y angle]
let m tan angle
let A m
let B -1
let C (- m * x + y)
report (list A B C)
end
to-report heading-to-angle [ h ]
report (90 - h) mod 360
end
let line-equ calculate-line (xcor) (ycor) (heading-to-angle heading)
2.Calculate the perpendicular distance from other turtles here, Check if there are within a range that the size of other turtles.
to-report value[A X1 Y1];;A is list of coefficents of line, x1 and y1 are coordinates of red turtle
if-else(abs((item 0 A * X1 + item 1 A * Y1 + item 2 A) / (sqrt((item 0 A ^ 2) + (item 1 A ^ 2) ))) < [size] of wall )
[ report "true"][report "false"]
end
3.To check if the red turtle is within D. One could obtain a line perpendicular to black one and compute the red turtle distance from it to check if it is less than or equal to D. But then that adds more complication.(Though one can simplify rotate the turtle by 90 left or right and get the line equation.)
This is what I meant by my comment. Run this code (as its own model). What it does is turn all the turtles on a few 'ahead' patches a different colour. I know this is not what you are trying to do, but the agentset candidates is a relatively small number of turtles. These are the only ones that you have to check whether they are on the correct path. So instead of turning them a different colour you could check the direction that they are from your initial turtle.
to setup
clear-all
set-patch-size 25
resize-world -10 10 -10 10
create-turtles 1000
[ setxy random-xcor random-ycor
set color yellow
set size 0.4
]
ask one-of turtles
[ set color red
set size 1
check-from-me 5
]
end
to check-from-me [howfar]
let counter 0
let candidates turtles-here
while [counter < howfar]
[ set counter counter + 1
set candidates (turtle-set candidates turtles-on patch-ahead counter)
]
ask candidates [set color red]
end
to-report check-wall
let return false
hatch 1[
set color black
set size ([size] of one-of walls) / 2
show (2.5 * ([size] of myself))
while [distance myself < (2.5 * ([size] of myself))]
[
fd ([size] of one-of walls) / 64
if any? walls in-radius size
[
set return true
]
show distance myself
]
]
report return
end
The above works. But still is approx. I am looking for better solution with probably less maths as one elucidated in the question.

Preventing a NetLogo turtle from hitting a wall

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. :)

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: