예제 #1
0
def Quaternion2DCM(quaternion):
    '''
    Calcul la matrice de passage DCM (Direct Cosine Matrix) à partir du quaternion q.

    Si q = q0+ q1 i + q2 j + q3 k alors

    DCM =
    [
    1-2q2^2-2q3^2    2q1q2-2q0q3     2q1q3+2q0q2
    2q1q2+2q0q3      1-2q1^2-2q3^2   2q2q3-2q0q1
    2q1q3-2q0q2      2q2q3+2q0q1     1-2q1^2-2q2^2
    ]
    '''
    check.vecteur_n(4, quaternion, "bloc outils/Quaternion2DCM")

    q = quaternion

    dcm = np.empty([3, 3])
    dcm[0][0] = 1 - 2 * q[2]**2 - 2 * q[3]**2
    dcm[1][0] = 2 * q[1] * q[2] + 2 * q[0] * q[3]
    dcm[2][0] = 2 * q[1] * q[3] - 2 * q[0] * q[2]

    dcm[0][1] = 2 * q[1] * q[2] - 2 * q[0] * q[3]
    dcm[1][1] = 1 - 2 * q[1]**2 - 2 * q[3]**2
    dcm[2][1] = 2 * q[2] * q[3] + 2 * q[0] * q[1]

    dcm[0][2] = 2 * q[1] * q[3] + 2 * q[0] * q[2]
    dcm[1][2] = 2 * q[2] * q[3] - 2 * q[0] * q[1]
    dcm[2][2] = 1 - 2 * q[1]**2 - 2 * q[2]**2

    dcm = dcm.T
    return dcm
예제 #2
0
def Euler2Quaternion(euler):
    '''
    Calcul du quaternion q à partir des angles d'Euler (phi,theta,psi)

    q = q0 + q1 i + q2 j + q3 k
    avec :

    q0 = cos(0.5*psi)cos(0.5*theta)cos(0.5*phi) + sin(0.5*psi)sin(0.5*theta)sin(0.5*phi)
    q1 =  sin(0.5*psi)cos(0.5*theta)cos(0.5*phi) - cos(0.5*psi)sin(0.5*theta)sin(0.5*phi)
    q2 =  cos(0.5*psi)sin(0.5*theta)cos(0.5*phi) + sin(0.5*psi)cos(0.5*theta)sin(0.5*phi)
    q3 =  cos(0.5*psi)cos(0.5*theta)sin(0.5*phi) - sin(0.5*psi)sin(0.5*theta)cos(0.5*phi)
    '''
    check.vecteur_n(3, euler, "bloc outils/Euler2Quaternion")

    phi = euler[0]
    theta = euler[1]
    psi = euler[2]

    u = np.empty(6)
    u[0] = np.sin(phi / 2)
    u[1] = np.cos(phi / 2)
    u[2] = np.sin(theta / 2)
    u[3] = np.cos(theta / 2)
    u[4] = np.sin(psi / 2)
    u[5] = np.cos(psi / 2)

    quaternion = np.empty(4)
    quaternion[0] = u[1] * u[3] * u[5] + u[0] * u[2] * u[4]
    quaternion[1] = u[0] * u[3] * u[5] - u[1] * u[2] * u[4]
    quaternion[2] = u[1] * u[2] * u[5] + u[0] * u[3] * u[4]
    quaternion[3] = u[1] * u[3] * u[4] - u[0] * u[2] * u[5]

    return quaternion
예제 #3
0
def vectoriel(u, v):
    '''
    Calcul le produit vectoriel de deux vecteur 3x1
    '''
    params = [u, v]
    for i, p in enumerate(params):
        check.vecteur_n(3, p, "bloc outils/vectoriel")

    w = np.cross(u, v)
    return w
예제 #4
0
def Inert2Miss(euler, u):
    '''
    Calcul les composantes d'un vecteur du repère inertiel dans le repère missile.
    '''
    check.vecteur_n(3, euler, "bloc outils/Inert2Miss")
    check.vecteur_n(3, u, "bloc outils/Inert2Miss")

    dcm = Euler2DCM(euler)
    v = dcm.dot(u)
    return v
예제 #5
0
    def execute(self, ecef):
        '''
        Transforme les coordonnées dans le repère ECEF (Earth-Centered
        Earth Fixed)  [m,m,m] en coordonnées géographiques LLA
        [rad,rad,m] par rapport à l'ellipsoïde de référence)
        '''
        self.input = ecef

        check.vecteur_n(3, self.input, "bloc outils/ECEF2LLA")

        r = self.__calcul_r()
        phi = self.__calcul_latitude(r)
        lmbda = self.__calcul_longitude()
        h = self.__calcul_h(phi, r)

        self.output = np.array([phi, lmbda, h])
