You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.1 KiB
88 lines
2.1 KiB
import numpy as np
|
|
|
|
|
|
def get_delta_out_limits(aEgo, aMax, aMin, jMax, jMin):
|
|
|
|
tDelta = 0.
|
|
if aEgo > aMax:
|
|
tDelta = (aMax - aEgo) / jMin
|
|
elif aEgo < aMin:
|
|
tDelta = (aMin - aEgo) / jMax
|
|
|
|
return tDelta
|
|
|
|
|
|
def speed_smoother(vEgo, aEgo, vT, aMax, aMin, jMax, jMin, ts):
|
|
|
|
dV = vT - vEgo
|
|
|
|
tDelta = get_delta_out_limits(aEgo, aMax, aMin, jMax, jMin)
|
|
|
|
if (ts <= tDelta):
|
|
if (aEgo < aMin):
|
|
vEgo += ts * aEgo + 0.5 * ts**2 * jMax
|
|
aEgo += ts * jMax
|
|
return vEgo, aEgo
|
|
elif (aEgo > aMax):
|
|
vEgo += ts * aEgo + 0.5 * ts**2 * jMin
|
|
aEgo += ts * jMin
|
|
return vEgo, aEgo
|
|
|
|
if aEgo > aMax:
|
|
dV -= 0.5 * (aMax**2 - aEgo**2) / jMin
|
|
vEgo += 0.5 * (aMax**2 - aEgo**2) / jMin
|
|
aEgo += tDelta * jMin
|
|
elif aEgo < aMin:
|
|
dV -= 0.5 * (aMin**2 - aEgo**2) / jMax
|
|
vEgo += 0.5 * (aMin**2 - aEgo**2) / jMax
|
|
aEgo += tDelta * jMax
|
|
|
|
ts -= tDelta
|
|
|
|
jLim = jMin if aEgo >= 0 else jMax
|
|
# if we reduce the accel to zero immediately, how much delta speed we generate?
|
|
dv_min_shift = - 0.5 * aEgo**2 / jLim
|
|
|
|
# flip signs so we can consider only one case
|
|
flipped = False
|
|
if dV < dv_min_shift:
|
|
flipped = True
|
|
dV *= -1
|
|
vEgo *= -1
|
|
aEgo *= -1
|
|
aMax = -aMin
|
|
jMaxcopy = -jMin
|
|
jMin = -jMax
|
|
jMax = jMaxcopy
|
|
|
|
# small addition needed to avoid numerical issues with sqrt of ~zero
|
|
aPeak = np.sqrt((0.5 * aEgo**2 / jMax + dV + 1e-9) / (0.5 / jMax - 0.5 / jMin))
|
|
|
|
if aPeak > aMax:
|
|
aPeak = aMax
|
|
t1 = (aPeak - aEgo) / jMax
|
|
vChange = dV - 0.5 * (aPeak**2 - aEgo**2) / jMax + 0.5 * aPeak**2 / jMin
|
|
if vChange < aPeak * ts:
|
|
t2 = t1 + vChange / aPeak
|
|
else:
|
|
t2 = t1 + ts
|
|
else:
|
|
t1 = (aPeak - aEgo) / jMax
|
|
t2 = t1
|
|
t3 = t2 - aPeak / jMin
|
|
|
|
dt1 = min(ts, t1)
|
|
dt2 = max(min(ts, t2) - t1, 0.)
|
|
dt3 = max(min(ts, t3) - t2, 0.)
|
|
|
|
if ts > t3:
|
|
vEgo += dV
|
|
aEgo = 0.
|
|
else:
|
|
vEgo += aEgo * dt1 + 0.5 * dt1**2 * jMax + aPeak * dt2 + aPeak * dt3 + 0.5 * dt3**2 * jMin
|
|
aEgo += jMax * dt1 + dt3 * jMin
|
|
|
|
vEgo *= -1 if flipped else 1
|
|
aEgo *= -1 if flipped else 1
|
|
|
|
return float(vEgo), float(aEgo)
|
|
|