Esempio n. 1
0
void generateDisplacement(Rate rate, Quaternion *q) {
    
    float norm, sina_2;
    bams32_t a_2;
    
    norm = sqrtf(   rate->yaw_rate*rate->yaw_rate +
                    rate->pitch_rate*rate->pitch_rate +
                    rate->roll_rate*rate->roll_rate   );

    if(norm == 0.0) {
        q->w = 1.0;
        q->x = 0.0;
        q->y = 0.0;
        q->z = 0.0;
    } else {
        a_2 = floatToBams32Rad(norm*period)/2;
        sina_2 = bams32SinFine(a_2);

        q->w = bams32CosFine(a_2)*norm;
        q->x = sina_2*rate->roll_rate;
        q->y = sina_2*rate->pitch_rate;
        q->z = sina_2*rate->yaw_rate;
    }
    quatNormalize(q);    
    
}
Esempio n. 2
0
// 12000 cycles?
void attEstimatePose(void) {

    Quaternion displacement_quat;
    float rate[3], norm, sina_2;
    bams32_t a_2;

    if(!is_ready) { return; }
    if(!is_running) { return; }

    gyroGetRadXYZ(rate); // Get last read gyro values
    timestamp = swatchToc(); // Record timestamp

    // Calculate magnitude and disiplacement
    norm = sqrtf(rate[0]*rate[0] + rate[1]*rate[1] + rate[2]*rate[2]);

    // Special case when no movement occurs due to simplification below
    if(norm == 0.0) {

        displacement_quat.w = 1.0;
        displacement_quat.x = 0.0;
        displacement_quat.y = 0.0;
        displacement_quat.z = 0.0;

    } else {

        // Generate displacement rotation quaternion
        // Normally this is w = cos(a/2), but we can delay normalizing
        // by multiplying all terms by norm
        a_2 = floatToBams32Rad(norm*sample_period)/2;
        sina_2 = bams32SinFine(a_2);

        displacement_quat.w = bams32CosFine(a_2)*norm;
        displacement_quat.x = sina_2*rate[0];
        displacement_quat.y = sina_2*rate[1];
        displacement_quat.z = sina_2*rate[2];
        quatNormalize(&displacement_quat);
    }

    // Apply displacement to pose
    quatMult(&pose_quat, &displacement_quat, &pose_quat);

    // Normalize pose quaternion to account for unnormalized displacement quaternion
    quatNormalize(&pose_quat);
    calculateEulerAngles();

}
Esempio n. 3
0
void rateApplyLocalRotation(Quaternion *rot) {

    Quaternion current_ref;
    
    rgltrGetQuatRef(&current_ref);
    quatMult(&current_ref, rot, &current_ref);
    quatNormalize(&current_ref);
    rgltrSetQuatRef(&current_ref);

}
Esempio n. 4
0
void rateProcess(void) {

    Quaternion current_ref;

    if(!is_ready || !is_running) { return; }
    
    rgltrGetQuatRef(&current_ref);    

    // q_body*q_current*q_global    
    quatMult(&global_displacement, &current_ref, &current_ref);
    quatMult(&current_ref, &body_displacement, &current_ref);

    quatNormalize(&current_ref);

    rgltrSetQuatRef(&current_ref);

}
Esempio n. 5
0
// qtarget = qcurr*qdisp
// qcurr'*qtarget = qdisp
void slewProcess(Quaternion *input, Quaternion *output) {

    Quaternion conjugate, displacement;
    bams32_t input_angle, limited_angle;
    float sin_input, sin_limited, scale;

    if(!is_ready || !is_running || max_angular_displacement == 0) {
        quatCopy(output, input);
        return;
    }

    // Calculate displacement
    quatConj(&prev_ref, &conjugate);
    quatMult(&conjugate, input, &displacement);

    // Calculate displacement magnitude
    input_angle = bams16ToBams32(bams16Acos(displacement.w)*2);
    if(input_angle == 0) { // Check for no displacement case
        quatCopy(output, input);
        return;
    }
    sin_input = bams32Sin(input_angle/2);

    // Apply displacement limits
    if(input_angle > max_angular_displacement) {
        limited_angle = max_angular_displacement;
    } else if(input_angle < -max_angular_displacement) {
        limited_angle = -max_angular_displacement;
    } else {
        limited_angle = input_angle;
    }

    sin_limited = bams32SinFine(limited_angle/2);
    scale = sin_limited/sin_input;

    displacement.w = bams32CosFine(limited_angle/2);
    displacement.x = displacement.x*scale;
    displacement.y = displacement.y*scale;
    displacement.z = displacement.z*scale;

    // Apply limited displacement
    quatMult(&prev_ref, &displacement, output);
    quatNormalize(output);
    quatCopy(&prev_ref, output);

}
Esempio n. 6
0
void attZero(void) {

    float gxy, sina_2, xl[3], temp;
    bams16_t a_2;

    xlGetFloatXYZ(xl);

    // Convert frames so that z axis is oriented upwards, x is forward, y is side
    xl[2] = -xl[2];
    temp = xl[0];
    xl[0] = -xl[1];
    xl[1] = temp;

    gxy = sqrtf(xl[0]*xl[0] + xl[1]*xl[1]);
    a_2 = (BAMS16_PI_2 + bams16Atan2(xl[2], gxy))/2;
    sina_2 = bams16SinFine(a_2);

    pose_quat.w = bams16CosFine(a_2)*gxy;
    pose_quat.x = sina_2*(-xl[1]);
    pose_quat.y = sina_2*(xl[0]);
    pose_quat.z = 0.0;
    quatNormalize(&pose_quat);

}
Esempio n. 7
0
static void
check_quaternion(generator_t &gen, distribution_t &dist)
{
  // check identity
  {
    quat      q;
    glm::quat g;

    quatIdentity(&q);
    assert(q == g);
  }

  for(size_t x = 0; x < 10000; ++x)
  {
    // check negation
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      assert(quatNegate(q) == -g);
    }

    // check addition
    {
      quat      q1 = randomQuat(gen, dist);
      quat      q2 = randomQuat(gen, dist);

      glm::quat g1 = loadQuat(q1);
      glm::quat g2 = loadQuat(q2);

      assert(quatAdd(q1, q2) == g1+g2);
    }

    // check subtraction
    {
      quat      q1 = randomQuat(gen, dist);
      quat      q2 = randomQuat(gen, dist);

      glm::quat g1 = loadQuat(q1);
      glm::quat g2 = loadQuat(q2);

      assert(quatSubtract(q1, q2) == g1 + (-g2));
    }

    // check scale
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      float f = dist(gen);

      assert(quatScale(q, f) == g*f);
    }

    // check normalize
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      assert(quatNormalize(q) == glm::normalize(g));
    }

    // check dot
    {
      quat      q1 = randomQuat(gen, dist);
      quat      q2 = randomQuat(gen, dist);
      glm::quat g1 = loadQuat(q1);
      glm::quat g2 = loadQuat(q2);

      assert(std::abs(quatDot(q1, q2) - glm::dot(g1, g2)) < 0.0001f);
    }

    // check conjugate
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      assert(quatConjugate(q) == glm::conjugate(g));
    }

    // check inverse
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      assert(quatInverse(q) == glm::inverse(g));
    }

    // check quaternion multiplication
    {
      quat      q1 = randomQuat(gen, dist);
      quat      q2 = randomQuat(gen, dist);
      glm::quat g1 = loadQuat(q1);
      glm::quat g2 = loadQuat(q2);

      assert(quatMultiply(q1, q2) == g1*g2);
    }

    // check vector multiplication
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      glm::vec3 v = randomVector(gen, dist);

      assert(quatMultiplyVec3f(q, (vec3f){ v.x, v.y, v.z }) == g*v);
    }

    // check rotation
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      glm::vec3 v = randomVector(gen, dist);
      float     r = randomAngle(gen, dist);

      assert(quatRotate(q, (vec3f){ v.x, v.y, v.z }, r) == glm::rotate(g, r, v));
    }

    // check rotate X
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      float     r = randomAngle(gen, dist);

      assert(quatRotateX(q, r) == glm::rotate(g, r, x_axis));
    }

    // check rotate Y
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      float     r = randomAngle(gen, dist);

      assert(quatRotateY(q, r) == glm::rotate(g, r, y_axis));
    }

    // check rotate Z
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      float     r = randomAngle(gen, dist);

      assert(quatRotateZ(q, r) == glm::rotate(g, r, z_axis));
    }

    // check conversion from matrix
    {
      quat      q = randomQuat(gen, dist);
      glm::quat g = loadQuat(q);

      mtx44 m;
      quatToMtx44(&m, q);

      assert(m == glm::mat4_cast(g));
    }
  }
}