Exemple #1
0
// uses simple explicit euler integration
void RigidBody::integrate(float delta_time) {
	//printf("integrate %f\n", delta_time);
	float inv_mass = 1.0f/mass;

	position += delta_time * velocity;
	#if 0
	mat3 skew_mat = transpose(skewSymmetric(angular_velocity));
	orientation = orientation + delta_time * (skew_mat*orientation);
	orientation = orthoNormalize(orientation);
	#endif

	// integrate quaternion orientation
	quat spin = 0.5f * quaternion(0.0f, angular_velocity.x, angular_velocity.y, angular_velocity.z) * q_orientation;
	q_orientation += delta_time * spin;
	q_orientation = normalize(q_orientation);

	velocity += /*0.5f */ (delta_time*inv_mass) * force;
	angular_momentum += /*0.5f */ delta_time * torque;

	// compute auxiliaries
	#if 1
	orientation = m3(q_orientation);
	inv_world_inertia_mat = orientation * inv_inertia_mat * transpose(orientation);
	angular_velocity = inv_world_inertia_mat * angular_momentum;
	#else
	inv_world_inertia_mat = inv_inertia_mat;
	#endif

	angular_velocity = inv_world_inertia_mat * angular_momentum;

	force = v3(0.0f);
	torque = v3(0.0f);
}
//*************************************************************************
TEST (EssentialMatrixFactor, testData) {
    CHECK(readOK);

    // Check E matrix
    Matrix expected(3, 3);
    expected << 0, 0, 0, 0, 0, -0.1, 0.1, 0, 0;
    Matrix aEb_matrix = skewSymmetric(c1Tc2.x(), c1Tc2.y(), c1Tc2.z())
                        * c1Rc2.matrix();
    EXPECT(assert_equal(expected, aEb_matrix, 1e-8));

    // Check some projections
    EXPECT(assert_equal(Point2(0, 0), pA(0), 1e-8));
    EXPECT(assert_equal(Point2(0, 0.1), pB(0), 1e-8));
    EXPECT(assert_equal(Point2(0, -1), pA(4), 1e-8));
    EXPECT(assert_equal(Point2(-1, 0.2), pB(4), 1e-8));

    // Check homogeneous version
    EXPECT(assert_equal(Vector3(-1, 0.2, 1), vB(4), 1e-8));

    // Check epipolar constraint
    for (size_t i = 0; i < 5; i++)
        EXPECT_DOUBLES_EQUAL(0, vA(i).transpose() * aEb_matrix * vB(i), 1e-8);

    // Check epipolar constraint
    for (size_t i = 0; i < 5; i++)
        EXPECT_DOUBLES_EQUAL(0, trueE.error(vA(i), vB(i)), 1e-7);
}
Exemple #3
0
/*
 * @brief Convert a quaternion to the corresponding rotation matrix
 * @note Pay attention to the convention used. The function follows the
 *    conversion in "Indirect Kalman Filter for 3D Attitude Estimation:
 *    A Tutorial for Quaternion Algebra", Equation (78).
 *
 *    The input quaternion should be in the form
 *      [q1, q2, q3, q4(scalar)]^T
 */
inline Eigen::Matrix3d quaternionToRotation(
    const Eigen::Vector4d& q) {
  const Eigen::Vector3d& q_vec = q.block(0, 0, 3, 1);
  const double& q4 = q(3);
  Eigen::Matrix3d R =
    (2*q4*q4-1)*Eigen::Matrix3d::Identity() -
    2*q4*skewSymmetric(q_vec) +
    2*q_vec*q_vec.transpose();
  //TODO: Is it necessary to use the approximation equation
  //    (Equation (87)) when the rotation angle is small?
  return R;
}
//------------------------------------------------------------------------------
pair<Vector3, Vector3> PreintegrationBase::correctMeasurementsByBiasAndSensorPose(
    const Vector3& j_measuredAcc, const Vector3& j_measuredOmega,
    OptionalJacobian<3, 3> D_correctedAcc_measuredAcc,
    OptionalJacobian<3, 3> D_correctedAcc_measuredOmega,
    OptionalJacobian<3, 3> D_correctedOmega_measuredOmega) const {

  // Correct for bias in the sensor frame
  Vector3 j_correctedAcc = biasHat_.correctAccelerometer(j_measuredAcc);
  Vector3 j_correctedOmega = biasHat_.correctGyroscope(j_measuredOmega);

  // Compensate for sensor-body displacement if needed: we express the quantities
  // (originally in the IMU frame) into the body frame
  // Equations below assume the "body" frame is the CG
  if (p().body_P_sensor) {
    // Correct omega to rotation rate vector in the body frame
    const Matrix3 bRs = p().body_P_sensor->rotation().matrix();
    j_correctedOmega = bRs * j_correctedOmega;

    // Correct acceleration
    j_correctedAcc = bRs * j_correctedAcc;

    // Jacobians
    if (D_correctedAcc_measuredAcc) *D_correctedAcc_measuredAcc = bRs;
    if (D_correctedAcc_measuredOmega) *D_correctedAcc_measuredOmega = Matrix3::Zero();
    if (D_correctedOmega_measuredOmega) *D_correctedOmega_measuredOmega = bRs;

    // Centrifugal acceleration
    const Vector3 b_arm = p().body_P_sensor->translation().vector();
    if (!b_arm.isZero()) {
      // Subtract out the the centripetal acceleration from the measured one
      // to get linear acceleration vector in the body frame:
      const Matrix3 body_Omega_body = skewSymmetric(j_correctedOmega);
      const Vector3 b_velocity_bs = body_Omega_body * b_arm; // magnitude: omega * arm
      j_correctedAcc -= body_Omega_body * b_velocity_bs;
      // Update derivative: centrifugal causes the correlation between acc and omega!!!
      if (D_correctedAcc_measuredOmega) {
        double wdp = j_correctedOmega.dot(b_arm);
        *D_correctedAcc_measuredOmega = -(diag(Vector3::Constant(wdp))
            + j_correctedOmega * b_arm.transpose()) * bRs.matrix()
            + 2 * b_arm * j_measuredOmega.transpose();
      }
    }
  }

  // Do update in one fell swoop
  return make_pair(j_correctedAcc, j_correctedOmega);
}
Exemple #5
0
/* ************************************************************************* */
Matrix3 Unit3::skew() const {
    return skewSymmetric(p_.x(), p_.y(), p_.z());
}
Exemple #6
0
/* ************************************************************************* */
Point3 Rot3::rotate(const Point3& p,
    OptionalJacobian<3,3> H1,  OptionalJacobian<3,3> H2) const {
  if (H1) *H1 = rot_ * skewSymmetric(-p.x(), -p.y(), -p.z());
  if (H2) *H2 = rot_;
  return Point3(rot_ * p.vector());
}