示例#1
0
 def test_Initialize(self):
     s = Strapdown()
     s.Initialze(toVector(0., 0., -10.), toVector(1., 0., 0.),
                 toVector(10., 5., 12.))
     self.assertTrue(s.isInitialized)
     q0, q1, q2, q3 = toValue(s.quaternion.values)
     self.assertEqual(q0, 1.)
     self.assertEqual(q1, 0.)
     self.assertEqual(q2, 0.)
     self.assertEqual(q3, 0.)
     x, y, z = toValue(s.position.values)
     self.assertEqual(x, 10.)
     self.assertEqual(y, 5.)
     self.assertEqual(z, 12.)
示例#2
0
 def test_init_values(self):
     q = Quaternion(toVector(1., 0.5, -0.5))
     q0, q1, q2, q3 = toValue(q.values)
     self.assertAlmostEqual(q0, 0.795, delta=0.001)
     self.assertAlmostEqual(q1, 0.504, delta=0.001)
     self.assertAlmostEqual(q2, 0.095, delta=0.001)
     self.assertAlmostEqual(q3, -0.325, delta=0.001)
示例#3
0
 def test_ell2xyz(self):
     llh = EllipsoidPosition(deg2rad(toVector(52.52,13.40,0.)))
     xyz = ell2xyz(llh) 
     x,y,z = toValue(xyz)
     self.assertAlmostEqual(x, 3783323.72435, delta = 0.0001)
     self.assertAlmostEqual(y, 901314.84651, delta = 0.0001)
     self.assertAlmostEqual(z, 5038219.09955, delta = 0.0001)
示例#4
0
 def getConjugatedQuaternion(self):
     """ returns the conjugated quaternion 
     """
     conjQuat = Quaternion()
     q0, q1, q2, q3 = toValue(self.values)
     conjQuat.values = toVector(q0, -q1, -q2, -q3)
     return conjQuat
示例#5
0
 def test_init_empty(self):
     q = Quaternion()
     q0, q1, q2, q3 = toValue(q.values)
     self.assertEqual(q0, 1.)
     self.assertEqual(q1, 0.)
     self.assertEqual(q2, 0.)
     self.assertEqual(q3, 0.)
示例#6
0
 def test_getEulerAngles(self):
     q = Quaternion(toVector(0.75, -0.51, pi))
     vec = q.getEulerAngles()
     phi, theta, psi = toValue(vec)
     self.assertAlmostEqual(0.75, phi, delta=0.001)
     self.assertAlmostEqual(-0.51, theta, delta=0.001)
     self.assertAlmostEqual(pi, psi, delta=0.001)
示例#7
0
 def test_update_without_rotation(self):
     q = Quaternion()
     q.update(toVector(0.0, 0.0, 0.0), 0.01)
     q0, q1, q2, q3 = toValue(q.values)
     self.assertEqual(q0, 1.)
     self.assertEqual(q1, 0.)
     self.assertEqual(q2, 0.)
     self.assertEqual(q3, 0.)
示例#8
0
 def __format__(self, f):
     phi, theta, psi = toValue(self.values)
     if f == 'deg':
         return 'Roll: {:4.3f} deg, Pitch: {:4.3f} deg, Yaw: {:4.3f} deg'.format(
             rad2deg(phi), rad2deg(theta), rad2deg(psi))
     elif f == 'rad':
         return 'Roll: {:4.3f} rad, Pitch: {:4.3f} rad, Yaw: {:4.3f} rad'.format(
             phi, theta, psi)
示例#9
0
 def test_update(self):
     q = Quaternion()
     rotationRate = toVector(-100., 50., 120.)
     q.update(rotationRate, 0.01)
     q0, q1, q2, q3 = toValue(q.values)
     self.assertAlmostEqual(q0, 0.68217, delta=0.0001)
     self.assertAlmostEqual(q1, -0.44581, delta=0.0001)
     self.assertAlmostEqual(q2, 0.22291, delta=0.0001)
     self.assertAlmostEqual(q3, 0.53498, delta=0.0001)
示例#10
0
def plotRGB(x, vector):
    """ plots 3x1 vector in 1 axis
    """
    y1, y2, y3 = toValue(vector)
    handle1, = plt.plot(x, y1, 'ro')
    handle2, = plt.plot(x, y2, 'go')
    handle3, = plt.plot(x, y3, 'bo')
    plt.grid(True)
    plt.legend([handle1, handle2, handle3], ['X', 'Y', 'Z'])
