Humans Turn Up and Go at a Train Station

Humans Turn Up and Go at a Train Station preview image

1 collaborator

Default-person Mathew Hounsell (Author)

Tags

courseware 

Tagged by Mathew Hounsell over 6 years ago

queueing 

Tagged by Mathew Hounsell over 6 years ago

trains 

Tagged by Mathew Hounsell over 6 years ago

transport 

Tagged by Mathew Hounsell over 6 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.0.3 • Viewed 736 times • Downloaded 54 times • Run 0 times
Download the 'Humans Turn Up and Go at a Train Station' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


WHAT IS IT?

A model of persons waiting at a train station. The persons are arrive randomly and will be picked up periodically by a train consist.

HOW IT WORKS

The simulation is designed to run at 1 updates per second. The tick control does control the speed of the simulation. See the SIMULATION-SPEED control.

Trains

A train is made up of one engine and several carriages.

In most cities like Sydney, Australia the urban trains are made of Electric Multiple Units (EMU). The first and last carriage of a Sydney Waratah train has the driver cab and engine embedded in both the first and last carriages. The train can thus be driven in both directions from either end of the train. Although generally drivers should be in the forward cab.

Engines

In this simulation an engine pulls the carriages. This simplifies the simulation as the engine is the master agent controlling the subordinate carriages.

There can only be 0 or 1 engine. World wrap breaks the train logic.

Engines always stop past the end of the platform (at coordinate 0).

Carriages

Each carriage has a load and can accept one passenger at a time.

If there are carriages but no engine then the train is leaving the right side of the world.

Humans

Humans arrive from the houses off the bottom of the world. Humans will travel up the path to the platform.

Humans will move up, up-left, up-right or right in order to be in front of a carriage. Humans will not move through another human, nor will they move backward. Humans will not enter the world if the path is full.

Humans board carriages

When the engine is stopped, the carriages will dwell at the platform and one human per interval can board the train. The train will only well for 20 simulation updates (2 seconds of simulated time.) You can tell if a train is dwelling because it will turn magenta.

HOW TO USE IT

CONTROL

SETUP

Click 'Setup' to erase the current state and start again.

GO

Click 'Go' to start or stop simulation from running continously. While the simulation is running the 'Go' button will be depressed.

GO ONCE

To assist in your understanding you can step through individual ticks of the simulation. Stop the simulation is stopped and click the 'Go Once' button to progress the simulation just one update. Note that humans only move as fast as HUMANINTERVAL and may not move for several updates._

SIMULATION-SPEED

Control the relative speed of the simulation. Choose speed from 8x, 4x, 2x, 1, 1/2, 1/4. 1/8.

DELAY TRAIN X

Click this button to increase the delay for the creation of the next engine by 60 or 300 seconds (in simulation time).

See ENGINE-INTERVAL and ENGINE-COUNTDOWN

CONFIGURE

CARRIAGE-LENGTH

The number of carriages that will follow the next engine. Range [2..12]. This variable will only impact the next train, not a current train.

ENGINE-INTERVAL

The number of seconds (in simulation time) before the next engine is due to be created.

See 'DELAY TRAIN X' and ENGINE-COUNTDOWN

HUMAN-INTERVAL and HUMAN-FREQUENCY

The interval is the number of seconds (in simulation time) before the next human might be created.

The frequency is the chance of a human being created this interval.

Some of the behaviour is easy to see with a 100% frequency and a lower interval. However to simulate random arrival a frequency less than 50% frequency is needed.

INFORMATION

COUNT-ENGINES and COUNT-CARRIAGES gives you the count of engines and carriages at the last update. There is a plot on the right hand side labelled 'Trains' which records the number of engines (red) and the number of carriages (blue) over time.

HUMANS-OUTSIDE and HUMANS-INSIDE

The number of humans on the current train are displayed a HUMANS-INSIDE. The number of humans on the path or platform are displayed as HUMANS-OUTSIDE.

On the right hand side of the display there is a plot of the number of humans outside over the simulated time. This plot tracks the number of humans queueing.

ENGINE COUNTDOWN

The number of simulation updates until the next engine is created. If an engine exists this display is "-". If you 'DELAY TRAIN X' the countdown will increase.

DWELL-COUNTDOWN

The number of simulation updates until the carriage door close and the engine departs,

THINGS TO NOTICE

Trees make your city nicer.

THINGS TO TRY

Make the HUMAN-INTERVAL 20 and the HUMAN-FREQUENCY 100, let four trains collect humans. Now delay the next train, what happen to the queue?

EXPANDING THE MODEL

Increase the scale of the simulated time to be more realistic.

COPYRIGHT AND LICENSE

Copyright 2018 Mathew Hounsell, Institute of Sustainable Futures, University of Technology Sydney

