import math
import numpy as np
from common . numpy_fast import interp
import selfdrive . messaging as messaging
X_PATH = np . arange ( 0.0 , 50.0 )
def model_polyfit ( points ) :
return np . polyfit ( X_PATH , map ( float , points ) , 3 )
# lane width http://safety.fhwa.dot.gov/geometric/pubs/mitigationstrategies/chapter3/3_lanewidth.cfm
_LANE_WIDTH_V = [ 3. , 3.8 ]
# break points of speed
_LANE_WIDTH_BP = [ 0. , 31. ]
def calc_desired_path ( l_poly , r_poly , p_poly , l_prob , r_prob , p_prob , speed ) :
#*** this function computes the poly for the center of the lane, averaging left and right polys
lane_width = interp ( speed , _LANE_WIDTH_BP , _LANE_WIDTH_V )
# lanes in US are ~3.6m wide
half_lane_poly = np . array ( [ 0. , 0. , 0. , lane_width / 2. ] )
if l_prob + r_prob > 0.01 :
c_poly = ( ( l_poly - half_lane_poly ) * l_prob +
( r_poly + half_lane_poly ) * r_prob ) / ( l_prob + r_prob )
c_prob = math . sqrt ( ( l_prob * * 2 + r_prob * * 2 ) / 2. )
else :
c_poly = np . zeros ( 4 )
c_prob = 0.
p_weight = 1. # predicted path weight relatively to the center of the lane
d_poly = list ( ( c_poly * c_prob + p_poly * p_prob * p_weight ) / ( c_prob + p_prob * p_weight ) )
return d_poly , c_poly , c_prob
class PathPlanner ( object ) :
def __init__ ( self , model ) :
self . model = model
self . dead = True
self . d_poly = [ 0. , 0. , 0. , 0. ]
self . last_model = 0.
self . logMonoTime = 0
self . lead_dist , self . lead_prob , self . lead_var = 0 , 0 , 1
def update ( self , cur_time , v_ego ) :
md = messaging . recv_sock ( self . model )
if md is not None :
self . logMonoTime = md . logMonoTime
p_poly = model_polyfit ( md . model . path . points ) # predicted path
p_prob = 1. # model does not tell this probability yet, so set to 1 for now
l_poly = model_polyfit ( md . model . leftLane . points ) # left line
l_prob = md . model . leftLane . prob # left line prob
r_poly = model_polyfit ( md . model . rightLane . points ) # right line
r_prob = md . model . rightLane . prob # right line prob
self . lead_dist = md . model . lead . dist
self . lead_prob = md . model . lead . prob
self . lead_var = md . model . lead . std * * 2
#*** compute target path ***
self . d_poly , _ , _ = calc_desired_path ( l_poly , r_poly , p_poly , l_prob , r_prob , p_prob , v_ego )
self . last_model = cur_time
self . dead = False
elif cur_time - self . last_model > 0.5 :
self . dead = True