Esempio n. 1
0
    def predict(self, Q=None, u=None):
        """ TODO: write docstring """

        x_ = self.state['expected']
        P_ = self.state['err_cov']

        x = np.atleast_2d(feval(self.process['f'], x_, u))
        self.state['expected'] = x.copy()

        F_ = np.atleast_2d(feval(self.process['Jacobian_x'], x_, u))

        if self.process['Jacobian_Q'] is None:
            w_ = np.eye(x_.shape[0])
        else:
            w_ = np.atleast_2d(feval(self.process['Jacobian_Q'], x_, u))

        if Q is None:
            Q = self.process['Q']
        else:
            self.process['Q'] = np.atleast_2d(Q)

        P = np.atleast_2d(F_ @ P_ @ F_.T + w_ @ Q @ w_.T)

        self.state['err_cov'] = P.copy()

        if self._verbose:
            print(self.state)

        self._history['predictions'].append(self.state.copy())
Esempio n. 2
0
    def __init__(
            self,
            x0,
            P0,
            f=None,
            Q0=None,
            Jf=None,
            JQ=None,  # Jacobians
            Hf=None,  # Hessian
            h=None,
            R0=None,
            Jh=None,
            JR=None,  # Jacobians
            Hh=None,  # Hessian
            _verbose: bool = False):
        """ TODO: write docstring """

        self.state = {
            'expected': np.atleast_2d(x0),
            'err_cov': np.atleast_2d(P0)
        }
        if f is None:
            if Jf is None:
                f = np.eye(x0.shape[0])
            else:
                f = lambda x: feval(feval(Jf, x), x)
        if Q0 is None:
            Q0 = np.zeros((x0.shape[0], x0.shape[0]))
        if Jf is None:
            Jf = np.eye(x0.shape[0])

        self.process = {
            'f': f,
            'Q': Q0,
            'Jacobian_x': Jf,
            'Hessian_x': Hf,
            'Jacobian_Q': JQ
        }

        if h is None:
            h = np.eye(x0.shape[0])
        if R0 is None:
            y_ = feval(h, x0)
            R0 = np.zeros((y_.shape[0], y_.shape[0]))
        if Jh is None:
            Jh = np.eye(x0.shape[0])

        self.observe = {
            'h': h,
            'R': R0,
            'Jacobian_x': Jh,
            'Hessian_x': Hh,
            'Jacobian_R': JR
        }

        self._history = {'predictions': [], 'updates': []}
        self._history['updates'].append(self.state)
        self.initial = self.state.copy()
        self._verbose = _verbose
Esempio n. 3
0
    def update(self, y, R=None, u=None):
        """ TODO: write docstring """

        if self.observe['Hessian_x'] is None:
            # If no Hessian supplied, use first order EKF update
            return super().update(Q, u)

        x_ = self.state['expected']
        P_ = self.state['err_cov']

        y_ = np.atleast_2d(feval(self.observe['h'], x_, u))

        H_ = feval(self.observe['Jacobian_x'], x_, u)
        G_ = feval(self.observe['Hessian_x'], x_, u)

        if self.observe['Jacobian_R'] is None:
            v_ = np.eye(y_.shape[0])
        else:
            v_ = feval(self.observe['Jacobian_R'], x_, u)

        for i_ in range(y_.shape[0]):
            y_[i_, 0] += 0.5 * np.trace(np.squeeze(G_[i_, :, :]) @ P_)

        if R is None:
            R = self.observe['R']
        else:
            self.observe['R'] = R

        P_xy = np.atleast_2d(P_ @ H_.T)
        P_y = np.atleast_2d(H_ @ P_xy + v_ @ R @ v_.T)

        for i_ in range(y_.shape[0]):
            for j_ in range(y_.shape[0]):
                P_y[i_, j_] += 0.5 * np.trace(
                    np.squeeze(G_[i_, :, :]) @ P_ @ np.squeeze(G_[j_, :, :])
                    @ P_)

        K = P_xy @ linalg.inv(P_y)

        x = x_ + K @ np.atleast_2d(y - y_)
        self.state['expected'] = x.copy()

        P = P_ - K @ P_y @ K.T
        self.state['err_cov'] = P.copy()

        self._history['updates'].append(self.state.copy())
