Netlogo: measuring time using distance and tick interval - netlogo

I have a model where I want to measure the time a turtle takes to travel from from one patch to another given the scale of the map, 'speed' or distance traveled (map scale is 1000m x 1000m per patch for reference), and a desired time that elapses in one tick (in seconds).
I am trying to count the total time it takes using a turtles-own variable called totaltime.
Total time is determined by taking the total number of ticks minus extra ticks and then multiplying it by the time-interval (last line of code).
Extra ticks are counted because the loop has to operate when the ship is moving directly to the center of the patch in the list. this is necessary so the patch can be removed from the list allowing the turtle to search for the next patch in the list and so on (in the ifelse statement).
The use of extra-ticks may be redundant and jumping to exact patch locations may certainly not be the best way to have turtles traverse through a list of patches. Unfortunately I am new to netlogo and don't have a great grasp on the concept of ticks and correct context (turtle, observer, etc). If anyone could help me it would GREATLY appreciated as I have been stuck trying to figure this out for way too long.
> to move
> set speed 40
> set time-interval 1
> set ship-distance (time-interval / 3600) * speed
> set extra-ticks 0
> tick
> ask ships with [length current-path != 0]
> [
> go-to-next-patch-in-current-path
> ]
> end
>
> to go-to-next-patch-in-current-path
> face first current-path
> set total-ticks total-ticks + 1
> ifelse distance first current-path <= ship-distance
> [
> set extra-ticks (1 - (distance first current-path / ship-distance)) + extra-ticks
> print (distance first current-path / ship-distance)
> move-to first current-path
> set current-path remove-item 0 current-path
> ]
> [
> set normal-ticks normal-ticks + 1
> fd ship-distance
> ]
>
> set totaltime (ticks - extra-ticks) * time-interval / 60
> end

Related

Min expected input to be a list but got the number ... instead

I have a twist on the usual thread. I am working on a labor market where the firm will pick the worker asking for the lower firm out of all close workers until its capital is exhausted or there are no more unemployed workers available.
The problem is, NetLogo min command does not like it when there is only one worker left to choose from. This causes the error message:
MIN expected input to be a list but got the number 98.22043664491966 instead.
the code is as follows:
while [ (capital > min-wage) and (local-number > 2) ] [
let min-worker min-one-of local-unenmp [ salary ]
let wage [salary] of min-worker
ask min-worker [
set unemployed? false
set aggregate-employed (aggregate-employed + 1)
set wealth (wealth + wage)
set labor-check1 (labor-check1 + 1)
set local-unenmp local-unenmp with [self != myself]
set local-number count local-unenmp
]
set working (working + 1)
set capital (capital - wage)
if capital <= min-wage [stop]
if local-number < 3 [stop]
]
set labor working
set labor-check2 (labor-check2 + 1)
]

NetLogo: Issues when restricting number of users charging at a certain patch

