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.
		
		
		
		
			
				
					100 lines
				
				2.4 KiB
			
		
		
			
		
	
	
					100 lines
				
				2.4 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  # recover quickly if dV is positive and aEgo is negative or viceversa
							 | 
						||
| 
								 | 
							
								  if dV > 0. and aEgo < 0.:
							 | 
						||
| 
								 | 
							
								    jMax *= 3.
							 | 
						||
| 
								 | 
							
								  elif dV < 0. and aEgo > 0.:
							 | 
						||
| 
								 | 
							
								    jMin *= 3.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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
							 | 
						||
| 
								 | 
							
								    if aPeak <= 0: # there is no solution, so stop after t1
							 | 
						||
| 
								 | 
							
								      t2 = t1 + ts + 1e-9
							 | 
						||
| 
								 | 
							
								      t3 = t2
							 | 
						||
| 
								 | 
							
								    else:
							 | 
						||
| 
								 | 
							
								      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
							 | 
						||
| 
								 | 
							
								      t3 = t2 - aPeak / jMin
							 | 
						||
| 
								 | 
							
								  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)
							 |