Esempio n. 4
0
    def update(self, y, R=None, u=None):
        """ TODO: write docstring """

        x_ = self.state['expected']
        P_ = self.state['err_cov']

        # if u is None:
        #     y_ = np.atleast_2d(feval(self.observe['h'], x_))
        #     if self._verbose:
        #         print(y_)
        #     H_ = feval(self.observe['Jacobian_x'], x_)
        #     if self.observe['Jacobian_R'] is None:
        #         v_ = np.eye(y_.shape[0])
        #     else:
        #         v_ = feval(self.observe['Jacobian_R'], x_)
        # else:
        y_ = np.atleast_2d(feval(self.observe['h'], x_, u))
        H_ = feval(self.observe['Jacobian_x'], x_, u)
        if self.observe['Jacobian_R'] is None:
            v_ = np.eye(y_.shape[0])
        else:
            v_ = feval(self.observe['Jacobian_R'], x_, u)

        if R is None:
            R = self.observe['R']
        else:
            self.observe['R'] = R

        P_xy = P_ @ H_.T
        P_y = H_ @ P_xy + v_ @ R @ v_.T

        K = P_xy @ linalg.inv(P_y)

        # The reshape part fixes some weird scalar issues
        x = x_ + K @ np.atleast_2d(y - y_)

        self.state['expected'] = x.copy()
        if self._verbose:
            print('x is ' + str(x))

        P = P_ - K @ P_y @ K.T
        self.state['err_cov'] = P.copy()

        self._history['updates'].append(self.state.copy())
Esempio n. 5
0
    def predict(self, Q=None, u=None):
        """ TODO: write docstring """

        if self.process['Hessian_x'] is None:
            # If no Hessian supplied, use first order EKF prediction
            return super().predict(Q, u)

        x_ = self.state['expected']
        P_ = self.state['err_cov']

        F_ = feval(self.process['Jacobian_x'], x_, u)
        G_ = feval(self.process['Hessian_x'], x_, u)

        if self.process['Jacobian_Q'] is None:
            w_ = np.eye(x_.shape[0])
        else:
            w_ = feval(self.process['Jacobian_Q'], x_, u)

        x = feval(self.process['f'], x_, u)
        for i_ in range(x_.shape[0]):
            x[i_, 0] += 0.5 * np.trace(np.squeeze(G_[i_, :, :]) @ P_)

        self.state['expected'] = x.copy()

        if Q is None:
            Q = self.process['Q']
        else:
            self.process['Q'] = Q

        P = F_ @ P_ @ F_.T + w_ @ Q @ w_.T

        for i_ in range(x_.shape[0]):
            for j_ in range(x_.shape[0]):
                P[i_, j_] += 0.5 * np.trace(
                    np.squeeze(G_[i_, :, :]) @ P_ @ np.squeeze(G_[j_, :, :]))

        self.state['err_cov'] = P.copy()

        if self._verbose:
            print(self.state)

        self._history['predictions'].append(self.state.copy())
Esempio n. 6
0
    def smooth_incremental(self, Q=None, u=None):
        """ TODO: write docstring """
        if Q is None:
            Q = self.process['Q']
        else:
            self.process['Q'] = Q

        x_ = self.filtered[self._tx]['expected']

        # if u is None:
        #     x_p = feval(self.process['f'], x_)
        #     F_ = feval(self.process['Jacobian_x'], x_)
        #     if self.process['Jacobian_Q'] is None:
        #         w_ = np.eye(x_.shape[0])
        #     else:
        #         w_ = feval(self.process['Jacobian_Q'], x_)
        # else:
        x_p = feval(self.process['f'], x_, u)
        F_ = feval(self.process['Jacobian_x'], x_, u)
        if self.process['Jacobian_Q'] is None:
            w_ = np.eye(x_.shape[0])
        else:
            w_ = feval(self.process['Jacobian_Q'], x_, u)

        P_ = self.filtered[self._tx]['err_cov']
        P_p = F_ @ P_ @ F_.T + w_ @ Q @ w_.T

        S = P_ @ F_ @ linalg.inv(P_p)

        x_t = self.smoothed[self._tx + 1]['expected']
        P_t = self.smoothed[self._tx + 1]['err_cov']

        x = x_ + S @ np.atleast_2d(x_t - x_p)
        P = P_ + S @ np.atleast_2d(P_t - P_p) @ S.T

        self.smoothed[self._tx] = {'expected': x, 'err_cov': P}
        self._tx -= 1
Esempio n. 7
0
    def __init__(self,
                 x0,
                 P0,
                 f=None,
                 Q0=None,
                 h=None,
                 R0=None,
                 params=unscented_default_params(),
                 augment: bool = False,
                 _verbose: bool = False):
        """ TODO: write docstring """
        self.state = {
            'expected': np.atleast_2d(x0),
            'err_cov': np.atleast_2d(P0)
        }

        if f is None:
            f = np.eye(x0.shape[0])
        if Q0 is None:
            Q0 = np.zeros((x0.shape[0], x0.shape[0]))

        self.process = {'f': f, 'Q': Q0}

        if h is None:
            h = np.eye(x0.shape[0])
        if R0 is None:
            y_ = feval(h, x0)
            R0 = np.zeros((y_.shape[0], y_.shape[0]))

        self.observe = {'h': h, 'R': R0}

        self.params = params
        self._history = {'predictions': [], 'updates': []}
        self._history['updates'].append(self.state)
        self.initial = self.state.copy()
        self.augment = augment
        self._verbose = _verbose