def __call__(self, T, X):
        """Calculate control.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch

        Returns:
            u: ndarray
                (m, 3) array of control vectors.
        """
        m = T.shape[0]
        G = GVE(mu=self.mu)(T, self.X(T))

        GTG_inv = np.array([np.linalg.inv(g.T @ g)
                            for g in G])

        return (
            GTG_inv @ G.transpose((0, 2, 1)) @
            self.Xdot(T).reshape((m, 6, 1))
            ).reshape((m, 3))
Example #2
0
    def __call__(self, T, X):
        """Calculate constant acceleration as MEE time derivatives.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch

        Returns:
            Xdot: ndarray
                (m, 6) array of state derivatives.
        """
        m = T.shape[0]
        u = np.tile(self.vector, (m, 1, 1))
        G = GVE(mu=self.mu)(T, X)
        self.u = u.reshape((m, 3))

        return (G @ u).reshape((m, 6))
Example #3
0
    def __call__(self, T, X):
        """Calculate zonal gravity perturations for MEEs with Ml0.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch

        Returns:
            Xdot: ndarray
                (m, 6) array of state derivatives.
        """
        super().lvlh_acceleration(T, convert.rv_mee(convert.mee_meeMl0(T, X)))
        G = GVE()(T, X)
        m = T.shape[0]

        return (G @ self.a_lvlh.reshape((m, 3, 1))).reshape((m, 6))
    def __call__(self, T, X):
        """Calculate control.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch

        Returns:
            u: ndarray
                (m, 3) array of control vectors.
        """
        m = T.shape[0]
        G = GVE(mu=self.mu)(T, X)

        GTG_inv = np.array([np.linalg.inv(g.T @ g) for g in G])

        self.E = np.tile(self.Xf, T.shape) - X

        u = (GTG_inv @ G.transpose((0, 2, 1)) @ self.E.reshape(
            (m, 6, 1))).reshape((m, 3))

        # u = np.array([u_i / np.linalg.norm(u_i) if np.linalg.norm(u_i) > 1
        #            else u_i for u_i in u])
        u = u / np.tile(np.linalg.norm(u, axis=1, keepdims=True), (1, 3))
        self.u = u

        return self.a_t * (G @ u.reshape((m, 3, 1))).reshape((m, 6))
    def __call__(self, T, X):
        """Calculate control.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch

        Returns:
            Xdot: ndarray
                (m, 6) array of state derivatives.
        """
        # state errors
        m = T.shape[0]
        Y = self.Y_func(T)
        self.E = mod_angles(X - Y)

        # delta control
        G_r = GVE(mu=self.mu)(T, Y)
        self.du = -(self.a_t * G_r.T @ self.E.reshape((m, 6, 1))).reshape(
            (m, 3))
        self.u = self.U_func(T) + self.du

        # lyapunov function and derivative
        self.V = (self.E.reshape(
            (m, 1, 6)) @ np.tile(self.W, (m, 1, 1)) @ self.E.reshape(
                (m, 6, 1))).reshape((m, 1))

        self.dVdt = (self.E.reshape(
            (m, 1, 6)) @ np.tile(self.W, (m, 1, 1)) @ G_r @ self.du.reshape(
                (m, 3, 1))).reshape((m, 1))

        self.u.shape = (m, 3)
        return self.a_t * (G_r @ self.u.reshape((m, 3, 1))).reshape((m, 6))
Example #6
0
    def __call__(self, T, X, a_d):
        """Calculate GVESSMs for MEEs with mean longitude at epoch.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch
            a_d: ndarray
                (m, 3) generalized LVLH perturbation vector.

        Returns:
            dGdx: ndarray
                (m, 6, 6) array of STMs, or an (m, 36, 36) block diagonal of
                STMs, depending on the value of vectorize.
        """
        m = T.shape[0]
        Xh = (np.tile(X.reshape((m, 1, 6)), (1, 6, 1)) +
              np.tile(np.identity(6), (m, 1, 1))*self.h)

        G_func = GVE(mu=self.mu)
        G = G_func(T, X)

        a_d = a_d.reshape((m, 3, 1))

        return np.concatenate(
            [(G_func(T, x.reshape((m, 6))) - G)/self.h @ a_d
             for x in Xh.transpose((1, 0, 2))],
            axis=2
        )
Example #7
0
    def __call__(self, T, X):
        """Calculate control.

        Args:
            T: ndarray
                (m, 1) array of times.
            X: ndarray
                (m, 6) array of modified equinoctial elements ordered as
                (p, f, g, h, k, Ml0), where
                p = semi-latus rectum
                f = 1-component of eccentricity vector in perifocal frame
                g = 2-component of eccentricity vector in perifocal frame
                h = 1-component of the ascending node vector in equ. frame
                k = 2-component of the ascending node vector in equ. frame
                Ml0 = mean longitude at epoch

        Returns:
            Xdot: ndarray
                (m, 6) array of state derivatives.
        """
        m = T.shape[0]
        G = GVE(mu=self.mu)(T, X)

        # state errors
        Y = self.Y_func(T)
        self.E = mod_angles(X - Y)

        # control
        EW = (self.E @ self.W).reshape((m, 1, 6))
        c = EW @ G

        if self.steering:
            self.u = np.array([-x / np.linalg.norm(x, axis=1) for x in c])
        else:
            self.u = np.zeros((m, 3))
            for i, x in enumerate(c):
                x_norm = np.linalg.norm(x, axis=1)
                if x_norm > 1:
                    self.u[i] = -x / x_norm
                elif x_norm < self.lower_bound:
                    self.u[i] = -self.lower_bound * x / x_norm
                else:
                    self.u[i] = -x

        if self.sliding_mag:
            E_norm = np.tile(
                np.linalg.norm(self.E, axis=1).reshape((m, 1, 1)), (1, 1, 3))
            self.u = self.u * E_norm / E_norm[0, 0, 0]

        # lyapunov function and derivative
        self.V = (self.E.reshape(
            (m, 1, 6)) @ np.tile(self.W, (m, 1, 1)) @ self.E.reshape(
                (m, 6, 1))).reshape((m, 1))
        kepdyn = KeplerianDynamics()
        a_d = self.a_t * G @ self.u.reshape((m, 3, 1))
        dXdt = kepdyn(T, X) + a_d.reshape((m, 6))
        dYdt = kepdyn(T, Y)
        dEdt = dXdt - dYdt
        self.dVdt = (self.E.reshape(
            (m, 1, 6)) @ np.tile(self.W, (m, 1, 1)) @ dEdt.reshape(
                (m, 6, 1))).reshape((m, 1))

        self.u.shape = (m, 3)
        return self.a_t * (G @ self.u.reshape((m, 3, 1))).reshape((m, 6))