def main(track_opts: dict, solver_opts: dict, driver_opts: dict, sa_opts: dict, debug_opts: dict, car_config: dict, track_pars: dict, car_name: str) -> laptimesim.src.lap.Lap: # ------------------------------------------------------------------------------------------------------------------ # CHECK PYTHON DEPENDENCIES ---------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------------ # get repo path repo_path = os.path.dirname(os.path.abspath(__file__)) # read dependencies from requirements.txt requirements_path = os.path.join(repo_path, 'requirements.txt') dependencies = [] with open(requirements_path, 'r') as fh: line = fh.readline() while line: dependencies.append(line.rstrip()) line = fh.readline() # check dependencies pkg_resources.require(dependencies) # ------------------------------------------------------------------------------------------------------------------ # INITIALIZATION --------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------------ output_path = os.path.join(repo_path, "laptimesim", "output") output_path_velprofile = os.path.join(output_path, "velprofile") os.makedirs(output_path_velprofile, exist_ok=True) output_path_testobjects = os.path.join(output_path, "testobjects") os.makedirs(output_path_testobjects, exist_ok=True) if debug_opts["use_plot_comparison_tph"]: output_path_veh_dyn_info = os.path.join(output_path, "veh_dyn_info") os.makedirs(output_path_veh_dyn_info, exist_ok=True) date = datetime.datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p") resultsfile = os.path.join(repo_path, "laptimesim", "output", "results-{}.csv".format(date)) datastore = DataStore(results_file_name=resultsfile, track_pars=track_pars, car_name=car_name) datastore.parse_car_config(car_config) datastore.generate_unique_sa_combinations() # generate car parameters used for debug lap plots. This set of # car parameters is used when the simulation does not do sensitivity analysis first_iter_veh_pars = datastore.single_iteration_data[0].race_car_model.get_car_parameters_for_laptimesim() # ------------------------------------------------------------------------------------------------------------------ # CREATE TRACK INSTANCE -------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------------ tmp_track_file_path = os.path.join(repo_path, "laptimesim", "input", "tracks", "racelines", track_opts["trackname"]) trackfilepath = os.path.join(tmp_track_file_path + ".csv") vel_lim_glob = np.inf # create instance track = laptimesim.src.track.Track(track_opts=track_opts, track_pars=track_pars, trackfilepath=trackfilepath, vel_lim_glob=vel_lim_glob, yellow_s1=driver_opts["yellow_s1"], yellow_s2=driver_opts["yellow_s2"], yellow_s3=driver_opts["yellow_s3"]) # debug plot if debug_opts["use_debug_plots"]: # check if track map exists and set path accordingly mapfolderpath = os.path.join(repo_path, "laptimesim", "input", "tracks", "maps") mapfilepath = "" for mapfile in os.listdir(mapfolderpath): if track_opts["trackname"] in mapfile: mapfilepath = os.path.join(mapfolderpath, mapfile) break # plot trackmap track.plot_trackmap(mapfilepath=mapfilepath) # plot curvature track.plot_curvature() if track_opts["use_elevation"]: track.plot_elevation() track.plot_elevation_3d() # recalculate raceline based on curvature track.check_track() # ------------------------------------------------------------------------------------------------------------------ # CREATE CAR INSTANCE ---------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------------ car = laptimesim.src.car_electric.CarElectric(pars=first_iter_veh_pars) # debug plot if debug_opts["use_debug_plots"]: # plot tire force potential characteristics car.plot_tire_characteristics() # ------------------------------------------------------------------------------------------------------------------ # CREATE DRIVER INSTANCE ------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------------ # create instance driver = laptimesim.src.driver.Driver(carobj=car, pars_driver=driver_opts, trackobj=track, stepsize=track.stepsize) # ------------------------------------------------------------------------------------------------------------------ # CREATE LAP INSTANCE ---------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------------------------------------ lap = laptimesim.src.lap.Lap(driverobj=driver, trackobj=track, pars_solver=solver_opts, debug_opts=debug_opts) # ------------------------------------------------------------------------------------------------------------------ # CALL SOLVER ------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------ # save start time t_start = time.perf_counter() # call simulation if not sa_opts["use_sa"]: # normal simulation -------------------------------------------------------------------------------------------- lap.simulate_lap() # debug plot if debug_opts["use_debug_plots"]: # plot torques lap.plot_torques() # plot lateral acceleration profile lap.plot_lat_acc() # plot tire load profile lap.plot_tire_loads() # plot aero forces lap.plot_aero_forces() #plot power lap.plot_power() lap.plot_throttle() # plot engine speed and gear selection lap.plot_enginespeed_gears() if not sa_opts["use_sa"]: if debug_opts["use_plot"]: lap.plot_overview() lap.plot_revs_gears() else: # sensitivity analysis ----------------------------------------------------------------------------------------- for i, single_simulation_data in datastore.single_iteration_data.items(): print("SA: Starting solver run (%i)" % (i + 1)) race_car_object = single_simulation_data.race_car_model veh_pars = race_car_object.get_car_parameters_for_laptimesim() car = laptimesim.src.car_electric.CarElectric(pars=veh_pars) # change properties of vehicle in the lap simulation lap.driverobj.carobj = car # simulate lap and save lap time # I made sure there was no other initialization needed, # we know this violates the object oriented world. # we know this isn't the best practiced but we # double checked that this was ok and there # wasn't any other initialization required or dependencies lap.simulate_lap() total_pit_time = race_car_object.general_parameters.pit_time + track_pars[PIT_DRIVE_THROUGH_PENALTY_TIME] race_sim = RaceSim(pit_time=total_pit_time, gwc_times=datastore.track_pars[GWC_TIMES_TAG], lap_time=lap.t_cl[-1], energy_per_lap=lap.e_cons_cl[-1], battery_capacity=race_car_object.battery_parameters.size) race_sim.calculate() total_pits = 0 energy_remaining = 0 for day in race_sim.race_days: total_pits += day.number_of_pits energy_remaining += day.energy_remaining*100 # for percentage conversion is_winning_car_configuration = race_sim.total_laps > track_pars["winning_laps"] datastore.set_single_iteration_results(iteration=i, lap_time=lap.t_cl[-1], total_laps=race_sim.total_laps, lap_energy=lap.e_cons_cl[-1]/1000, # 1000 factor fo J -> kJ total_pits=total_pits, energy_remaining=energy_remaining, is_winning_car_configuration=is_winning_car_configuration) lap.reset_lap() print("Solver run {}. Winning car?: {}, total laps: {}".format(i, is_winning_car_configuration, race_sim.total_laps )) best_results, multiple_optimum_results = datastore.get_best_result() print("Best result was iteration: {}".format(best_results[ITER_TAG])) print("{}: {}".format(WINNING_ELECTRIC_CAR_TAG, best_results[WINNING_ELECTRIC_CAR_TAG])) print("{}: {}".format(TOTAL_LAPS_TAG, best_results[TOTAL_LAPS_TAG])) print("{}: {}".format(WINNING_GAS_CAR_LAPS, track_pars[WINNING_GAS_CAR_LAPS])) print("{}: {}".format(TOTAL_PITS_TAG, best_results[TOTAL_PITS_TAG])) print("{}: {}".format(LAP_ENERGY_TAG, best_results[LAP_ENERGY_TAG])) print("{}: {}".format(ENERGY_REMAINING_TAG, best_results[ENERGY_REMAINING_TAG])) print("{}: {}".format(BATTERY_SIZE_TAG, best_results[BATTERY_SIZE_TAG])) print("Are there multiple optimum results?: {}".format(multiple_optimum_results)) print("total simulation time: {}" .format(time.perf_counter() - t_start))