def make_ll_lc_event(vehicles, id2obj, meas, platooninfo, dt, addevent_list, lcevent_list): """Makes the lc_events for NewellLL model.""" for veh in vehicles: curveh = id2obj[veh] leadinfo = helper.makeleadinfo([veh],platooninfo,meas)[0] t_nstar, t_n = platooninfo[veh][:2] for count, j in enumerate(leadinfo): curlead, start, end = j # make lc_event - supports single vehicle simulation only curlen = meas[curlead][0,6] if start > t_n or (t_n > t_nstar and count == 0): # LC or merge prevlane, newlane = meas[veh][start-t_nstar-1, 7], meas[veh][start-t_nstar,7] if newlane != prevlane: # veh = 'i' vehicle in LL notation userelax = True ip1 = False x1veh, x2veh = meas[veh][start-t_nstar,4], meas[veh][start-t_nstar,5] if x2veh == 0: # handle edge case # print('warning - follower missing for '+str(veh)+' change at time '+str(start)) userelax = False x1, x2 = None, None else: x1t_nstar, x2t_nstar = platooninfo[x1veh][0], platooninfo[x2veh][0] x1, x2 = meas[x1veh][start-x1t_nstar,2], meas[x2veh][start-x2t_nstar,2] else: temp = meas[veh][start-t_nstar,4] tempt_nstar = platooninfo[temp][0] if meas[temp][start-1-tempt_nstar,7] != newlane: # veh = 'i+1' in LL notation userelax = True ip1 = True x1veh, x2veh = meas[veh][start-1-t_nstar,4], meas[veh][start-t_nstar,4] x1t_nstar, x2t_nstar = platooninfo[x1veh][0], platooninfo[x2veh][0] x1, x2 = meas[x1veh][start-x1t_nstar,2], meas[x2veh][start-x2t_nstar,2] else: userelax = False x1, x2, ip1 = None, None, None else: userelax = False # no relax x1, x2, ip1 = None, None, None leadstate = (x1, x2, ip1) curevent = (start, 'lc', curveh, curlead, curlen, userelax, leadstate) if count == 0: curevent = (start, 'add', curveh, curevent) addevent_list.append(curevent) else: lcevent_list.append(curevent) return addevent_list, lcevent_list
def make_lc_event(vehicles, id2obj, meas, platooninfo, dt, addevent_list, lcevent_list): for veh in vehicles: curveh = id2obj[veh] leadinfo = helper.makeleadinfo([veh],platooninfo,meas)[0] for count, j in enumerate(leadinfo): curlead, start, end = j leadt_nstar = platooninfo[curlead][0] # even though the change occurs at time start, we want to calculate the relaxation using # the differences in headway at time start - 1. This leads to 4 combinations, first, whether # the new leader is simulated or not, and second, whether the new lead is available at start-1 if curlead in vehicles: # curlead is simulated (in the same calibration object) if start-1 < leadt_nstar: # handle edge case where t_nstar = start leadstate = (meas[curlead][0,2]-meas[curlead][0,3]*dt, meas[curlead][0,3]) else: leadstate = (None,) curlead, curlen = id2obj[curlead], None else: curlen = meas[curlead][0,6] # curlead is already simulated, stored in curveh.leadstatemem if start-1 < leadt_nstar: # handle edge case where t_nstar = start leadstate = (meas[curlead][0,2]-meas[curlead][0,3]*dt, meas[curlead][0,3]) else: leadstate = (meas[curlead][start-1-leadt_nstar,2], meas[curlead][start-1-leadt_nstar,3]) if count == 0: # add event adds vehicle to simulation t_nstar, t_n = platooninfo[veh][0:2] if t_n > t_nstar: # apply merger rule userelax = True else: userelax = False # make the add event curevent = (start, 'lc', curveh, curlead, curlen, userelax, leadstate) curevent = (start, 'add', curveh, curevent) addevent_list.append(curevent) else: # lc event changes leader, applies relax curevent = (start, 'lc', curveh, curlead, curlen, True, leadstate) lcevent_list.append(curevent) return addevent_list, lcevent_list
def make_dataset(meas, platooninfo, veh_list, rp=15, dt=.1): """Makes dataset from meas and platooninfo. Args: meas: see havsim.helper.makeplatooninfo platooninfo: see havsim.helper.makeplatooninfo veh_list: list of vehicle IDs to put into dataset dt: timestep Returns: ds: (reads as dataset) dictionary of vehicles, values are a dictionary with keys 'IC' - (initial conditions) list of starting position/speed for vehicle 'times' - list of two int times. First is the first time with an observed leader. Second is the last time with an observed leader +1. The number of times we call the model is equal to times[1] - times[0], which is the length of the lead measurements. 'posmem' - (1d,) numpy array of observed positions for vehicle, 0 index corresponds to times[0]. Typically this has a longer length than the lead posmem/speedmem. 'speedmem' - (1d,) numpy array of observed speeds for vehicle 'lead posmem' - (1d,) numpy array of positions for leaders, 0 index corresponds to times[0]. length is subtracted from the lead position. 'lead speedmem' - (1d,) numpy array of speeds for leaders. 'lc times' - (1d,) numpy array with relaxation amounts at each time normalization amounts: tuple of maxheadway: max headway observed in training set maxspeed: max velocity observed in training set minacc: minimum acceleration observed in training set maxacc: maximum acceleration observed in training set """ # get normalization for inputs, and get input data ds = {} maxheadway, maxspeed = 0, 0 minacc, maxacc = 1e4, -1e4 for veh in veh_list: # get data t0, t1, t2, t3 = platooninfo[veh][:4] leadpos, leadspeed = helper.get_lead_data(veh, meas, platooninfo, dt=dt) # relaxation added relax = helper.get_fixed_relaxation(veh, meas, platooninfo, rp, dt=dt) leadpos = leadpos + relax # new input indicates lane change leadinfo = helper.makeleadinfo([veh], platooninfo, meas) rinfo = helper.makerinfo([veh], platooninfo, meas, leadinfo, mergertype=None) lc_input = np.zeros((t2 + 1 - t1, )) for lc in rinfo[0]: time, relax_amount = lc lc_input[time - t1] = relax_amount vehpos = meas[veh][t1 - t0:, 2] vehspd = meas[veh][t1 - t0:, 3] IC = [meas[veh][t1 - t0, 2], meas[veh][t1 - t0, 3]] headway = leadpos - vehpos[:t2 + 1 - t1] # normalization + add item to datset vehacc = [(vehpos[i + 2] - 2 * vehpos[i + 1] + vehpos[i]) / (dt**2) for i in range(len(vehpos) - 2)] minacc, maxacc = min(minacc, min(vehacc)), max(maxacc, max(vehacc)) maxheadway = max(max(headway), maxheadway) maxspeed = max(max(leadspeed), maxspeed) ds[veh] = { 'IC': IC, 'times': [t1, min(int(t2 + 1), t3)], 'posmem': vehpos, 'speedmem': vehspd, 'lead posmem': leadpos, 'lead speedmem': leadspeed, 'lc times': lc_input } return ds, (maxheadway, maxspeed, minacc, maxacc)
def make_calibration(vehicles, meas, platooninfo, dt, vehicle_class = None, calibration_class = None, event_maker = None, lc_event_fun = None): """Sets up a Calibration object. Extracts the relevant quantities (e.g. LeadVehicle, initial conditions, loss) from the data and creates the add/lc event. Args: vehicles: list/set of vehicles to add to the Calibration meas: from havsim.calibration.algs.makeplatoonlist platooninfo: from havsim.calibration.algs.makeplatoonlist dt: timestep vehicle_class: subclassed Vehicle to use - if None defaults to CalibrationVehicle calibration_class: subclassed Calibration to use - if None defaults to Calibration event_maker: specify a function to create custom (lc) events lc_event_fun: specify function which handles custom lc events """ # TODO - to make this consistent with deep_learning, y should be over the times t_n+1 - min(T_nm1+1, T_n) # and also this should use the helper function get_lead_data if vehicle_class is None: vehicle_class = CalibrationVehicle if calibration_class is None: calibration_class = Calibration if event_maker is None: event_maker = make_lc_event if lc_event_fun is None: lc_event_fun = lc_event # initialize vehicle_list = [] addevent_list = [] lcevent_list = [] id2obj = {} if type(vehicles) == list: vehicles = set(vehicles) for veh in vehicles: # make lead memory - a list of position/speed tuples for any leaders which are not simulated leads = set(platooninfo[veh][4]) needleads = leads.difference(vehicles) if len(needleads) > 0: leadstatemem = [] leadinittime = None # initial time lead is used leadinfo = helper.makeleadinfo([veh],platooninfo,meas) for j in leadinfo[0]: curlead, start, end = j if curlead in needleads: if not leadinittime: leadinittime = start leadt_n = platooninfo[curlead][0] poslist = list(meas[curlead][start-leadt_n:end-leadt_n+1,2]) spdlist = list(meas[curlead][start-leadt_n:end-leadt_n+1,3]) leadstatemem.extend(zip(poslist,spdlist)) elif leadinittime is not None: temp = [0]*(end-start+1) leadstatemem.extend(temp) else: leadstatemem, leadinittime = None, None # get initial values, y for veh t_nstar, inittime, endtime = platooninfo[veh][0:3] initlead, initpos, initspd, length = meas[veh][inittime-t_nstar,[4,2,3,6]] y = meas[veh][inittime-t_nstar:endtime+1-t_nstar,2] # create vehicle object newveh = vehicle_class(veh, y, initpos, initspd, inittime, leadstatemem, leadinittime, length=length) vehicle_list.append(newveh) id2obj[veh] = newveh # create events addevent_list, lcevent_list = event_maker(vehicles, id2obj, meas, platooninfo, dt, addevent_list, lcevent_list) addevent_list.sort(key = lambda x: x[0], reverse = True) # sort events in time lcevent_list.sort(key = lambda x: x[0], reverse = True) # make calibration object return calibration_class(vehicle_list, addevent_list, lcevent_list, dt, endtime=endtime, lc_event_fun = lc_event_fun)
def analyze_res_NN(res_list, meas, platooninfo, dt, mergeind = math.inf, times = 100, realistic = 1.1): out = {'mse':None, 'mse near LC':None, 'mse for merges':None, 'mse for many LC':None, 'realistic acc':None, 'short lc':None} mse = [] nearlc = [] merge = [] manylc = [] real = [] out2 = [] shortlc = [] for count, item in enumerate(res_list.items()): veh, res = item leadinfo = helper.makeleadinfo([veh], platooninfo, meas) lctimes = [cur[1] for cur in leadinfo[0]] rinfo = helper.makerinfo([veh], platooninfo, meas, leadinfo) if len(lctimes) > len(rinfo[0]): # this handles an edge case rinfo[0].insert(0, [None, -1]) t_nstar, t_n, T_nm1 = platooninfo[veh][:3] if lctimes[0] == t_nstar: lctimes = lctimes[1:] curmeas = meas[veh][t_n-t_nstar:T_nm1+1-t_nstar,2] cursim = np.array(res['posmem']) curmse = np.mean(np.square(curmeas-cursim))/(3.28084**2) mse.append(curmse) if len(leadinfo[0]) > 3: manylc.append(curmse) # many lc if count >= mergeind: merge.append(curmse) for count, curtime in enumerate(lctimes): curmse = np.square(cursim[curtime-t_n:curtime-t_n+times] - curmeas[curtime-t_n:curtime-t_n+times]) curmse = np.sum(curmse)/len(curmse)/(3.28084**2) nearlc.append(curmse) # near lc # try: curg = rinfo[0][count][1] if curg > 0: shortlc.append(curmse) # except: # print('hello') simacc = [(cursim[i+2] - 2*cursim[i+1] + cursim[i])/(dt**2) for i in range(len(cursim)-2)] measacc = [(curmeas[i+2] - 2*curmeas[i+1] + curmeas[i])/(dt**2) for i in range(len(curmeas)-2)] upper = max(realistic*max(measacc), 4*3.28) lower = min(-6*3.28, realistic*min(measacc)) temp1, temp2 = max(simacc), min(simacc) if temp1 < upper and temp2 > lower: real.append(1) else: real.append(0) out2.append(((upper, lower), (temp1, temp2))) out['mse'] = (np.mean(mse), np.median(mse), np.std(mse)) out['mse near LC'] = (np.mean(nearlc), np.median(nearlc), np.std(nearlc)) out['mse for merges'] = (np.mean(merge), np.median(merge), np.std(merge)) out['mse for many LC'] = (np.mean(manylc), np.median(manylc), np.std(manylc)) out['realistic acc'] = (np.mean(real)) out['short lc'] = (np.mean(shortlc), np.median(shortlc), np.std(shortlc)) print(out) return out, out2