Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5575c9ee4008
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ebf62c9481ca
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Aug 28, 2021

  1. Copy the full SHA
    62c5386 View commit details
  2. Merge pull request #3117 from pleroy/TrajectoryFactories4

    A new trajectory factory and a test cleanup
    pleroy authored Aug 28, 2021
    Copy the full SHA
    ebf62c9 View commit details
173 changes: 52 additions & 121 deletions ksp_plugin_test/renderer_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


#include "ksp_plugin/renderer.hpp"

#include "base/not_null.hpp"
@@ -18,6 +18,7 @@
#include "quantities/si.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/componentwise.hpp"
#include "testing_utilities/trajectory_factories.hpp"

namespace principia {
namespace ksp_plugin {
@@ -42,6 +43,7 @@ using quantities::si::Radian;
using quantities::si::Second;
using testing_utilities::AlmostEquals;
using testing_utilities::Componentwise;
using testing_utilities::NewLinearTrajectory;
using ::testing::Ref;
using ::testing::Return;
using ::testing::ReturnRef;
@@ -55,24 +57,6 @@ class RendererTest : public ::testing::Test {
std::make_unique<MockDynamicFrame<Barycentric, Navigation>>()),
dynamic_frame_(renderer_.GetPlottingFrame()) {}

// TODO(phl): There is a similar function in ContinuousTrajectoryTest and
// possibly in other places. It would be good to factor this out.
template<typename Frame>
void FillTrajectory(
Instant const& time,
Time const& step,
int const number_of_steps,
std::function<Position<Frame>(Instant const& t)> const& position_function,
std::function<Velocity<Frame>(Instant const& t)> const& velocity_function,
DiscreteTrajectory<Frame>& trajectory) {
for (int i = 0; i < number_of_steps; ++i) {
Instant const ti = time + i * step;
trajectory.Append(ti,
DegreesOfFreedom<Frame>(position_function(ti),
velocity_function(ti)));
}
}

Instant const t0_;
MockCelestial const celestial_;
Renderer renderer_;
@@ -87,18 +71,14 @@ TEST_F(RendererTest, TargetVessel) {
.WillRepeatedly(Return(&celestial_trajectory));

MockVessel vessel;
DiscreteTrajectory<Barycentric> vessel_trajectory;
FillTrajectory<Barycentric>(
/*time=*/t0_,
/*step=*/1 * Second,
/*number_of_steps=*/1,
/*position_function=*/
[](Instant const& t) { return Barycentric::origin; },
/*velocity_function=*/
[](Instant const& t) { return Barycentric::unmoving; },
vessel_trajectory);
auto const vessel_trajectory = NewLinearTrajectory(
/*v=*/Barycentric::unmoving,
/*Δt=*/1 * Second,
/*t1=*/t0_,
/*t2=*/t0_ + 1 * Second);

EXPECT_CALL(vessel, prediction())
.WillRepeatedly(ReturnRef(vessel_trajectory));
.WillRepeatedly(ReturnRef(*vessel_trajectory));

renderer_.SetTargetVessel(&vessel, &celestial_, &ephemeris);
EXPECT_TRUE(renderer_.HasTargetVessel());
@@ -114,24 +94,15 @@ TEST_F(RendererTest, TargetVessel) {
}

TEST_F(RendererTest, RenderBarycentricTrajectoryInPlottingWithoutTargetVessel) {
DiscreteTrajectory<Barycentric> trajectory_to_render;
FillTrajectory<Barycentric>(
/*time=*/t0_,
/*step=*/1 * Second,
/*number_of_steps=*/10,
/*position_function=*/
[this](Instant const& t) {
return Barycentric::origin +
(t - t0_) * Velocity<Barycentric>({6 * Metre / Second,
5 * Metre / Second,
4 * Metre / Second});
},
/*velocity_function=*/
[](Instant const& t) {
return Velocity<Barycentric>(
{6 * Metre / Second, 5 * Metre / Second, 4 * Metre / Second});
},
trajectory_to_render);
auto const vx = 6 * Metre / Second;
auto const vy = 5 * Metre / Second;
auto const vz = 4 * Metre / Second;
Velocity<Barycentric> const v({vx, vy, vz});
auto const trajectory_to_render = NewLinearTrajectory(
v,
/*Δt=*/1 * Second,
/*t1=*/t0_,
/*t2=*/t0_ + 10 * Second);

RigidMotion<Barycentric, Navigation> rigid_motion(
RigidTransformation<Barycentric, Navigation>::Identity(),
@@ -144,25 +115,21 @@ TEST_F(RendererTest, RenderBarycentricTrajectoryInPlottingWithoutTargetVessel) {

auto const rendered_trajectory =
renderer_.RenderBarycentricTrajectoryInPlotting(
trajectory_to_render.begin(),
trajectory_to_render.end());
trajectory_to_render->begin(),
trajectory_to_render->end());

EXPECT_EQ(10, rendered_trajectory->Size());
int index = 0;
for (auto const& [time, degrees_of_freedom] : *rendered_trajectory) {
EXPECT_EQ(t0_ + index * Second, time);
EXPECT_THAT(
degrees_of_freedom,
Componentwise(
AlmostEquals(Navigation::origin +
Displacement<Navigation>({6 * index * Metre,
5 * index * Metre,
4 * index * Metre}),
0),
AlmostEquals(Velocity<Navigation>({6 * Metre / Second,
5 * Metre / Second,
4 * Metre / Second}),
0)));
EXPECT_THAT(degrees_of_freedom,
Componentwise(
AlmostEquals(Navigation::origin + Displacement<Navigation>(
{vx * (time - t0_),
vy * (time - t0_),
vz * (time - t0_)}),
0),
AlmostEquals(Velocity<Navigation>({vx, vy, vz}), 0)));
++index;
}
}
@@ -173,47 +140,23 @@ TEST_F(RendererTest, RenderBarycentricTrajectoryInPlottingWithTargetVessel) {
EXPECT_CALL(ephemeris, trajectory(_))
.WillRepeatedly(Return(&celestial_trajectory));

DiscreteTrajectory<Barycentric> trajectory_to_render;
FillTrajectory<Barycentric>(
/*time=*/t0_,
/*step=*/1 * Second,
/*number_of_steps=*/10,
/*position_function=*/
[this](Instant const& t) {
return Barycentric::origin +
(t - t0_) * Velocity<Barycentric>({6 * Metre / Second,
5 * Metre / Second,
4 * Metre / Second});
},
/*velocity_function=*/
[](Instant const& t) {
return Velocity<Barycentric>(
{6 * Metre / Second, 5 * Metre / Second, 4 * Metre / Second});
},
trajectory_to_render);
auto const trajectory_to_render = NewLinearTrajectory(
/*v=*/Velocity<Barycentric>(
{6 * Metre / Second, 5 * Metre / Second, 4 * Metre / Second}),
/*Δt=*/1 * Second,
/*t1=*/t0_,
/*t2=*/t0_ + 10 * Second);

// The prediction is shorter than the |trajectory_to_render|.
MockVessel vessel;
DiscreteTrajectory<Barycentric> vessel_trajectory;
FillTrajectory<Barycentric>(
/*time=*/t0_ + 3 * Second,
/*step=*/1 * Second,
/*number_of_steps=*/5,
/*position_function=*/
[this](Instant const& t) {
return Barycentric::origin +
(t - t0_) * Velocity<Barycentric>({1 * Metre / Second,
2 * Metre / Second,
3 * Metre / Second});
},
/*velocity_function=*/
[](Instant const& t) {
return Velocity<Barycentric>(
{1 * Metre / Second, 2 * Metre / Second, 3 * Metre / Second});
},
vessel_trajectory);
auto const vessel_trajectory = NewLinearTrajectory(
/*v=*/Velocity<Barycentric>(
{1 * Metre / Second, 2 * Metre / Second, 3 * Metre / Second}),
/*Δt=*/1 * Second,
/*t1=*/t0_ + 3 * Second,
/*t2=*/t0_ + 8 * Second);
EXPECT_CALL(vessel, prediction())
.WillRepeatedly(ReturnRef(vessel_trajectory));
.WillRepeatedly(ReturnRef(*vessel_trajectory));

for (Instant t = t0_ + 3 * Second; t < t0_ + 8 * Second; t += 1 * Second) {
EXPECT_CALL(celestial_trajectory, EvaluateDegreesOfFreedom(t))
@@ -226,8 +169,8 @@ TEST_F(RendererTest, RenderBarycentricTrajectoryInPlottingWithTargetVessel) {
renderer_.SetTargetVessel(&vessel, &celestial_, &ephemeris);
auto const rendered_trajectory =
renderer_.RenderBarycentricTrajectoryInPlotting(
trajectory_to_render.begin(),
trajectory_to_render.end());
trajectory_to_render->begin(),
trajectory_to_render->end());

EXPECT_EQ(5, rendered_trajectory->Size());
int index = 3;
@@ -244,24 +187,12 @@ TEST_F(RendererTest, RenderBarycentricTrajectoryInPlottingWithTargetVessel) {
}

TEST_F(RendererTest, RenderPlottingTrajectoryInWorldWithoutTargetVessel) {
DiscreteTrajectory<Navigation> trajectory_to_render;
FillTrajectory<Navigation>(
/*time=*/t0_,
/*step=*/1 * Second,
/*number_of_steps=*/10,
/*position_function=*/
[this](Instant const& t) {
return Navigation::origin +
(t - t0_) * Velocity<Navigation>({6 * Metre / Second,
5 * Metre / Second,
4 * Metre / Second});
},
/*velocity_function=*/
[](Instant const& t) {
return Velocity<Navigation>(
{6 * Metre / Second, 5 * Metre / Second, 4 * Metre / Second});
},
trajectory_to_render);
auto const trajectory_to_render = NewLinearTrajectory(
/*v=*/Velocity<Navigation>(
{6 * Metre / Second, 5 * Metre / Second, 4 * Metre / Second}),
/*Δt=*/1 * Second,
/*t1=*/t0_,
/*t2=*/t0_ + 10 * Second);

Instant const rendering_time = t0_ + 5 * Second;
Position<World> const sun_world_position =
@@ -282,8 +213,8 @@ TEST_F(RendererTest, RenderPlottingTrajectoryInWorldWithoutTargetVessel) {

auto const rendered_trajectory =
renderer_.RenderPlottingTrajectoryInWorld(rendering_time,
trajectory_to_render.begin(),
trajectory_to_render.end(),
trajectory_to_render->begin(),
trajectory_to_render->end(),
sun_world_position,
planetarium_rotation);

11 changes: 11 additions & 0 deletions testing_utilities/trajectory_factories.hpp
Original file line number Diff line number Diff line change
@@ -14,11 +14,21 @@ namespace internal_trajectory_factories {

using base::not_null;
using geometry::Instant;
using geometry::Velocity;
using physics::DiscreteTrajectory;
using quantities::AngularFrequency;
using quantities::Length;
using quantities::Time;

// A linear trajectory with constant velocity, going through the origin at
// t = 0. The first point is at time |t1|, the last point at a time < |t2|.
template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>> NewLinearTrajectory(
Velocity<Frame> const& v,
Time const& Δt,
Instant const& t1,
Instant const& t2);

// A circular trajectory in the plane XY, centred at the origin. The first
// point is at time |t1|, the last point at a time < |t2|.
template<typename Frame>
@@ -44,6 +54,7 @@ void AppendTrajectory(DiscreteTrajectory<Frame> const& from,

using internal_trajectory_factories::AppendTrajectory;
using internal_trajectory_factories::NewCircularTrajectory;
using internal_trajectory_factories::NewLinearTrajectory;

} // namespace testing_utilities
} // namespace principia
15 changes: 15 additions & 0 deletions testing_utilities/trajectory_factories_body.hpp
Original file line number Diff line number Diff line change
@@ -19,6 +19,21 @@ using quantities::Sin;
using quantities::Speed;
using quantities::si::Radian;

template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>> NewLinearTrajectory(
Velocity<Frame> const& v,
Time const& Δt,
Instant const& t1,
Instant const& t2) {
static Instant const t0;
auto trajectory = make_not_null_unique<DiscreteTrajectory<Frame>>();
for (auto t = t1; t < t2; t += Δt) {
DegreesOfFreedom<Frame> const dof = {Frame::origin + v * (t - t0), v};
trajectory->Append(t, dof);
}
return std::move(trajectory);
}

template<typename Frame>
not_null<std::unique_ptr<DiscreteTrajectory<Frame>>> NewCircularTrajectory(
AngularFrequency const& ω,
26 changes: 26 additions & 0 deletions testing_utilities/trajectory_factories_test.cpp
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
#include "geometry/named_quantities.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/elementary_functions.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/vanishes_before.hpp"
@@ -21,6 +22,7 @@ using geometry::InnerProduct;
using geometry::Instant;
using geometry::Position;
using geometry::Velocity;
using quantities::Sqrt;
using quantities::si::Metre;
using quantities::si::Radian;
using quantities::si::Second;
@@ -33,6 +35,30 @@ class TrajectoryFactoriesTest : public ::testing::Test {
serialization::Frame::TEST>;
};

TEST_F(TrajectoryFactoriesTest, NewLinearTrajectory) {
auto const trajectory = NewLinearTrajectory<World>(
/*v=*/Velocity<World>(
{6 * Metre / Second, 5 * Metre / Second, 4 * Metre / Second}),
/*Δt=*/0.1 * Second,
/*t1=*/Instant() + 4 * Second,
/*t2=*/Instant() + 42 * Second);

for (auto const& [time, degrees_of_freedom] : *trajectory) {
Position<World> const& position = degrees_of_freedom.position();
Velocity<World> const& velocity = degrees_of_freedom.velocity();

EXPECT_THAT(
(position - World::origin).Norm(),
AlmostEquals((time - Instant()) * Sqrt(77) * Metre / Second, 0, 1));
EXPECT_THAT(velocity.Norm(), AlmostEquals(Sqrt(77) * Metre / Second, 0, 0));
}
EXPECT_THAT(trajectory->begin()->time,
AlmostEquals(Instant() + 4 * Second, 0));
EXPECT_THAT(trajectory->back().time,
AlmostEquals(Instant() + 41.9 * Second, 46));
EXPECT_EQ(380, trajectory->Size());
}

TEST_F(TrajectoryFactoriesTest, NewCircularTrajectory) {
auto const trajectory = NewCircularTrajectory<World>(
/*ω=*/3 * Radian / Second,