Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilizes ACC and Midpoint controllers #33

Merged
merged 3 commits into from
Sep 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions python/carfns.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ def carFn((idx, car), sim, step):
traci.vehicle.changeLane(car["id"], maxl, 10000)
return carFn

def ACCFnBuilder(follow_sec = 3.0, max_speed = 26.8, gain = 0.01):
def ACCFnBuilder(follow_sec = 3.0, max_speed = 26.8, gain = 0.01, beta = 0.5):
"""
Basic adaptive cruise control (ACC) controller
:param follow_sec:
:param follow_sec: number of seconds worth of following distance to keep from the front vehicle
:param max_speed: 26.8 m/s = 60 mph
:param gain:
:param gain: gain for tracking following distance
:param beta: gain for tracking speed of front vehicle
:return: ACCFn to input to a carParams
"""

def ACCFn((idx, car), sim, step):
"""
P controller
:param idx:
:param car:
:param sim:
Expand All @@ -70,7 +70,8 @@ def ACCFn((idx, car), sim, step):
# TODO(cathywu) Setting tau to any value seems to cause collisions
# traci.vehicle.setTau(vehID, 0.01)

if step < 250:
if step < sim.simSteps/2:
# changeFasterLaneBuilder()((idx, car), sim, step)
return

try:
Expand All @@ -89,24 +90,30 @@ def ACCFn((idx, car), sim, step):
# print delta, curr_speed, front_speed, curr_speed-front_speed
if follow_dist < front_dist and curr_speed < max_speed:
# speed up
new_speed = min(curr_speed + gain * delta, max_speed)
new_speed = min(curr_speed + beta * (front_speed-curr_speed) + gain * delta, max_speed)
traci.vehicle.slowDown(vehID, new_speed, 1000) # 2.5 sec
print step, "FASTER", curr_speed, new_speed, front_speed, delta, front_dist, follow_dist
print "t=%d, FASTER, %0.1f -> %0.1f (%0.1f) | d=%0.2f = %0.2f vs %0.2f" % \
(step, curr_speed, new_speed, front_speed, delta, front_dist, follow_dist)
elif follow_dist > front_dist:
# slow down
new_speed = max(curr_speed + gain * delta, 0)
new_speed = max(curr_speed + beta * (front_speed-curr_speed) + gain * delta, 0)
traci.vehicle.slowDown(vehID, new_speed, 1000) # 2.5 sec
print step, "SLOWER", curr_speed, new_speed, front_speed, delta, front_dist, follow_dist
print "t=%d, SLOWER, %0.1f -> %0.1f (%0.1f) | d=%0.2f = %0.2f vs %0.2f" % \
(step, curr_speed, new_speed, front_speed, delta, front_dist, follow_dist)

return ACCFn

def MidpointFnBuilder(max_speed = 26.8, gain = 0.01):
def MidpointFnBuilder(max_speed = 26.8, gain = 0.1, beta = 0.5, duration = 500, bias = 1.0, ratio = 0.5):
"""
Basic adaptive cruise control (ACC) controller
:param follow_sec:
:param max_speed: 26.8 m/s = 60 mph
:param gain:
:return: ACCFn to input to a carParams
:param gain: gain for tracking following distance
:param beta: gain for tracking speed of front vehicle
:param duration: duration for transitioning to new speed (ms)
:param bias: additive speed bias term (m/s)
:param ratio: ratio of distance between front and back vehicles to track
as following distance (default is 0.5=midpoint)
:return: MidpointFn as input to a carParams
"""

def MidpointFn((idx, car), sim, step):
Expand All @@ -119,7 +126,8 @@ def MidpointFn((idx, car), sim, step):
"""
vehID = car["id"]

if step < 250:
if step < sim.simSteps/2:
# changeFasterLaneBuilder()((idx, car), sim, step)
return

try:
Expand All @@ -133,18 +141,20 @@ def MidpointFn((idx, car), sim, step):