CC BY-NC-SA 3.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Comments and Questions

20180327 Update

The new version of the model no longer uses no-display and will work in the browser.

Posted over 6 years ago

Click to Run Model

; Copyright 2018 Mathew Hounsell, Institute of Sustainable Futures, University of Technology Sydney
; CC BY-NC-SA 3.0
; This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.
; To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Definitions
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Maximum Train/Platform Length 12
globals [
  last_new_human_tick
  last_new_engine_tick
  last_move_tick
  next_carriage_delay
  dwelling_max
]

breed [ engines engine ]
breed [ carriages carriage ]
breed [ humans human ]
breed [ flora florum ]

engines-own [
  dwell
]
carriages-own [
  load
]

; ~~~~~~~~~~~~~~~~~~~~
; Reporting
; ~~~~~~~~~~~~~~~~~~~~

to-report ticks-of-next-new-engine
  report last_new_engine_tick + engine-interval
end 

to-report is-time-to-make-new-engine
  report ticks >= ticks-of-next-new-engine
end 

to-report is-time-to-make-new-human
  let t ( human-interval )
  report ticks >= last_new_human_tick + t
end 

to-report is-time-to-move
  report ticks >= last_move_tick + 2
end 

to-report get-load-on-carriages
  if count engines < 1 [
    report 0
  ]
  let c 0
  ask carriages [ set c ( c + load ) ]
  report c
end 

to-report can-platform-be-at-coord [ x ]
  report x > -13 and x < 0
end 

to-report can-engine-be-at-coord [ x ]
  report x > (0 - carriage-length - 1) and x < 0
end 

to-report can-next-stopping-engine-be-at-coord [ x ]
  let active-engine false
  ; no engine
  if count engines > 1 [
    ask engines [
      ; past station
      if xcor <= 0 and xcor > (min-pxcor + carriage-length + 1) [
        set active-engine true
      ]
    ]
  ]
  if not active-engine [ report can-engine-be-at-coord x ]
  report x > (0 - (count carriages) - 1) and x < 0
end 

to-report coord-to-location [ x y ]
  if y = 0 [ report "dirt" ]
  if y = -1 [ report "railway" ]
  if y = -2 and not can-platform-be-at-coord x [ report "dirt" ]
  if ( y = -2 or y = -3 ) and can-platform-be-at-coord x [ report "platform" ]
  if y < 0 and can-platform-be-at-coord x [ report "path" ]
  report "grass"
end 

to-report tree-color [ v ]
  if v < 1.0 [ report red - 2 ]
  if v < 2.0 [ report orange - 1 ]
  if v < 3.0 [ report yellow - 1 ]
  report green - 3
end 

to-report dwell-countdown
  let dwelling "-"
  if (count engines-on patch 0 -1) = 1 [
    ask engines [
      set dwelling dwell
    ]
  ]
  report dwelling
end 

to-report engine-countdown
  if count engines < 1 [
    let t ( ticks-of-next-new-engine - ticks )
    if t < 0 [ report 0 ]
    report t
  ]
  report "-"
end 

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Setup
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

to startup
  setup
end 

to setup
  clear-all
  reset-ticks
  set last_new_human_tick 0
  set last_new_engine_tick 0
  set last_move_tick 0
  set dwelling_max 20

  set-default-shape engines "train passenger engine"
  set-default-shape carriages "train passenger car"
  set-default-shape humans "person"
  set-default-shape flora "tree"

  setup-patches
end 

to setup-patches
  ask patches [
    let loc ( coord-to-location pxcor pycor )
    let grass ( green - 0.25 + random-float 1.5 )
    set pcolor ( ifelse-value (loc = "railway") [black] [ifelse-value (loc = "platform") [grey] [ifelse-value (loc = "dirt") [brown] [ifelse-value (loc = "path") [green] [grass]]]] )
  ]

  let c 0
  while [ c < 40 ] [
    let x random-pxcor
    let y random-pycor
    let loc ( coord-to-location  x y )
    if loc = "grass" and not any? flora-on patch x y [
      create-flora 1 [
        setxy x y
        set color tree-color random-float 5.0
      ]
      set c ( c + 1 )
    ]
  ]
end 

; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Running
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

to go
  every 0.1 / simulation-speed [
    ; let us set the tick rate at 10 fps
    ; then we shall assume that every tick is equivilant to 1 sec
    ; the fps is 24 so that it is a multiple of 8
    go-single
    tick
  ]
end 

to go-single
  ;; not available in the web -> no-display ;; to keep the carriages moving as one
  ifelse count engines > 0 or count carriages > 0 [
    move-engines
  ] [
    make-new-engine
  ]
  make-new-carriage ; use the fact that the last carriage may have moved into the second square to test
  ;; not available in the web -> display

  move-humans
  make-new-human
end 

