Skip to content

Commit

Permalink
added the Gipps car folowing model- first order model (#776)
Browse files Browse the repository at this point in the history
* added the Gipps car folowing model- first order model

* added the Gipps car folowing model- first order model_

* tests for GippsController
  • Loading branch information
gilbertbahati authored and AboudyKreidieh committed Nov 20, 2019
1 parent 7a99a56 commit 27f0cfd
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 3 deletions.
5 changes: 3 additions & 2 deletions flow/controllers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from flow.controllers.base_controller import BaseController
from flow.controllers.car_following_models import CFMController, \
BCMController, OVMController, LinearOVM, IDMController, \
SimCarFollowingController, LACController
SimCarFollowingController, LACController, GippsController
from flow.controllers.velocity_controllers import FollowerStopper, \
PISaturation

Expand All @@ -34,5 +34,6 @@
"CFMController", "BCMController", "OVMController", "LinearOVM",
"IDMController", "SimCarFollowingController", "FollowerStopper",
"PISaturation", "StaticLaneChanger", "SimLaneChangeController",
"ContinuousRouter", "GridRouter", "BayBridgeRouter", "LACController"
"ContinuousRouter", "GridRouter", "BayBridgeRouter", "LACController",
"GippsController"
]
85 changes: 85 additions & 0 deletions flow/controllers/car_following_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,3 +499,88 @@ class SimCarFollowingController(BaseController):
def get_accel(self, env):
"""See parent class."""
return None


class GippsController(BaseController):
"""Gipps' Model controller.
For more information on this controller, see:
Traffic Flow Dynamics written by M.Treiber and A.Kesting
By courtesy of Springer publisher, http://www.springer.com
http://www.traffic-flow-dynamics.org/res/SampleChapter11.pdf
Usage
-----
See BaseController for usage example.
Attributes
----------
veh_id : str
Vehicle ID for SUMO identification
car_following_params : flow.core.param.SumoCarFollowingParams
see parent class
v0 : float
desirable velocity, in m/s (default: 30)
acc : float
max acceleration, in m/s2 (default: 1.5)
b : float
comfortable deceleration, in m/s2 (default: -1)
b_l : float
comfortable deceleration for leading vehicle , in m/s2 (default: -1)
s0 : float
linear jam distance for saftey, in m (default: 2)
tau : float
reaction time in s (default: 1)
noise : float
std dev of normal perturbation to the acceleration (default: 0)
fail_safe : str
type of flow-imposed failsafe the vehicle should posses, defaults
to no failsafe (None)
"""

def __init__(self,
veh_id,
car_following_params=None,
v0=30,
acc=1.5,
b=-1,
b_l=-1,
s0=2,
tau=1,
delay=0,
noise=0,
fail_safe=None):
"""Instantiate a Gipps' controller."""
BaseController.__init__(
self,
veh_id,
car_following_params,
delay=delay,
fail_safe=fail_safe,
noise=noise
)

self.v_desired = v0
self.acc = acc
self.b = b
self.b_l = b_l
self.s0 = s0
self.tau = tau

def get_accel(self, env):
"""See parent class."""
v = env.k.vehicle.get_speed(self.veh_id)
h = env.k.vehicle.get_headway(self.veh_id)
v_l = env.k.vehicle.get_speed(
env.k.vehicle.get_leader(self.veh_id))

# get velocity dynamics
v_acc = v + (2.5 * self.acc * self.tau * (
1 - (v / self.v_desired)) * np.sqrt(0.025 + (v / self.v_desired)))
v_safe = (self.tau * self.b) + np.sqrt(((self.tau**2) * (self.b**2)) - (
self.b * ((2 * (h-self.s0)) - (self.tau * v) - ((v_l**2) / self.b_l))))

v_next = min(v_acc, v_safe, self.v_desired)

return (v_next-v)/env.sim_step
59 changes: 58 additions & 1 deletion tests/fast_tests/test_controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

from flow.controllers.routing_controllers import ContinuousRouter
from flow.controllers.car_following_models import IDMController, \
OVMController, BCMController, LinearOVM, CFMController, LACController
OVMController, BCMController, LinearOVM, CFMController, LACController, \
GippsController
from flow.controllers import FollowerStopper, PISaturation
from tests.setup_scripts import ring_road_exp_setup
import os
Expand Down Expand Up @@ -635,5 +636,61 @@ def test_get_action(self):
np.testing.assert_array_almost_equal(requested_accel, expected_accel)


class TestGippsontroller(unittest.TestCase):
"""
Tests that the Gipps Controller returning mathematically accurate values.
"""

def setUp(self):
# add a few vehicles to the network using the requested model
# also make sure that the input params are what is expected
contr_params = {
"v0": 30,
"acc": 1.5,
"b": -1,
"b_l": -1,
"s0": 2,
"tau": 1,
"delay": 0,
"noise": 0,
}

vehicles = VehicleParams()
vehicles.add(
veh_id="test",
acceleration_controller=(GippsController, contr_params),
routing_controller=(ContinuousRouter, {}),
car_following_params=SumoCarFollowingParams(
accel=15, decel=5),
num_vehicles=5)

# create the environment and network classes for a ring road
self.env, _ = ring_road_exp_setup(vehicles=vehicles)

def tearDown(self):
# terminate the traci instance
self.env.terminate()

# free data used by the class
self.env = None

def test_get_action(self):
self.env.reset()
ids = self.env.k.vehicle.get_ids()

test_headways = [2, 4, 6, 8, 10]
for i, veh_id in enumerate(ids):
self.env.k.vehicle.set_headway(veh_id, test_headways[i])

requested_accel = [
self.env.k.vehicle.get_acc_controller(veh_id).get_action(self.env)
for veh_id in ids
]

expected_accel = [0., 5.929271, 5.929271, 5.929271, 5.929271]

np.testing.assert_array_almost_equal(requested_accel, expected_accel)


if __name__ == '__main__':
unittest.main()

0 comments on commit 27f0cfd

Please sign in to comment.