//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** @author John Miller, Casey Bowman * @version 2.0 * @date Tue Feb 4 14:56:34 EST 2020 * @see LICENSE (MIT style license file). * * @note Vehicle Is Enhanced SimActor Supporting Changing Velocities */ package scalation package simulation package process import scala.math.log val vehicleProps = Map ("τ" -> 1.0, // reaction time (defaults) "amax" -> 2.0, // max acceleration "bmax" -> -1.5, // max deceleration "v0" -> 0.0, // starting velocity "vmax" -> 33.528, // max velocity "T" -> 3.0, // min time headway "s" -> 5.0, // min distance headway "len" -> 4.0) // length of the vehicle //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** The Vehicle class extends the `SimActor` and represents a vehicle on a road. * @param label the label/name of the vehicle * @param director the model to which this vehicle belongs * @param prop the property map governing the motion of the vehicle */ abstract class Vehicle (label: String, director: Model, prop: Map [String, Double] = vehicleProps) extends SimActor (label, director): private val debug = debugf ("Vehicle", true) // debug function private [process] var disp = 0.0 // set initial current displacement to 0 private [process] var t_disp = 0.0 // set initial total displacement to 0 private [process] var velocity = prop("v0") // set initial velocity to v0 private var o_t_disp = t_disp // set initial old total displacement t_disp private var o_velocity = velocity // set initial old velocity to velocity private var acc = 0.0 // set initial acceleration to 0 private var o_acc = acc // set initial old acceleration acc def rt: Double = prop("rt") // reaction time def amax: Double = prop("amax") // max acceleration def bmax: Double = prop("bmax") // max deceleration def v0: Double = prop("v0") // starting velocity def vmax: Double = prop("vmax") // max velocity def T: Double = prop("T") // min time headway def s: Double = prop("s") // min distance headway def len: Double = prop("len") // length of the vehicle //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** Update the values of the vehicle: velocity, displacement, lane according * to the car-following model being used. * @param gipps whether to use the Gipps or IDM car-following model */ def update (gipps: Boolean = true): Unit = if gipps then gippsUpdate () else iDMUpdate () end update //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** Update the vehicle's velocity and position using Gipps' Model (located in `Motion`) * and Butcher's method for solving ordinary differential equations. * @param prop the property map governing the motion of a vehicle */ def gippsUpdate (): Unit = val v = Motion.gipps (this, pred.asInstanceOf [Vehicle]) val x = Motion.butcher (t_disp, v, velocity, rt) o_velocity = velocity velocity = v val dx = x - t_disp disp += dx o_t_disp = t_disp t_disp = x end gippsUpdate //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** Update the vehicle's acceleration, velocity, and position using the * Intelligent Driver Model (located in `Motion`) and Butcher's method * for solving ordinary differential equations. */ def iDMUpdate (): Unit = var a = Motion.iDM (this, pred.asInstanceOf [Vehicle], rt) // was delta ??? debug ("iDMUpdate", s"name: \t the new ACCELERATION is: $a") if a.isNaN then a = 0.0 if a.isNegInfinity then a = bmax // max braking acceleration if a.isPosInfinity then a = amax // max forward acceleration if a < 0.0 && a < bmax then val r = log(a) / log (bmax) a = if r > 5.0 then 3.0 * bmax else bmax // FIX - unclear if a > 0.0 && a > amax then a = amax var v = Motion.butcher (velocity, a, acc, rt) debug ("iDMUpdate", s"name: \t the new VELOCITY is: $v") if v < 0.0 then v = 1.0 // move slowly, not stopped val x = Motion.butcher (t_disp, v, velocity, rt) debug ("iDMUpdate", s"name: \t the new POSITION is: $x") o_acc = acc acc = a o_velocity = velocity velocity = v val dx = x - t_disp disp += dx o_t_disp = t_disp t_disp = x end iDMUpdate end Vehicle