示例#11
0
 def test_concatenation(self):
     q = Quaternion()
     q_increment = Quaternion(toVector(deg2rad(10.), 0., 0.))
     #q.values = mvMultiplication(q.values,q_increment.values)
     q *= q_increment
     q0, q1, q2, q3 = toValue(q.values)
     self.assertAlmostEqual(q0, 0.996, delta=0.001)
     self.assertAlmostEqual(q1, 0.087, delta=0.001)
     self.assertAlmostEqual(q2, 0., delta=0.001)
     self.assertAlmostEqual(q3, 0., delta=0.001)
示例#12
0
 def test_update_180(self):
     q = Quaternion()
     rotationRate = toVector(0., deg2rad(5.), 0.)  #rad/s
     for _ in range(3600):
         q.update(rotationRate, 0.01)
     q0, q1, q2, q3 = toValue(q.values)
     self.assertAlmostEqual(q0, 0.0, delta=0.0001)
     self.assertAlmostEqual(q1, 0.0, delta=0.0001)
     self.assertAlmostEqual(q2, 1., delta=0.0001)
     self.assertAlmostEqual(q3, 0.0, delta=0.0001)
示例#13
0
    def correct(self, vector):
        """ vector is defined as (N, E, D) in meter 
        """
        lat, _, h = toValue(self.values)
        Rn, Re = earthCurvature(self.a, self.f, lat)
        M = eye(3, 3)
        M[0, 0] = 1 / (Rn - h)
        M[1, 1] = 1 / ((Re - h)) * cos(lat)
        M[2, 2] = 1

        self.values += M * vector
示例#14
0
 def test_vecTransformation(self):
     q = Quaternion(toVector(0.1, 0.5, 0.2))
     vec1 = toVector(0.1, -2., 9.81)
     vec2 = q.vecTransformation(vec1)
     self.assertAlmostEqual(vec2[0].item(), 5.168, delta=0.001)
     self.assertAlmostEqual(vec2[1].item(), -1.982, delta=0.001)
     self.assertAlmostEqual(vec2[2].item(), 8.343, delta=0.001)
     a, b, c = toValue(vec2)
     self.assertAlmostEqual(pythagoras(0.1, -2., 9.81),
                            pythagoras(a, b, c),
                            delta=0.001)
示例#15
0
def ell2xyz(pos_obj):
    """ transformation of geographic coordinates to cartesian coordinates
        input is an EllipsoidPosition-object
        returns a 3x1 vector
    """
    lat, lon, he = toValue(pos_obj.values)
    _, N = earthCurvature(pos_obj.a, pos_obj.f, lat)
    x = (N + he) * cos(lat) * cos(lon)
    y = (N + he) * cos(lat) * sin(lon)
    z = N * sin(lat) * (pos_obj.b**2 / pos_obj.a**2) + he * sin(lat)
    return toVector(x, y, z)
示例#16
0
def plotVector(x, vector):
    """ plots 3x1 vector using subplots
    """
    y1, y2, y3 = toValue(vector)
    symbol = 'ro'
    plt.subplot(311)
    plt.plot(x, y1, symbol)
    plt.subplot(312)
    plt.plot(x, y2, symbol)
    plt.subplot(313)
    plt.plot(x, y3, symbol)
示例#17
0
    def update(self, velocity, DT):
        """ updates current position based on previous position and velocity 
            velocity-object has attribute values in m/s 
        """
        lat, _, h = toValue(self.values)
        Rn, Re = earthCurvature(self.a, self.f, lat)
        M = eye(3, 3)
        M[0, 0] = 1 / (Rn - h)
        M[1, 1] = 1 / ((Re - h)) * cos(lat)
        M[2, 2] = 1

        self.values += (DT * M) * velocity.values
示例#18
0
def plot3DFrame(s, ax):
    """ transforms and plots 3 orthognal vectors representing the orientation
        requires a strapdown-object and an 3D axis as argument
    """
    q = s.quaternion.getConjugatedQuaternion()
    xn = toVector(0, 1, 0)
    yn = toVector(1, 0, 0)
    zn = toVector(0, 0, -1)

    xb = q.vecTransformation(xn)
    yb = q.vecTransformation(yn)
    zb = q.vecTransformation(zn)

    x1, x2, x3 = toValue(xb)
    y1, y2, y3 = toValue(yb)
    z1, z2, z3 = toValue(zb)
    xb = [x1, x2, x3]
    yb = [y1, y2, y3]
    zb = [z1, z2, z3]

    for i in range(3):
        ax.plot([0, xb[i]], [0, yb[i]], zs=[0, zb[i]])

    ax.auto_scale_xyz([-1, 1], [-1, 1], [-1, 1])
    ax.set_xlabel('East')
    ax.set_ylabel('North')
    ax.set_zlabel('Down')

    phi, theta, psi = s.getOrientation()
    vx, vy, vz = s.getVelocity()
    px, py, pz = s.getPosition()
    s1 = ' Roll: %.4f\n Pitch: %.4f\n Yaw: %.4f\n\n' % (
        rad2deg(phi), rad2deg(theta), rad2deg(psi))
    s2 = ' vx: %.2f\n vy: %.2f\n vz: %.2f\n\n' % (vx, vy, vz)
    s3 = ' px: %.2f\n py: %.2f\n pz: %.2f\n' % (px, py, pz)
    plt.figtext(0, 0, s1 + s2 + s3)
