Beispiel #1
0
 def __init__(self, motion_model, meas_model, num_iter, line_search_method):
     super().__init__()
     self._motion_model = motion_model
     self._meas_model = meas_model
     self.num_iter = num_iter
     self._ls_method = line_search_method
     self._cache = ExtCache(self._motion_model, self._meas_model)
Beispiel #2
0
class Iekf(Filter):
    """Iterated Extended Kalman filter (IEKF)"""
    def __init__(self, motion_model, meas_model):
        self._motion_model = motion_model
        self._meas_model = meas_model
        self._current_means = None
        self._cache = ExtCache(self._motion_model, self._meas_model)

    def _update_estimates(self, means, _covs, cache=None):
        self._current_means = means.copy()
        if cache is None:
            self._cache.update(means, None)
        else:
            self._cache = cache

    def _motion_lin(self, _mean, _cov, time_step):
        return self._cache.motion_lin[time_step - 1]

    def _meas_lin(self, _mean, _cov, time_step):
        return self._cache.meas_lin[time_step - 1]

    def _proc_noise(self, time_step):
        return self._motion_model.proc_noise(time_step)

    def _meas_noise(self, time_step):
        return self._meas_model.meas_noise(time_step)
Beispiel #3
0
class Ieks(IteratedSmoother):
    """Iterated Extended Kalman Smoother (IEKS)"""
    def __init__(self, motion_model, meas_model, num_iter):
        super().__init__()
        self._motion_model = motion_model
        self._meas_model = meas_model
        self.num_iter = num_iter
        self._cache = ExtCache(self._motion_model, self._meas_model)

    def _motion_lin(self, _mean, _cov, time_step):
        return self._cache.motion_lin[time_step - 1]

    def _first_iter(self, measurements, m_1_0, P_1_0, cost_fn):
        smoother = Eks(self._motion_model, self._meas_model)
        return smoother.filter_and_smooth(measurements, m_1_0, P_1_0, cost_fn)

    def _filter_seq(self, measurements, m_1_0, P_1_0):
        iekf = Iekf(self._motion_model, self._meas_model)
        iekf._update_estimates(self._current_means, self._current_covs,
                               self._cache)
        return iekf.filter_seq(measurements, m_1_0, P_1_0)

    def _update_estimates(self, means, covs):
        """The 'previous estimates' which are used in the current iteration are stored in the smoother instance.
        They should only be modified through this method.
        """
        super()._update_estimates(means, covs)
        self._cache.update(means, None)

    def _is_initialised(self):
        return self._cache.is_initialized() and self._current_means is not None
Beispiel #4
0
 def __init__(self, motion_model, meas_model, num_iter,
              cost_improv_iter_lim, lambda_, nu):
     super().__init__()
     self._motion_model = motion_model
     self._meas_model = meas_model
     self.num_iter = num_iter
     self._cost_improv_iter_lim = cost_improv_iter_lim
     self._lambda = lambda_
     self._nu = nu
     self._cache = ExtCache(self._motion_model, self._meas_model)
Beispiel #5
0
class LmIeks(IteratedSmoother):
    """Levenberg-Marquardt Iterated Extended Kalman Smoother (LM-IEKS)"""
    def __init__(self, motion_model, meas_model, num_iter,
                 cost_improv_iter_lim, lambda_, nu):
        super().__init__()
        self._motion_model = motion_model
        self._meas_model = meas_model
        self.num_iter = num_iter
        self._cost_improv_iter_lim = cost_improv_iter_lim
        self._lambda = lambda_
        self._nu = nu
        self._cache = ExtCache(self._motion_model, self._meas_model)

    def _motion_lin(self, _mean, _cov, time_step):
        return self._cache.motion_lin[time_step - 1]

    # TODO: This should also have inner LM check
    def _first_iter(self, measurements, m_1_0, P_1_0, cost_fn):
        smoother = Eks(self._motion_model, self._meas_model)
        return smoother.filter_and_smooth(measurements, m_1_0, P_1_0, cost_fn)

    def filter_and_smooth_with_init_traj(self, measurements, m_1_0, P_1_0,
                                         init_traj, start_iter, cost_fn):
        """Filter and smoothing given an initial trajectory"""
        current_ms, current_Ps = init_traj
        self._update_estimates(current_ms, current_Ps)
        prev_cost = cost_fn(current_ms)
        cost_iter = []
        for iter_ in range(start_iter, self.num_iter + 1):
            self._log.debug(f"Iter: {iter_}")
            inner_iter = 0
            has_improved = False
            while has_improved is False and inner_iter < self._cost_improv_iter_lim:
                # Note: here we want to run the base `Smoother` class method.
                # I.e. we're getting the grandparent's method.
                mf, Pf, current_ms, current_Ps, cost = super(
                    IteratedSmoother,
                    self).filter_and_smooth(measurements, m_1_0, P_1_0,
                                            cost_fn)
                self._log.debug(f"Cost: {cost}, lambda: {self._lambda}")
                if not self._lambda > 0.0:
                    self._log.info("lambda=0, skipping cost check")
                    has_improved = True
                elif cost < prev_cost:
                    self._lambda /= self._nu
                    has_improved = True
                else:
                    self._lambda *= self._nu
                inner_iter += 1
            if inner_iter == self._cost_improv_iter_lim - 1:
                self._log.warning(
                    f"No cost improvement for {self._cost_improv_iter_lim} iterations"
                )
            self._update_estimates(current_ms, current_Ps)
            prev_cost = cost
            cost_iter.append(cost)
            # _cost = cost(current_ms, measurements, m_1_0, P_1_0, self._motion_model, self._meas_model)
        return mf, Pf, current_ms, current_Ps, np.array(cost_iter)

    def _filter_seq(self, measurements, m_1_0, P_1_0):
        lm_iekf = _LmIekf(self._motion_model, self._meas_model, self._lambda)
        lm_iekf._update_estimates(self._current_means, self._current_covs,
                                  self._cache)
        return lm_iekf.filter_seq(measurements, m_1_0, P_1_0)

    def _update_estimates(self, means, covs):
        """The 'previous estimates' which are used in the current iteration are stored in the smoother instance.
        They should only be modified through this method.
        """
        super()._update_estimates(means, covs)
        self._cache.update(means, None)

    def _is_initialised(self):
        return self._cache.is_initialized() and self._current_means is not None