I am working on a project to model the impact of charging electric cars on the grid and modeling/simulating the driving and charging habits of the car users. I'm getting an issue in my code that unable to resolve yet.
Each location has a limited number of charging ports. For example, WORK has a total of 2 TERMINALS, so only 2 adopters can charge there simultaneously (first-come-first-serve basis). What I want to do is when 2 adopters arrive at WORK, they start charging (if required, i.e. "charging-status" = true). Any additional adopters wait until a port is available there. The adopters who finish charging should vacate the charging port for those in the wait-list, even if they don't leave.
Here's part of my effort (code) that I did:
to go
...
charge-car ; sets the charging-status based on state-of-charge.
ask adopters
[
if charging? and not marked?
[
ifelse remaining-ports != 0
[
set remaining-ports max list (remaining-ports - 1) 0
set marked? true
]
[set occupied? true]
]
if marked? and not charging?
[
set remaining-ports min list (remaining-ports + 1) terminals
set marked? false
set occupied? false
]
]
ask adopters with [charging? and marked?]
[
set color green
let battery0 battery
let charging-speed0 charging-speed
let battery1 max list 0 ( battery + charging-speed0 )
set battery min list battery1 battery-capacity
let charged min list ( battery - battery0 ) charging-speed0
set charge-demand charge-demand + charged
set soc battery / battery-capacity
set range-left battery / discharge-patch
]
tick
end
Now, the issue is this: there are multiple location on the map with charging ports. This code gives different results at some locations, even though it is the same algorithm for all locations and agents. For example, if both ports are occupied at certain locations, the "occupied?" will be true for some locations and not all of the ones with all ports engaged. I mean to say, this is showing quite a random response.
Can anyone please help me with this? Is there another way to do what I want to do? Also, please let me know if you need more info to understand my situation.
Thank you!
Edit:
This is my code for to go
to go
...
ask adopters
[
if patch-here = current-loc ; choose next target only when reached at a destination (current location)
[
choose-target
set nearest-station min-one-of patches with [location = "charging-station"][distance myself]
] ; choose target based on start time and current location
; go to target only when NOT at the arbitrary target location
if target != [0 0]
[
let dist-to-targ distance-between current-loc target
let dist-to-station distance-between current-loc nearest-station
ifelse dist-to-targ > range-left and dist-to-station < range-left
[go-to-station nearest-station]
[go-to-target]
]
if charging = "Charge Car Now"
[charge-car]
...
]
where, charge-car is
to charge-car
if patch-here = current-loc and charging-point
[
ifelse soc < 1
[
if charge-power = 1
[
set charging-speed 1 / 12
set charging-status true
]
if charge-power = 2
[
set charging-speed 6.6 / 12
set charging-status true
]
]
[
set charging-status false
set color blue
]
]
end
and go-to-target is
to go-to-target
ifelse patch-here != target
[
; move towards destination and use fuel
face target
; set marked? false
set color blue
ifelse distance target <= speed
[set speed1 0.3 * distance target] ; decrease speed as target gets nearer
[set speed1 speed]
forward speed1
set moving? true
set charging-status false
if marked?
[
set rem-term min list (rem-term + 1) terminals
type patch-here type "Updated ports" print rem-term
set marked? false
set occupied? false
]
]
[
move-to target
if target != [0 0]
[set dist-trav distance-between current-loc target]
set current-loc target
set moving? false
set dwell dwell-acq day-ind time-ind position [location] of target places ; calculate dwell time based on arrival time at target
ifelse dwell < 0
[
set dwell 288 - (ticks mod 288) ; spend rest of the time till 24:00 at that location
set dwell-flag 1
]
[set dwell-flag 0]
if current-loc = target
[
set arrival-time (ticks mod 288)
set start-time (dwell + arrival-time) mod 288
set target [0 0]
set battery battery - (discharge-patch * dist-trav) ; discharge based on distance traveled per tick
set soc battery / battery-capacity
set range-left battery / discharge-patch
if battery < 0
[set battery 0]
if soc < 0
[set soc 0]
]
]
end
where, rem-term is same as remaining-ports and charging-status is same as charging?.
I tried adding the same code in the go-to-target function, since charging-status changes there first, but that didn't show any change in the results I'm getting.
I can't see anything obviously wrong with your code. This sort of thing usually happens because you have multiple ask turtles blocks, and you work out the intention in the first block but don't do the behaviour until the second block. In your case, I can see you updating the ports count in the first block, so that doesn't directly apply.
However, I wonder if you're doing something similar with your if statements, that turtles are going through different blocks than you expect and the relevant code is missing from the extract that you pulled out. The easiest way to diagnose this type of problem is with print statements. See below for one possibility.
ask adopters
[ if charging? and not marked?
[ ifelse remaining-ports > 0
[ type patch-here print remaining-ports
set remaining-ports remaining-ports - 1
set marked? true
type patch-here type "Updated ports" print remaining-ports
]
[ set occupied? true ]
]
if marked? and not charging?
[ set remaining-ports min list (remaining-ports + 1) terminals
set marked? false
set occupied? false
]
]
Note that I also changed your code for testing/updating number of remaining ports for clarity.
On your question about lists, there is no problem adding a turtle to a list (eg set queue lput self queue) but if you want more detail than that, please ask a separate question. I strongly recommend that you do not make any attempt to introduce queues for your ports until you have the existing code working properly.