示例#19
0
    def __init__(self, acceleration=-G, magneticField=EARTHMAGFIELD):
        """ calculates the bearing from raw acceleration and magnetometer values
            accelaration in m/s2 and magnetic field in gauss
            angles are saved in radians
            calling w/o arguments creates a vector with phi, theta, psi = 0
        """
        ax, ay, az = toValue(acceleration)
        mx, my, mz = toValue(magneticField)
        if isclose(pythagoras(ax, ay, az), 0., abs_tol=0.001):
            raise ValueError("Acceleration is not significant")
        if isclose(pythagoras(mx, my, mz), 0., abs_tol=0.001):
            raise ValueError("MagneticFlux is not significant")

        phi = -atan2(ay, -az)  #phi = asin(-ay/g*cos(theta))
        theta = asin(ax / g)

        # transformation to horizontal coordinate system - psi = 0
        q = Quaternion(toVector(phi, theta, 0.))
        mHor = q.vecTransformation(magneticField)
        mxh, myh, _ = toValue(mHor)

        psi = atan2(myh, mxh) - DECANGLE

        self.values = toVector(phi, theta, psi)
示例#20
0
    def __init__(self, euler=toVector(0., 0., 0.)):
        """ Quaternion is initiated by Euler angles
            the angles are given in radians using ZYX-convention
        """
        phi, theta, psi = toValue(euler)

        ph2 = phi / 2
        th2 = theta / 2
        ps2 = psi / 2

        q0 = cos(ph2) * cos(th2) * cos(ps2) + sin(ph2) * sin(th2) * sin(ps2)
        q1 = sin(ph2) * cos(th2) * cos(ps2) - cos(ph2) * sin(th2) * sin(ps2)
        q2 = cos(ph2) * sin(th2) * cos(ps2) + sin(ph2) * cos(th2) * sin(ps2)
        q3 = cos(ph2) * cos(th2) * sin(ps2) - sin(ph2) * sin(th2) * cos(ps2)

        self.values = toVector(q0, q1, q2, q3)
示例#21
0
    def getEulerAngles(self):
        """ calculates Euler angles from the current Quaternion
            result is given in a 3x1 vector in radians
        """

        q0, q1, q2, q3 = toValue(self.values)

        try:
            phi = atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1**2 + q2**2))
            st = 2 * (q0 * q2 - q3 * q1)
            st = 1 if st > 1 else st  #gimbal lock
            st = -1 if st < -1 else st
            theta = asin(st)
            psi = atan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (q2**2 + q3**2))
        except ValueError:
            raise ValueError('Quaternion is invalid', q0, q1, q2, q3)

        return toVector(phi, theta, psi)
示例#22
0
    def getRotationMatrix(self):
        """ creates the 3x3 rotation matrix from quaternion parameters 
            represents the same relation between coordinate systems
            return a numpy.matrix
        """
        q0, q1, q2, q3 = toValue(self.values)

        r11 = q0**2 + q1**2 - q2**2 - q3**2
        r22 = q0**2 - q1**2 + q2**2 - q3**2
        r33 = q0**2 - q1**2 - q2**2 + q3**2
        r12 = 2 * (q1 * q2 - q0 * q3)
        r13 = 2 * (q1 * q3 + q0 * q2)
        r23 = 2 * (q2 * q3 - q0 * q1)
        r21 = 2 * (q1 * q2 + q0 * q3)
        r31 = 2 * (q1 * q3 - q0 * q2)
        r32 = 2 * (q2 * q3 + q0 * q1)

        return matrix([[r11, r12, r13], [r21, r22, r23], [r31, r32, r33]])
