Пример #1
0
Vector<Acceleration, Frame> Ephemeris<Frame>::
ComputeGravitationalAccelerationOnMasslessBody(
    not_null<DiscreteTrajectory<Frame>*> const trajectory,
    Instant const& t) const {
  auto const it = trajectory->Find(t);
  DegreesOfFreedom<Frame> const& degrees_of_freedom = it.degrees_of_freedom();
  return ComputeGravitationalAccelerationOnMasslessBody(
             degrees_of_freedom.position(), t);
}
// A linear acceleration identical for both bodies.  The test point doesn't
// move.  The resulting acceleration combines centrifugal and linear.
TEST_F(BodySurfaceDynamicFrameTest, LinearAcceleration) {
  Instant const t = t0_ + 0 * Second;
  DegreesOfFreedom<MockFrame> const point_dof =
      {Displacement<MockFrame>({10 * Metre, 20 * Metre, 30 * Metre}) +
           MockFrame::origin,
       Velocity<MockFrame>({0 * Metre / Second,
                            0 * Metre / Second,
                            0 * Metre / Second})};
  DegreesOfFreedom<ICRFJ2000Equator> const centre_dof =
      {Displacement<ICRFJ2000Equator>({0 * Metre, 0 * Metre, 0 * Metre}) +
           ICRFJ2000Equator::origin,
       Velocity<ICRFJ2000Equator>({0 * Metre / Second,
                                   0 * Metre / Second,
                                   0 * Metre / Second})};

  EXPECT_CALL(mock_centre_trajectory_, EvaluateDegreesOfFreedom(t, _))
      .Times(2)
      .WillRepeatedly(Return(centre_dof));
  {
    // The acceleration is linear + centripetal.
    InSequence s;
    EXPECT_CALL(*mock_ephemeris_,
                ComputeGravitationalAccelerationOnMassiveBody(
                    check_not_null(massive_centre_), t))
        .WillOnce(Return(Vector<Acceleration, ICRFJ2000Equator>({
                             -160 * Metre / Pow<2>(Second),
                             120 * Metre / Pow<2>(Second),
                             300 * Metre / Pow<2>(Second)})));
    EXPECT_CALL(*mock_ephemeris_,
                ComputeGravitationalAccelerationOnMasslessBody(_, t))
        .WillOnce(Return(Vector<Acceleration, ICRFJ2000Equator>()));
  }

  // The acceleration is linear + centrifugal.
  EXPECT_THAT(mock_frame_->GeometricAcceleration(t, point_dof),
              AlmostEquals(Vector<Acceleration, MockFrame>({
                               (-120 + 1e3) * Metre / Pow<2>(Second),
                               (-160 + 2e3) * Metre / Pow<2>(Second),
                               -300 * Metre / Pow<2>(Second)}), 2));
}
// The test point is at the origin and in motion.  The acceleration is purely
// due to Coriolis.
TEST_F(BodySurfaceDynamicFrameTest, CoriolisAcceleration) {
  Instant const t = t0_ + 0 * Second;
  // The velocity is opposed to the motion and away from the centre.
  DegreesOfFreedom<MockFrame> const point_dof =
      {Displacement<MockFrame>({0 * Metre, 0 * Metre, 0 * Metre}) +
           MockFrame::origin,
       Velocity<MockFrame>({10 * Metre / Second,
                            20 * Metre / Second,
                            30 * Metre / Second})};
  DegreesOfFreedom<ICRFJ2000Equator> const centre_dof =
      {Displacement<ICRFJ2000Equator>({0 * Metre, 0 * Metre, 0 * Metre}) +
           ICRFJ2000Equator::origin,
       Velocity<ICRFJ2000Equator>()};

  EXPECT_CALL(mock_centre_trajectory_, EvaluateDegreesOfFreedom(t, _))
      .Times(2)
      .WillRepeatedly(Return(centre_dof));
  {
    InSequence s;
    EXPECT_CALL(*mock_ephemeris_,
                ComputeGravitationalAccelerationOnMassiveBody(
                    check_not_null(massive_centre_), t))
        .WillOnce(Return(Vector<Acceleration, ICRFJ2000Equator>({
                             0 * Metre / Pow<2>(Second),
                             0 * Metre / Pow<2>(Second),
                             0 * Metre / Pow<2>(Second)})));
    EXPECT_CALL(*mock_ephemeris_,
                ComputeGravitationalAccelerationOnMasslessBody(_, t))
        .WillOnce(Return(Vector<Acceleration, ICRFJ2000Equator>()));
  }

  // The Coriolis acceleration is towards the centre and opposed to the motion.
  EXPECT_THAT(mock_frame_->GeometricAcceleration(t, point_dof).coordinates(),
              Componentwise(AlmostEquals(400 * Metre / Pow<2>(Second), 1),
                            AlmostEquals(-200 * Metre / Pow<2>(Second), 0),
                            VanishesBefore(1 * Metre / Pow<2>(Second), 110)));
}