Pathfinding on Netlogo - Robotic lawn mower simulation project - netlogo

I am trying to simulate a robotic lawn mower on Netlogo. My goals were that :
It goes randomly on green patches (grass) to cut them (green turns grey).
It finds its way home to recharge itself when the battery is low.
It does not go away the defined perimeter (garden) narrowed by red patches and goes arround obstacles placed by user with mouse clicks.
I have now a working code for my two first objectives(thanks to Luke !).
However making the lawn mower respect my whish of not going on red patches is getting complicated after getting in the to check death step.
Indeed it seems that it does not take into account my previous orders in the to move-cars step.
Some people told me that if I wanted to make it navigate around the walls it would be actually pretty involved and will require some kind of pathfinding.
Through my research I found some documentation about what is called an A*.
I understood the concept of the algorithm well but its translation on Netlogo is very difficult for me. What I did without a course so far was pretty basic, based on existing codes and following the advice I was given. But from now on, adapting an A* for my code makes me lose my hair. I hope to be able to finally understand the intricacies of Netlogo by understanding how pathfinding would be implemented in my code.
I understand that some people will not want to dwell on explaining how it works. I just hope to find someone patient enough to explain to me how things work with an A* step by step.
Thanks a lot
Here's my code :
breed [cars car]
cars-own [target charging? charge-time car-energy]
breed [houses house]
to setup
clear-all
setup-patches
setup-cars
setup-house
reset-ticks
end
to setup-patches
ask patches [set pcolor green] ;; Setup grass patches
ask patches with [
pxcor = max-pxcor or
pxcor = min-pxcor or
pycor = max-pycor or
pycor = min-pycor ] [
set pcolor red ;; Setup garden perimeter
]
end
to setup-cars
set-default-shape cars "car"
create-cars 1 [
setxy 8 8 ;; Place the lawn mower near the house
set target one-of houses
set charging? false
set car-energy energy
]
end
to setup-house
set-default-shape houses "house"
ask patch 7 8 [sprout-houses 1]
end
to place-walls
if mouse-down? [
ask patch mouse-xcor mouse-ycor [ set pcolor red ]
display ;; Permits the user to place red patches as new obstacles in garden.
]
end
to go
move-cars
cut-grass
check-death ;; Verify % battery.
tick
end
to move-cars
ask cars [
ifelse charging? [
set charge-time charge-time + 1 ;; Counts the time spent to charge
if charge-time > 15 [ ;; Defined charge time here
set car-energy 1000
set charging? false
set charge-time 0
]
] [
ifelse [pcolor] of patch-ahead 1 = red
[ lt random-float 360 ] ;; See a red patch ahead : turn left randomly
[ fd 1 ] ;; Otherwise, its safe to go foward.
set car-energy car-energy - 1
]
]
end
to cut-grass
ask cars [
if pcolor = green [ ;; cut grass (green patches go grey)
set pcolor gray
]
]
end
to check-death ;; checking battery level
ask cars [
ifelse car-energy >= 300
[ set label "Energy ok" ]
[ set label "Low Energy, returning to base"
set target min-one-of houses [distance myself]
face target
ifelse distance target < 1
[ move-to target
set charging? true
set label "Charging"
]
[ fd 1 ]
]
]
end

Related

getting a particular colored turtle to do something on a particular colored patch in Netlogo

