#!/usr/bin/env python3 import unittest import numpy as np from cereal import log import cereal.messaging as messaging from selfdrive.config import Conversions as CV from selfdrive.controls.lib.lead_mpc_lib.lead_mpc import RW, LeadMpc class FakePubMaster(): def send(self, s, data): assert data def run_following_distance_simulation(v_lead, t_end=200.0): dt = 0.2 t = 0. x_lead = 200.0 x_ego = 0.0 v_ego = v_lead a_ego = 0.0 mpc = LeadMpc(0) first = True while t < t_end: # Setup CarState CS = messaging.new_message('carState') CS.carState.vEgo = float(v_ego) CS.carState.aEgo = float(a_ego) # Setup model packet radarstate = messaging.new_message('radarState') lead = log.RadarState.LeadData.new_message() lead.modelProb = .75 lead.dRel = x_lead - x_ego lead.vLead = v_lead lead.aLeadK = 0.0 lead.status = True radarstate.radarState.leadOne = lead # Run MPC mpc.set_cur_state(v_ego, a_ego) if first: # Make sure MPC is converged on first timestep for _ in range(20): mpc.update(CS.carState, radarstate.radarState, 0) mpc.update(CS.carState, radarstate.radarState, 0) # Choose slowest of two solutions v_ego, a_ego = float(mpc.v_solution[5]), float(mpc.a_solution[5]) # Update state x_lead += v_lead * dt x_ego += v_ego * dt t += dt first = False return x_lead - x_ego class TestFollowingDistance(unittest.TestCase): def test_following_distanc(self): for speed_mph in np.linspace(10, 100, num=10): v_lead = float(speed_mph * CV.MPH_TO_MS) simulation_steady_state = run_following_distance_simulation(v_lead) correct_steady_state = RW(v_lead, v_lead) + 4.0 self.assertAlmostEqual(simulation_steady_state, correct_steady_state, delta=.2) if __name__ == "__main__": unittest.main()