Beispiel #6
0
class LsIeks(IteratedSmoother):
    """Line-search Iterated Extended Kalman Smoother (LS-IEKS)"""
    def __init__(self, motion_model, meas_model, num_iter, line_search_method):
        super().__init__()
        self._motion_model = motion_model
        self._meas_model = meas_model
        self.num_iter = num_iter
        self._ls_method = line_search_method
        self._cache = ExtCache(self._motion_model, self._meas_model)

    def _motion_lin(self, _mean, _cov, time_step):
        return self._cache.motion_lin[time_step - 1]

    # TODO: This should also have inner LS check
    def _first_iter(self, measurements, m_1_0, P_1_0, cost_fn):
        smoother = Eks(self._motion_model, self._meas_model)
        return smoother.filter_and_smooth(measurements, m_1_0, P_1_0, cost_fn)

    def filter_and_smooth_with_init_traj(self, measurements, m_1_0, P_1_0,
                                         init_traj, start_iter, cost_fn):
        """Filter and smoothing given an initial trajectory"""
        current_ms, current_Ps = init_traj
        # If self.num_iter is too low to enter the iter loop
        mf, Pf = init_traj
        self._update_estimates(current_ms, current_Ps)
        prev_cost = cost_fn(current_ms)
        cost_iter = [prev_cost]
        self._log.debug(f"Initial cost: {prev_cost}")
        for iter_ in range(start_iter, self.num_iter + 1):
            self._log.debug(f"Iter: {iter_}")
            # Note: here we want to run the base `Smoother` class method.
            # I.e. we're getting the grandparent's method.
            current_mf, current_Pf, current_ms, current_Ps, cost = super(
                IteratedSmoother,
                self).filter_and_smooth(measurements, m_1_0, P_1_0, cost_fn)
            ls_ms, alpha, ls_cost = self._ls_method.search_next(
                self._current_means, current_ms)
            if ls_cost > cost:
                self._log.warning(
                    f"Line search did not decrease, defaulting to plain IEKS.")
                self._update_estimates(current_ms, current_Ps)
                prev_cost = cost
                mf = current_mf
                Pf = current_Pf
            else:
                self._update_estimates(ls_ms, current_Ps)
                prev_cost = ls_cost
                mf = mf + alpha * (current_mf - self._current_means)
            cost_iter.append(prev_cost)
            # _cost = cost(current_ms, measurements, m_1_0, P_1_0, self._motion_model, self._meas_model)
        return mf, Pf, current_ms, current_Ps, np.array(cost_iter)

    def _filter_seq(self, measurements, m_1_0, P_1_0):
        iekf = Iekf(self._motion_model, self._meas_model)
        iekf._update_estimates(self._current_means, self._current_covs,
                               self._cache)
        return iekf.filter_seq(measurements, m_1_0, P_1_0)

    def _update_estimates(self, means, covs):
        """The 'previous estimates' which are used in the current iteration are stored in the smoother instance.
        They should only be modified through this method.
        """
        super()._update_estimates(means, covs)
        self._cache.update(means, None)

    def _is_initialised(self):
        return self._cache.is_initialized() and self._current_means is not None
Beispiel #7
0
 def __init__(self, motion_model, meas_model):
     self._motion_model = motion_model
     self._meas_model = meas_model
     self._current_means = None
     self._cache = ExtCache(self._motion_model, self._meas_model)
Beispiel #8
0
 def __init__(self, motion_model, meas_model, num_iter):
     super().__init__()
     self._motion_model = motion_model
     self._meas_model = meas_model
     self.num_iter = num_iter
     self._cache = ExtCache(self._motion_model, self._meas_model)