Esempio n. 1
0
    def __init__(self, K=5):
        self.MAX_TRACKS = 6000
        self.K = K

        #Array of tracks, each track
        #has K 5D features preceded
        #by 5 params that inidicate
        #[f_idx, last_idx, updated, complete, valid]
        # f_idx: idx of current last feature in track
        # idx of of last feature in frame
        # bool for whether this track has been update
        # bool for whether this track is complete
        # bool for whether this track is valid
        self.tracks = np.zeros((self.MAX_TRACKS, K + 1, 5))
        self.tracks[:] = np.nan

        name = f"{FeatureHandler.name}_{K}"
        ffi, lib = load_code(name)

        def merge_features_c(tracks, features, empty_idxs):
            lib.merge_features(ffi.cast("double *", tracks.ctypes.data),
                               ffi.cast("double *", features.ctypes.data),
                               ffi.cast("long long *", empty_idxs.ctypes.data))

        #self.merge_features = self.merge_features_python
        self.merge_features = merge_features_c
Esempio n. 2
0
    def __init__(self, K=4, MIN_DEPTH=2, MAX_DEPTH=500):
        self.to_c = orient.rot_matrix(-np.pi / 2, -np.pi / 2, 0)
        self.MAX_DEPTH = MAX_DEPTH
        self.MIN_DEPTH = MIN_DEPTH

        name = f"{LstSqComputer.name}_{K}"
        ffi, lib = load_code(name)

        # wrap c functions
        def residual_jac(x, poses, img_positions):
            out = np.zeros(((K * 2, 3)), dtype=np.float64)
            lib.jac_fun(ffi.cast("double *", x.ctypes.data),
                        ffi.cast("double *", poses.ctypes.data),
                        ffi.cast("double *", img_positions.ctypes.data),
                        ffi.cast("double *", out.ctypes.data))
            return out

        self.residual_jac = residual_jac

        def residual(x, poses, img_positions):
            out = np.zeros((K * 2), dtype=np.float64)
            lib.res_fun(ffi.cast("double *", x.ctypes.data),
                        ffi.cast("double *", poses.ctypes.data),
                        ffi.cast("double *", img_positions.ctypes.data),
                        ffi.cast("double *", out.ctypes.data))
            return out

        self.residual = residual

        def compute_pos_c(poses, img_positions):
            pos = np.zeros(3, dtype=np.float64)
            param = np.zeros(3, dtype=np.float64)
            # Can't be a view for the ctype
            img_positions = np.copy(img_positions)
            lib.compute_pos(ffi.cast("double *", self.to_c.ctypes.data),
                            ffi.cast("double *", poses.ctypes.data),
                            ffi.cast("double *", img_positions.ctypes.data),
                            ffi.cast("double *", param.ctypes.data),
                            ffi.cast("double *", pos.ctypes.data))
            return pos, param

        self.compute_pos_c = compute_pos_c
Esempio n. 3
0
    def __init__(self,
                 name,
                 Q,
                 x_initial,
                 P_initial,
                 dim_main,
                 dim_main_err,
                 N=0,
                 dim_augment=0,
                 dim_augment_err=0,
                 maha_test_kinds=[]):
        """Generates process function and all observation functions for the kalman filter."""
        self.msckf = N > 0
        self.N = N
        self.dim_augment = dim_augment
        self.dim_augment_err = dim_augment_err
        self.dim_main = dim_main
        self.dim_main_err = dim_main_err

        # state
        x_initial = x_initial.reshape((-1, 1))
        self.dim_x = x_initial.shape[0]
        self.dim_err = P_initial.shape[0]
        assert dim_main + dim_augment * N == self.dim_x
        assert dim_main_err + dim_augment_err * N == self.dim_err
        assert Q.shape == P_initial.shape

        # kinds that should get mahalanobis distance
        # tested for outlier rejection
        self.maha_test_kinds = maha_test_kinds

        # process noise
        self.Q = Q

        # rewind stuff
        self.rewind_t = []
        self.rewind_states = []
        self.rewind_obscache = []
        self.init_state(x_initial, P_initial, None)

        ffi, lib = load_code(name)
        kinds, self.feature_track_kinds = [], []
        for func in dir(lib):
            if func[:2] == 'h_':
                kinds.append(int(func[2:]))
            if func[:3] == 'He_':
                self.feature_track_kinds.append(int(func[3:]))

        # wrap all the sympy functions
        def wrap_1lists(name):
            func = eval("lib.%s" % name, {"lib": lib})

            def ret(lst1, out):
                func(ffi.cast("double *", lst1.ctypes.data),
                     ffi.cast("double *", out.ctypes.data))

            return ret

        def wrap_2lists(name):
            func = eval("lib.%s" % name, {"lib": lib})

            def ret(lst1, lst2, out):
                func(ffi.cast("double *", lst1.ctypes.data),
                     ffi.cast("double *", lst2.ctypes.data),
                     ffi.cast("double *", out.ctypes.data))

            return ret

        def wrap_1list_1float(name):
            func = eval("lib.%s" % name, {"lib": lib})

            def ret(lst1, fl, out):
                func(ffi.cast("double *", lst1.ctypes.data),
                     ffi.cast("double", fl),
                     ffi.cast("double *", out.ctypes.data))

            return ret

        self.f = wrap_1list_1float("f_fun")
        self.F = wrap_1list_1float("F_fun")

        self.err_function = wrap_2lists("err_fun")
        self.inv_err_function = wrap_2lists("inv_err_fun")
        self.H_mod = wrap_1lists("H_mod_fun")

        self.hs, self.Hs, self.Hes = {}, {}, {}
        for kind in kinds:
            self.hs[kind] = wrap_2lists("h_%d" % kind)
            self.Hs[kind] = wrap_2lists("H_%d" % kind)
            if self.msckf and kind in self.feature_track_kinds:
                self.Hes[kind] = wrap_2lists("He_%d" % kind)

        # wrap the C++ predict function
        def _predict_blas(x, P, dt):
            lib.predict(ffi.cast("double *", x.ctypes.data),
                        ffi.cast("double *", P.ctypes.data),
                        ffi.cast("double *", self.Q.ctypes.data),
                        ffi.cast("double", dt))
            return x, P

        # wrap the C++ update function
        def fun_wrapper(f, kind):
            f = eval("lib.%s" % f, {"lib": lib})

            def _update_inner_blas(x, P, z, R, extra_args):
                f(ffi.cast("double *", x.ctypes.data),
                  ffi.cast("double *", P.ctypes.data),
                  ffi.cast("double *", z.ctypes.data),
                  ffi.cast("double *", R.ctypes.data),
                  ffi.cast("double *", extra_args.ctypes.data))
                if self.msckf and kind in self.feature_track_kinds:
                    y = z[:-len(extra_args)]
                else:
                    y = z
                return x, P, y

            return _update_inner_blas

        self._updates = {}
        for kind in kinds:
            self._updates[kind] = fun_wrapper("update_%d" % kind, kind)

        def _update_blas(x, P, kind, z, R, extra_args=[]):
            return self._updates[kind](x, P, z, R, extra_args)

        # assign the functions
        self._predict = _predict_blas
        # self._predict = self._predict_python
        self._update = _update_blas