示例#23
0
def data_listener():
    s = Strapdown()
    rot_mean = toVector(0., 0., 0.)
    acc_mean = toVector(0., 0., 0.)
    mag_mean = toVector(0., 0., 0.)
    gyroBias = toVector(0., 0., 0.)

    i = 0
    init_time = 1 / 6  #min
    while True:
        if imu.IMURead():
            data = imu.getIMUData()
            gyro = data["gyro"]
            gyro_v = toVector(gyro[0], gyro[1], gyro[2]) - gyroBias
            accel = data["accel"]
            accel_v = toVector(accel[0], accel[1], accel[2]) * -9.80665
            mag = data["compass"]
            mag_v = toVector(mag[0], mag[1], mag[2])
            if not s.isInitialized:
                rot_mean = runningAverage(rot_mean, gyro_v, 1 / i)
                acc_mean = runningAverage(acc_mean, accel_v, 1 / i)
                mag_mean = runningAverage(mag_mean, mag_v, 1 / i)
                if (i * poll_interval / 1000) % 60 == 0:
                    print('Initialized in %.1f minutes\n' %
                          (init_time - i * poll_interval / 1000. / 60., ))
                if i * poll_interval / 1000 >= init_time:
                    s.Initialze(acc_mean, mag_mean)
                    gyroBias = rot_mean

                    print('STRAPDOWN INITIALIZED with %i values\n' % (i, ))
                    print('Initial bearing\n', s.getOrientation())
                    print('Initial velocity\n', s.getVelocity())
                    print('Initial position\n', s.getPosition())
                    print('Initial gyro Bias\n', gyroBias)
            else:
                s.quaternion.update(gyro_v)
                s.velocity.update(accel_v, s.quaternion)
                s.position.update(s.velocity)
                phi, theta, psi = toValue(rad2deg(s.getOrientation()))
                phi_list.append(phi)
                theta_list.append(theta)
                psi_list.append(psi)
                i += 1
                i_list.append(i)
示例#24
0
    def update(self, rotationRate, DT):
        """ updates the quaternion via the rotation of the last period
            the rotation rate is a 3x1 vector - wx, wy, wz
            approximated quaternion differential equation
        """
        w = rotationRate * DT
        wx, wy, wz = toValue(w)
        norm = pythagoras(wx, wy, wz)

        # exact formula
        #         r1 = cos(norm/2)
        #         factor = 1/norm * sin(norm/2)
        #         r234 = w*factor

        # series expansion
        r1 = 1 - (1 / 8) * norm**2 + (1 / 384) * norm**4 - (1 /
                                                            46080) * norm**6
        factor = 0.5 - (1 / 48) * norm**2 + (1 / 3840) * norm**4 - (
            1 / 645120) * norm**6
        r234 = w * factor
        r = insert(r234, 0, r1)

        self.values = mvMultiplication(self.values, r.transpose())
示例#25
0
 def test_getVelocity(self):
     s = Strapdown()
     v1, v2, v3 = toValue(s.getVelocity())
     self.assertEqual(v1, 0.)
     self.assertEqual(v2, 0.)
     self.assertEqual(v3, 0.)
示例#26
0
 def __str__(self):
     q0, q1, q2, q3 = toValue(self.values)
     return 'q0: {:2.3f}, q1: {:2.3f}, q2: {:2.3f}, q3: {:2.3f}'.format(
         q0, q1, q2, q3)
示例#27
0
theta = 1 * pi / 180
psi = 0 * pi / 180

# bw = toVector((theta), -(phi), 0)  # 5degree/s
bw = toVector(
    sin(phi) * sin(psi) + cos(phi) * sin(theta) * cos(psi),
    -sin(phi) * cos(psi) + cos(phi) * sin(theta) * sin(psi),
    1 - cos(phi) * cos(theta))

ba = toVector(10, 10, 10)  # mg
ba_ms = ba * g / 1000

for t in range(60):

    dr1 = (1 / 6) * g * (bw) * t**3

    dr2 = (1 / 2) * ba_ms * t**2

    x, y, z = toValue(dr1)

    red_dot, = plt.plot(t, x, "ro")
    blue_dot, = plt.plot(t, y, "bo")
    green_dot, = plt.plot(t, z, "go")

plt.legend([red_dot, blue_dot, green_dot], ["X-Pos", "Y-Pos", "Z-Pos"])
title('Positionsfehler durch Drehratenbias')

xlabel('Zeit in [sek]')
ylabel('Positionsfehler in [m]')
plt.show()
示例#28
0
 def __str__(self):
     vx, vy, vz = toValue(self.values)
     return 'vx: {:4.2f} m/s, vy: {:4.3f} m/s, vz: {:4.3f} ms'.format(
         vx, vy, vz)
from MathLib import toVector, toValue
from math import pi
g = 9.81

ba = toVector(10, 10, 10)  # mg
ba_ms = ba * g / 1000
bx, by, bz = toValue(ba_ms)

s_phi = -bx/g
print("Lagefehler phi = ", s_phi*180/pi, "deg")
s_theta = bz/g 
print("Lagefehler theta = ", s_theta*180/pi, "deg")
示例#30
0
 def test_getPosition(self):
     s = Strapdown()
     p1, p2, p3 = toValue(s.getPosition())
     self.assertEqual(p1, 0.)
     self.assertEqual(p2, 0.)
     self.assertEqual(p3, 0.)