curr_speed = car["v"]
front_speed = front_car["v"]
follow_dist = (front_dist + back_dist)/2
follow_dist = (front_dist + back_dist) * ratio
delta = front_dist - follow_dist
# print delta, curr_speed, front_speed, curr_speed-front_speed
if follow_dist < front_dist and curr_speed < max_speed:
# speed up
new_speed = min(curr_speed + gain * delta, max_speed)
traci.vehicle.slowDown(vehID, new_speed, 1000) # 2.5 sec
print step, "FASTER", curr_speed, new_speed, front_speed, delta, front_dist, follow_dist
new_speed = min(curr_speed + beta * (front_speed-curr_speed) + gain * delta + bias, max_speed)
traci.vehicle.slowDown(vehID, new_speed, duration) # 2.5 sec
print "t=%d, FASTER, %0.1f -> %0.1f (%0.1f) | d=%0.2f = %0.2f vs %0.2f" % \
(step, curr_speed, new_speed, front_speed, delta, front_dist, follow_dist)
elif follow_dist > front_dist:
# slow down
new_speed = max(curr_speed + gain * delta, 0)
traci.vehicle.slowDown(vehID, new_speed, 1000) # 2.5 sec
print step, "SLOWER", curr_speed, new_speed, front_speed, delta, front_dist, follow_dist
new_speed = max(curr_speed + beta * (front_speed-curr_speed) + gain * delta + bias, 0)
traci.vehicle.slowDown(vehID, new_speed, duration) # 2.5 sec
print "t=%d, SLOWER, %0.1f -> %0.1f (%0.1f) | d=%0.2f = %0.2f vs %0.2f" % \
(step, curr_speed, new_speed, front_speed, delta, front_dist, follow_dist)

return MidpointFn
25 changes: 13 additions & 12 deletions python/loopsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def simulate(self, opts):
tag = opts.get("tag", None)

paramsList = opts["paramsList"]
simSteps = opts.get("simSteps", 500)
self.simSteps = opts.get("simSteps", 500)

if self.label is None:
self.label = "-".join([x["name"] + "%03d" % x["count"]
Expand All @@ -206,7 +206,7 @@ def simulate(self, opts):
self._simInit("-" + self.label, [x["name"] for x in paramsList])
self._addTypes(paramsList)
self._addCars(paramsList)
self._run(simSteps)
self._run(self.simSteps)

def plot(self, show=True, save=False):
# Plot results
Expand All @@ -232,34 +232,35 @@ def plot(self, show=True, save=False):

humanParams = {
"name" : "human",
"count" : 30,
"count" : 25,
"maxSpeed" : 40,
"accel" : 4,
"decel" : 6,
"function" : changeFasterLaneBuilder(),
"accel" : 2.6,
"decel" : 4.5,
# "function" : randomChangeLaneFn,
# "function" : changeFasterLaneBuilder(),
"laneSpread" : 0,
"speedFactor" : 1.0,
"speedDev" : 0.1,
"sigma" : 0.5,
"tau" : 2,
"tau" : 4,
}

robotParams = {
"name" : "robot",
"count" : 10,
"count" : 25,
"maxSpeed" : 40,
"accel" : 4,
"decel" : 6,
"function" : MidpointFnBuilder(max_speed = 26.8, gain = 0.1),
# "function" : ACCFnBuilder(follow_sec = 3.0, max_speed = 26.8, gain = 0.1),
# "function" : MidpointFnBuilder(max_speed=40, gain=0.1, beta=0.9, duration=250, bias=1.0, ratio=0.25),
"function" : ACCFnBuilder(follow_sec=1.0, max_speed=40, gain=0.1, beta=0.9),
"laneSpread" : 0,
"tau" : 1,
"tau" : 0.5,
}

opts = {
"paramsList" : [humanParams, robotParams],
"simSteps" : 500,
"tag" : "Midpoint"
"tag" : "ACC"
}

defaults.SIM_STEP_LENGTH = 0.5
Expand Down