Пример #1
0
    def __init__(self, car_model, estimator_type):
        '''
        Allowable combinations of car_model and estimator_type are
        ("simple", "fcn")
        ("simple", "analytical")
        ("complex", "fcn")

        No analytical solution for complex internal model.
        '''
        if (estimator_type not in {"analytical", "fcn"}):
            raise Exception(
                f"Illegal estimator_type, f{estimator_type}, must be 'analytical' or 'fcn'"
            )

        if (car_model not in {"simple", "complex"}):
            raise Exception(
                f"Illegal estimator_type, f{estimator_type}, must be 'simple' or 'complex'"
            )

        if (estimator_type == 'analytical' and car_model == 'complex'):
            raise Exception("No analytical estimator for complex car model")

        self.estimator_type = estimator_type
        '''
        If using a fcn load parameters from Brakind Distance directory
        two inputs (intitial velocity, stopping distance), output must be between 0 and 1
        '''
        if (estimator_type == "fcn"):
            self.fcn = nn.fcn(model_name=os.path.join(self.bd_fp(),
                                                      f"{car_model}_bd"),
                              num_inputs=2,
                              out_range=(0, 1))
        '''
        If using analytical approach get coefficients from controller
        model (pedal weights, friction constant, and rolling bias)
        '''
        if (estimator_type == "analytical"):
            ci = controller_model.Car_Interface()
            self.brake_weight = ci.brake_weight
            self.rolling_bias = ci.rolling_bias
            self.friction_constant = ci.friction_constant
Пример #2
0
    def __init__(self, mode, car_model="simple"):

        self.mode = mode
        self.car_model = car_model
        '''
        Initialize the interface that will be used to manage motion dynamics.
        '''
        self.interface = controller.Car_Interface(car_model)
        '''
        If we are testing system ID then we will initialize an instance of the
        controller model, which we will interact with side by side along with
        the actual interface.
        '''
        if (self.mode == "sysID_test"):
            import car_iface.controller_model as controller_model
            self.interface_model = controller_model.Car_Interface(car_model)
        '''
        pedal_type intitialized to None
        peda_type can later be "accelerate", "brake", or "release"

        amount is relevant for both "accelerate" and "brake" and
        represents the magnitude of pedal depression.

        TIME_UNIT is a constant and represents how often we update
        the car's state.
        '''
        self.pedal_type = None
        self.amount = 0.0
        self.TIME_UNIT = self.interface.dt
        '''
        Build up is used to allow for increasing pedal depression
        the longer you hold a control.  That is when you press as
        you hold "accelerate" or "brake" the pedal depression will
        increase from 0 to 1 over time.

        When we are doing SystemID we will not follow the build up
        principle and apply random depression quantities, to make sure
        we are covering all possible scenarios.
        '''
        if (not (self.mode == "sysID_data" or self.mode == "sysID_test")):
            self.build_up = 0
            self.bu_to_amt = lambda: 1 - 1 / ((self.build_up / 20) + 1)
        '''
        If we are collecting data for System ID we intialize a file path for
        where we will save the data points (including reference to the internal
        car model).
        If there is a preexisting data points file we will load it
        and add to it, as opposed to starting from scratch.
        We will also keep track how long ago we last saved the collected data.
        '''
        if (self.mode == "sysID_data"):
            import settings

            cur_dir = os.path.dirname(__file__)
            internal_path = os.path.join(cur_dir, '../../internal_only/sysid/')
            if settings.use_internal_if_available and os.path.exists(
                    internal_path):
                self.data_points_file_path = internal_path
            else:
                if (car_model == "simple"):
                    self.data_points_file_path = os.path.join(
                        cur_dir, '../hw/sysid/')
                elif (car_model == "complex"):
                    self.data_points_file_path = os.path.join(
                        cur_dir, '../demos/week3/')
            self.data_points_file_path = os.path.join(
                self.data_points_file_path, f'{car_model}_data_points.json')

            if (os.path.exists(self.data_points_file_path)):
                self.data_points = json.load(
                    open(self.data_points_file_path, "r"))
            else:
                self.data_points = []

            self.saved_data = 0
        '''
        If we are testing System ID we will keep track of a rolling average of
        the discrepancy between the actual controller and the controller model.

        The average will be taken over the last ERROR_WINDOW times.  The maximum
        average error will be tracked as well.
        '''
        if (self.mode == "sysID_test"):
            self.ERROR_WINDOW = 100
            self.errors = []
            self.max_mean_error = None