; ~~~~~~~~~~~~~~~~~~~~
; Control
; ~~~~~~~~~~~~~~~~~~~~

to delay-next-engine [ duration ]
  set last_new_engine_tick ( last_new_engine_tick + duration )
end 

; ~~~~~~~~~~~~~~~~~~~~
; Movement
; ~~~~~~~~~~~~~~~~~~~~

to move-engines
  let dwelling 0
  ask engines [
    ifelse not can-move? 1 [
      die
    ][
      set dwelling dwell
      ifelse dwell > 0 [
        set dwell dwell - 1
      ][
        fd 1
        if xcor = 0 [
          set dwell dwelling_max + 1
        ]
      ]
    ]
  ]
  foreach sort-on [ xcor ] carriages [ the-carriage -> ask the-carriage [
    ifelse not can-move? 1 [
      die
    ][
      if dwelling = 0 [
        fd 1
      ]
    ]
  ] ]
  ifelse dwelling > 1 [
    ask engines [ set color magenta ]
    ask carriages [ set color magenta ]
  ][
    ask engines [ set color white ]
    ask carriages [ set color white ]
  ]
end 

to move-a-human [ dwelling ]
  if dwelling > 1 and dwelling < dwelling_max and ycor = -2 [
    let hxcor xcor
    if any? carriages-on patch hxcor -1 [
      ask carriages with [ xcor = hxcor and ycor = -1 ] [ set load load + 1 ]
      die
    ]
  ]
  if ycor < -2 [
    let newy ( ycor + 1 )
    if heading = 180 [ set newy ( ycor - 1 ) ]
    ; go forward
    if can-next-stopping-engine-be-at-coord (xcor) and not any? turtles-on patch xcor newy [
      setxy xcor newy
      stop
    ]
    ; prefer to move up and right
    if can-next-stopping-engine-be-at-coord (xcor + 1) and not any? turtles-on patch (xcor + 1) newy [
      setxy xcor + 1 newy
      stop
    ]
    ; then to move up and left
    if can-next-stopping-engine-be-at-coord (xcor - 1) and not any? turtles-on patch (xcor - 1) newy [
      setxy xcor - 1 newy
      stop
    ]
  ]
  ; try moving right
  if not can-next-stopping-engine-be-at-coord (xcor) and (xcor + 1 < 0) and not any? turtles-on patch (xcor + 1) ycor [
    setxy (xcor + 1) ycor
  ]
end 

to move-humans
  if is-time-to-move
  [
    let dwelling 0
    ask engines with [ xcor = 0 ] [
      set dwelling dwell
    ]

    ; remember it is [start..stop) by step
    foreach (range -2 (min-pycor - 1) -1) [ y ->
      foreach (range -1 -14 -1) [ x ->
        ask humans with [ xcor = x and ycor = y ] [
          move-a-human dwelling
        ]
      ]
    ]
    set last_move_tick ticks
  ]
end 

; ~~~~~~~~~~~~~~~~~~~~
; Creation
; ~~~~~~~~~~~~~~~~~~~~

to make-new-human
  if is-time-to-make-new-human [
    set last_new_human_tick ticks
    let dir 0 ; ( floor ( random-float 1.9 ) ) * 180
    let x ( -1 - floor ( random-float carriage-length ) )
    let y min-pycor
    if dir = 180 [ set y max-pycor ]
    if (random-float 100 < human-frequency) and not any? turtles-on patch x y [
      create-humans 1 [
        setxy x y
        set heading dir
        set color cyan ; one-of [ yellow red blue orange cyan ]
        set shape one-of [ "person business" "person construction" "person doctor" "person service" "person lumberjack" "person student" ]
      ]
    ]
  ]
end 

to make-new-carriage
  if count carriages < carriage-length [
    if any? turtles-on patch (min-pxcor + 1) -1 [
      create-carriages 1 [
        setxy min-pxcor -1
        set heading 90
        set color white
        set load 0
      ]
    ]
  ]
end 

to make-new-engine
  if count engines > 0 [ error "Asked to make a engine when one already exists." ]

  if is-time-to-make-new-engine [
    set last_new_engine_tick ticks

    create-engines 1 [
      setxy min-pxcor -1
      set heading 90
      set color white ; one-of [ yellow red blue orange cyan ]
      set dwell 0
    ]
  ]
end 

There are 2 versions of this model.

Uploaded by When Description Download
Mathew Hounsell over 6 years ago More realistic speed and now works on the web. Download this version
Mathew Hounsell over 6 years ago Initial upload Download this version

Attached files

File Type Description Last updated
Humans Turn Up and Go at a Train Station.png preview Preview for 'Humans Turn Up and Go at a Train Station' over 6 years ago, by Mathew Hounsell Download

This model does not have any ancestors.

This model does not have any descendants.