Creating the game Snake on Netogo

I have to create the game snake on Netlogo, with specific instructions on how the snake has to move, as below:
"The snake moves by adding a square to its head and simultaneously deleting a square from the tip of its tail."
I believe that I have successfully managed to fulfill this condition, however, when taking a sharp turn everything falls apart, due to lines 105-110. The issue is that I can't seem to figure out how to specify which body segment has to become the tail in the next step.
ask heads [
if (count heads-here + count mice-here = 2) [
if heading = 0 [
hatch-heads 1 [
setxy xcor (ycor + 1)
;;and so on for all 4 directions
ask heads [
if heading = 0 [
hatch-heads 1 [
setxy xcor (ycor + 1)
;; and so on for all 4 directions
ask bodies [if (
count bodies-on neighbors4) + (
count heads-on neighbors4) + (
count tails-on neighbors4) < 2 [
set breed tails
set shape "square"]]
;; the above segment is where I believe the problem lies
I am hoping for the last "body" segment on the snake to turn into the breed "tail".

Counting turtles after a chunk of code has executed

In my model currently, I have a monitor on the Interface that counts the total number of turtles (deer in my case) every tick. Is it possible to have another monitor that counts the number of deer after a certain line of code is executed? For example, here's a snippet of code:
to catch-fawns-source
let fawn-hunting-rate (fawn-harvest-rate-source)
if any? fawns-on source-patches
[ ask fawns-on source-patches [
if random-float 1.0001 < (fawn-hunting-rate)
[ set harvest (harvest + 1)
set fawn-harvest (fawn-harvest + 1)
set source-harvest (source-harvest + 1)
die ] ]
]
end
In this case, this is where I have fawns being harvested. This code is the same for my male and female adult and juvenile deer. So is there a way I could track my population specifically after that snippet of code (and the other identical ones for the juveniles and adults) is executed?
I'm not sure if I would need any sort of Netlogo extension (if there are any applicable to this) or if I could somehow add in another global variable and lines of code that accomplishes this task.
Thanks for all of your help as always!
I think you can get away with another global variable that you just update however often you want. For a very simple example, consider this setup:
globals [ most-recent-pop-check ]
to setup
ca
crt 10
set most-recent-pop-check count turtles
reset-ticks
end
Here, most-recent-pop-check will only be updated when needed, then you can just set a monitor to display that variable. In this example, the value will only change every 25 ticks- see comments for more detail:
to go
ask turtles [
; Turtles may die
if random-float 1 < 0.25 [
die
]
; Throw in some density-dependence to control population size
if random-float 1 < ( 0.5 * ( 1 - ( count turtles / 500 ) ) ) [
hatch random 2 + 1
]
]
; If the ticks are not 0, and if the remainder after dividing
; the ticks by 0 is 0, update the most-recent-pop-check
; variable to reflect the current turtle population.
if ticks != 0 and ticks mod 25 = 0 [
set most-recent-pop-check count turtles
]
tick
end
Of course, in your case rather than having the update occur based on the number of ticks, just have it occur whenever you run the code chunk you're after.

Seed dispersal around a tree provokes an infinite loop?

I've just started a project in which I intend to simulate (among other things) the seed dispersal around trees (named zsps). Neighboring patches can already be settled or unable for seeding due to low fertility.
I wrote code that runs (at the begining of simulation) but that made the code enter into an infinite loop (I think) because some trees attempt to spread seeds but cannot find any available place.
Does anyone have a solution to escape from this trap (in case the number of places is < the number of seeds or in case there are no places at all)?
Here is the procedure I wrote :
to check-seed-dispersal
ask zsps[
let nb-seeds 0
ifelse (age > 4) [set NFemFlowers 100]
[set NFemFlowers 0]
let temp-color color
if Tot_pol > 0
[set nb-seeds round ((NFemFlowers / Tot_pol) * 6 ) ]
if (nb-seeds > 0 )[
ask patches in-radius 5 with [fertility > 8 and not any? zsps-here]
[sprout-zsps nb-seeds
[ifelse (temp-color = yellow)
[set color gray set age 0 ]
[set color red set age 0 ]
]
]
]
]
end