I am putting together a Netlogo model where students and criminals are interacting on a college campus. If criminals are close to students, a chase ensues so that when a criminal is distance < 1 the student dies. In addition to dying when criminal are to close I also want students(leader) to die during the chase when they are on a green patch. Green patches in this sense equate 'safe' areas. I have procedures set up for criminals chasing(follower) and students running away(leader), but I am at a complete block with getting the students being chased to die when coming across a green patch. One thought I had was making students being chased blue with the follower procedure:
ask students[
set no-threat criminals in-radius 25
ifelse any? no-threat[set color blue][set color black]
]
Then having blue students die when they encounter a green patch. I think I am missing something obvious to get this to work. Any nudge in the right direction would be much appreciated!
FYI, I am also relatively new to asking questions here so all apologize for any forum faux pas
here is the meat of the program I have been working on for reference
'''
to move-to-student
ask criminals[
set candidate students in-radius 25
if any? candidate[
set leader min-one-of candidate [distance myself]
if leader != nobody [ set color red]
;set follower myself
face leader
fd .3
if [pcolor] of patch-ahead 5 = 2.2 [
set heading heading - 100]
]
]
end
to run-from-criminal
ask students[
;while[distance follower > 1][
set threat criminals in-radius 25
if any? threat[
set follower min-one-of threat [distance myself]
if distance follower < 1 [ set number-dead number-dead + 1 die]; set candidate leader set threat follower ] ;students 'die' if criminal gets to close
if threat != nobody [set color blue]
face follower
rt 180 lt random 20 rt random 20 fd .2
if [pcolor] of patch-ahead 5 = 2.2 [
set heading heading - 100]
]]
end
to safe-die
ask students[
if follower = blue and if [pcolor] of patch-here = green [die]
]
end
to revert-leader
ask students[
set no-threat criminals in-radius 25
ifelse any? no-threat[set color blue][set color black]
]
end
to create-new-students
ask students[
if count students < student-count [hatch 1 setxy random-xcor random-ycor]
]
end
I figured it out. Maybe writing it down helped.
Looks like my solution was a combination of a nested if statement (something I've tried and failed at previously) and assigning the agents I want to die to an agent-set. There might be a better way to get this done but I wanted to share the solution I got...
ask students[
if any? no-threat[if [pcolor] of patch-here = green [die]
]

NETLOGO: pass on water amount along the nodes of a river network

I would like to simulate the water flow along a river with NETLOGO. Therefore I do have many water nodes which are linked to each other; and each water node having the variable "amount_water". Every tick, the variable "amount_water" should be passed on to the next water node. At each node waterusers (various agents) can interact with the stream flow and extract some water, which would change the variable "amount_water"; but now I would like show you the modelled river flow only, without the water users.
if you have a model world with min-pycor -6 and max-pycor 6:
breed [waternodes waternode]
waternodes-own
[
amount_water
]
to setup
clear-all
reset-ticks
; create the waternodes
create-waternodes 13 [setxy 0 (who - 6) set shape "dot" set color blue]
ask waternodes
[
let neighborbelow waternodes-on neighbors4 with [pycor < [ycor] of myself]
create-links-to waternodes-on neighborbelow
]
end
to go
move-water
update-inflow
tick
end
to move-water
ask waternodes
[
ask out-link-neighbors [set amount_water [amount_water] of myself]
]
end
to update-inflow
ask waternode 12 [set amount_water ticks]
end
(in my model, the inflow is of course not the number of ticks, but it is read in from a csv-file)
My problem: With this code, the amount of water is NOT continuously passed on from node to node (and I do not know why!!) ????
And generally, I am not so sure if this network is the best idea to represent a stream flow. Can you think of other solutions?
Many thanks
I have solved the problem so far. It seems that when I just call the waternodes in move-water like this
to move-water
ask waternodes
[
ask out-link-neighbors [set amount_water [amount_water] of myself]
]
end
, the waternodes are not always called in order from 0 to 11.
Therfore I changed the code to
to move-water
(foreach sort-on [who] waternodes
[the-turtle -> ask the-turtle [ask out-link-neighbors [set amount_water [amount_water] of myself]]])
end
and now it is working!

Turtle Behavior after asking for Patch Evaluation

I'm creating a fish-tank style simulation in NetLogo. There are "prey", "predators", and "hidingspots".
The idea is that when a predator appears on the map, the prey will individually run the "hide" behavior and head to the nearest "hidingspot" - provided there are no predators between it and the "hidingspot".
to move-turtles
ask prey [
if (any? predators)
[
hide
stop
]
The relevant code to run the hide command.
to hide
face min-one-of hidingspot [distance myself]
set d distance min-one-of hidingspot [distance myself]
ask patches in-cone d 80
[ set pcolor yellow
if (any? predators-here)
[ ask prey
[ forward 1
set color red
output-print "DANGER"]]]
forward 1
end
The problem is that I do not know how to use the if statement in the "ask patches" properly. And therefore when one prey spots a threat all prey are running the else part of the statement rather than evaluating it individually.
How would I fix this?
Any help is appreciated.
You need to separate what you are asking the prey to do from what you are asking the patches to do. As King-Ink said, you are asking the patches to ask all the prey to do things.
The easiest way is to create a patchset for the 'danger' patches and then check if there's a predator on those patches. To do this, you want something like the following (note that this is a complete model, so you can copy this whole code into a new model and run it).
A couple of other things in your code that I cleaned up. I used let for the local variable d so that it doesn't have to appear in your globals. I asked for min-one-of only once and reused because otherwise a different hidingspot could be selected each time (if multiple at same distance). While this would not have caused an error this time (because the second selection is just to find the distance which is, by definition, the same), it is good practice.
breed [prey a-prey]
breed [predators predator]
breed [hidingspots hidingspot]
to setup
clear-all
create-predators 1 [setxy random-xcor random-ycor set color red]
create-prey 5 [setxy random-xcor random-ycor set color brown]
create-hidingspots 20
[ setxy random-xcor random-ycor
hide-turtle
ask patch-here [set pcolor green]
]
reset-ticks
end
to go
ifelse any? predators
[ ask prey [hide] ]
[ ask prey [swim] ]
end
to hide ; turtle procedure
let target min-one-of hidingspots [distance self]
let path patches in-cone distance target 80
ask path [ set pcolor yellow ]
if any? predators-on path
[ set color red
output-print "DANGER"
face target
]
forward 1
end
to swim
end
you are asking each prey to ask all prey to hide. If you drop the ask prey from the command all prey are running it should work fine and be a bit faster
to hide
face min-one-of hidingspot [distance myself]
set d distance min-one-of hidingspot [distance myself]
ask patches in-cone d 80
[set pcolor yellow]
if (any? predators-here)
[
forward 1
set color red
output-print "DANGER"
]
end

NetLogo - find minimum angle between two patches in patchset

I'd like to find the set of patches that constitute the convex hull around a set of patches belonging to the turtle's territory. I was planning to use a "gift wrap" procedure to calculate the convex hull (related to below picture).
I'm first finding the territory patch with the lowest pxcor to start at. Then, I'd like to find the territory patch that has the smallest heading (i.e., angle closest to zero) from the starting patch, and so on, until I arrive back at the starting patch. But I can't seem to figure out how to calculate headings between two patches. Any suggestions would be really helpful. Here is what I have so far. Eventually I will have to make this loop through each point along the outer hull.
patches-own [ owner-animal ]
turtles-own [ territory ]
to setup
ca
create-turtles 1
[
move-to patch-at (max-pxcor / 2) (max-pycor / 2)
set territory patches in-radius (2 + random 8)
ask territory [
set owner-animal myself
set pcolor [ color ] of myself - 2
]
]
end
to find-convex-hull
ask turtles
[
let start-patch min-one-of territory [pxcor]
ask start-patch
[
let next-patch min-one-of [territory] of myself [towards self]
]
]
end
I think this does what you're looking for. The only odd thing about the code is the [towards myself - heading] of myself] in which the first myself refers to the next turtle and the second myself refers to original, because it is the myself of the myself.
Does that make sense? Let me know if you have any questions.
to setup
ca
crt 10 [setxy random-xcor random-ycor]
end
to start-connecting
ask min-one-of turtles [xcor][set heading 0 connect]
end
to connect
let the-turtle min-one-of other turtles with [[towards myself - heading] of myself > 0] [ [towards myself - heading] of myself]
if the-turtle = nobody [stop]
face the-turtle
ask the-turtle [set heading [heading] of myself]
create-link-with the-turtle
ask the-turtle [connect]
end
By the way, if you only want to do this for particular agentsets, just change which turtles you connect with in the connect procedure.

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!