예제 #6
0
    def execute(self, enu):
        '''
        Transforme les coordonnées dans le repère ENU local 
        (East North Up) xyz= [m,m,m]  défini par le plan tangent 
        à l'ellipsoïde au point origine lla0 [rad,rad,m] et le 
        vecteur normal défini positivement suivant les altitudes 
        dans le repère ECEF (Earth Centered Earth Fixed).
        '''
        self.input = enu

        check.vecteur_n(3, enu, "bloc outils/xyz_ENU2ECEF")

        xyz0 = self.__calcul_xyz0()
        m_ned2ecef = self.__calcul_M_NED2ECEF()
        ned = np.array([self.input[1], self.input[0], -self.input[2]])

        self.output = xyz0 + m_ned2ecef.dot(ned)
예제 #7
0
def Euler2DCM(euler):
    '''
    Calcul la matrice de passage DCM (Direct Cosine Matrix) à partir des angles d'Euler.

    DCM =
    [
    c(theta)c(psi)    -c(phi)s(psi)+s(phi)s(theta)c(psi)    s(phi)s(psi)+c(phi)s(theta)c(psi)

    c(theta)s(psi)    c(phi)c(psi)+s(phi)s(theta)s(psi)     -s(phi)c(psi)+c(phi)s(theta)s(psi)

    -s(theta)         s(phi)c(theta)                        c(phi)c(theta)
    ]^T
    où c correspond à cos,  et s correspond à sin
    '''
    check.vecteur_n(3, euler, "bloc outils/Euler2DCM")

    phi = euler[0]
    theta = euler[1]
    psi = euler[2]

    u = np.empty(6)
    u[0] = np.sin(phi)
    u[1] = np.cos(phi)
    u[2] = np.sin(theta)
    u[3] = np.cos(theta)
    u[4] = np.sin(psi)
    u[5] = np.cos(psi)

    dcm = np.empty([3, 3])
    dcm[0][0] = u[3] * u[5]
    dcm[1][0] = u[3] * u[4]
    dcm[2][0] = -u[2]

    dcm[0][1] = -u[1] * u[4] + u[0] * u[2] * u[5]
    dcm[1][1] = u[1] * u[5] + u[0] * u[2] * u[4]
    dcm[2][1] = u[0] * u[3]

    dcm[0][2] = u[0] * u[4] + u[1] * u[2] * u[5]
    dcm[1][2] = -u[0] * u[5] + u[1] * u[2] * u[4]
    dcm[2][2] = u[1] * u[3]

    dcm = dcm.T
    return dcm
예제 #8
0
def Quaternion2Euler(quaternion):
    '''
    Calcul des angles d'Euler (phi,theta,psi) à partir du quaternion q. 

    Si q = q0 + q1 i + q2 j + q3 k ,  alors

    phi = atan2( 2(q0q1+q2q3) , q0^2-q1^2 - q2^2+q3^2)
    theta = asin(2q0q2-2q1q3)
    psi = atan2( 2(q1q2+q0q3) , q0^2+q1^2 - q2^2-q3^2)
    '''
    check.vecteur_n(4, quaternion, "bloc outils/Quaternion2Euler")

    q = quaternion
    euler = np.empty(3)

    euler[0] = math.atan2(2 * (q[0] * q[1] + q[2] * q[3]),
                          q[0]**2 - q[1]**2 - q[2]**2 + q[3]**2)
    euler[1] = math.asin(np.clip(2 * (q[0] * q[2] - q[1] * q[3]), -1, 1))
    euler[2] = math.atan2(2 * (q[1] * q[2] + q[0] * q[3]),
                          q[0]**2 + q[1]**2 - q[2]**2 - q[3]**2)

    return euler
예제 #9
0
    def execute(self, euler):
        '''
        Calcul du quaternion à partir des vitesses de rotation du missile et de 
        l'attidude initiale du missile.
        '''
        self.input = euler
        check.vecteur_n(3, euler, "bloc outils/pqr2Quaternion")

        if self.time != -1:
            eidot = self.__pqr2eidot()
            y = self.__integrator(eidot)
            self.output = y / norme(y)

            eidot = self.__pqr2eidot()
            self.int_xdot = eidot

            self.time += self.time_step
        else:
            self.output = self.int_x / norme(self.int_x)
            eidot = self.__pqr2eidot()
            self.int_xdot = eidot
            self.time = 0
예제 #10
0
    def execute(self, ned):
        '''
        Calcul les coordonnées LLA (latitude, longitude, altitude) à 
        partir des coordonnées xyz exprimées dans le repère NED 
        (North, East, Down) dont l'origine du repère est définit par une 
        position LLA de référence.
        '''
        self.input = ned

        check.vecteur_n(3, self.input, "bloc outils/NED2LLA")

        enu = np.array([self.input[1], self.input[0], -self.input[2]])

        enu2ecef = ENU2ECEF(self.lla_ref[0], self.lla_ref[1], self.lla_ref[2],
                            self.ellipsoide[0], self.ellipsoide[1],
                            self.ellipsoide[2])
        enu2ecef.execute(enu)

        ecef2lla = ECEF2LLA(self.ellipsoide[0], self.ellipsoide[1],
                            self.ellipsoide[2])
        ecef2lla.execute(enu2ecef.output)

        self.output = ecef2lla.output