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 )