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: 6c7b95159832
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a74810d78788
Choose a head ref
  • 6 commits
  • 9 files changed
  • 1 contributor

Commits on Sep 18, 2017

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    09a8d58 View commit details
  2. Preserve UpdatePrediction.

    pleroy committed Sep 18, 2017
    Copy the full SHA
    4d940ab View commit details

Commits on Sep 19, 2017

  1. Fix a bug in Forkable::Size.

    pleroy committed Sep 19, 2017
    Copy the full SHA
    9af61df View commit details

Commits on Sep 20, 2017

  1. Proper mocking.

    pleroy committed Sep 20, 2017
    Copy the full SHA
    a548d22 View commit details

Commits on Sep 21, 2017

  1. Copy the full SHA
    62b98b7 View commit details
  2. Merge pull request #1569 from pleroy/ForkedPrediction

    Fork the prediction at the end of the psychohistory
    pleroy authored Sep 21, 2017
    Copy the full SHA
    a74810d View commit details
2 changes: 1 addition & 1 deletion ksp_plugin/plugin.cpp
Original file line number Diff line number Diff line change
@@ -699,7 +699,7 @@ void Plugin::SetPredictionAdaptiveStepParameters(

void Plugin::UpdatePrediction(GUID const& vessel_guid) const {
CHECK(!initializing_);
FindOrDie(vessels_, vessel_guid)->UpdatePrediction(InfiniteFuture);
FindOrDie(vessels_, vessel_guid)->FlowPrediction(InfiniteFuture);
}

void Plugin::CreateFlightPlan(GUID const& vessel_guid,
4 changes: 2 additions & 2 deletions ksp_plugin/renderer.cpp
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ Vessel const& Renderer::GetTargetVessel() const {
DiscreteTrajectory<Barycentric> const& Renderer::GetTargetVesselPrediction(
Instant const& time) const {
CHECK(target_);
target_->vessel->UpdatePrediction(time);
target_->vessel->FlowPrediction(time);
// The prediction may not have been prolonged to |time| if we are near a
// singularity.
CHECK_LE(time, target_->vessel->prediction().last().time());
@@ -109,7 +109,7 @@ Renderer::RenderBarycentricTrajectoryInPlotting(
if (target_ && begin != end) {
auto last = end;
--last;
target_->vessel->UpdatePrediction(last.time());
target_->vessel->FlowPrediction(last.time());
}
for (auto it = begin; it != end; ++it) {
Instant const& t = it.time();
99 changes: 46 additions & 53 deletions ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
#include <string>
#include <vector>

#include "astronomy/epoch.hpp"
#include "ksp_plugin/integrators.hpp"
#include "ksp_plugin/pile_up.hpp"
#include "quantities/si.hpp"
@@ -16,6 +17,7 @@ namespace principia {
namespace ksp_plugin {
namespace internal_vessel {

using astronomy::InfiniteFuture;
using base::Contains;
using base::FindOrDie;
using base::make_not_null_unique;
@@ -36,9 +38,9 @@ Vessel::Vessel(GUID const& guid,
prediction_adaptive_step_parameters_(prediction_adaptive_step_parameters),
parent_(parent),
ephemeris_(ephemeris),
history_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
prediction_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {
// Can't create the |psychohistory_| here because |history_| is empty;
history_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {
// Can't create the |psychohistory_| and |prediction_| here because |history_|
// is empty;
}

Vessel::~Vessel() {
@@ -141,6 +143,7 @@ void Vessel::PrepareHistory(Instant const& t) {
CHECK(psychohistory_ == nullptr);
history_->Append(t, calculator.Get());
psychohistory_ = history_->NewForkAtLast();
prediction_ = psychohistory_->NewForkAtLast();
}
}

@@ -192,6 +195,8 @@ void Vessel::AdvanceTime() {
AppendToVesselTrajectory(&Part::psychohistory_begin,
&Part::psychohistory_end,
*psychohistory_);
prediction_ = psychohistory_->NewForkAtLast();

for (auto const& pair : parts_) {
Part& part = *pair.second;
part.ClearHistory();
@@ -200,10 +205,9 @@ void Vessel::AdvanceTime() {

void Vessel::ForgetBefore(Instant const& time) {
// Make sure that the history keeps at least one (authoritative) point and
// don't change the psychohistory. We cannot use the parts because they may
// have been moved to the future already.
// don't change the psychohistory or prediction. We cannot use the parts
// because they may have been moved to the future already.
history_->ForgetBefore(std::min(time, history_->last().time()));
prediction_->ForgetBefore(time);
if (flight_plan_ != nullptr) {
flight_plan_->ForgetBefore(time, [this]() { flight_plan_.reset(); });
}
@@ -228,19 +232,30 @@ void Vessel::DeleteFlightPlan() {
flight_plan_.reset();
}

void Vessel::UpdatePrediction(Instant const& last_time) {
// TODO(phl): The prediction should probably be a fork of the psychohistory.
auto const psychohistory_last = psychohistory_->last();
auto const prediction_begin = prediction_->Begin();
if (prediction_->Empty() ||
prediction_begin.time() != psychohistory_last.time() ||
prediction_begin.degrees_of_freedom() !=
psychohistory_last.degrees_of_freedom()) {
prediction_ = make_not_null_unique<DiscreteTrajectory<Barycentric>>();
prediction_->Append(psychohistory_last.time(),
psychohistory_last.degrees_of_freedom());
void Vessel::FlowPrediction(Instant const& time) {
if (time > prediction_->last().time()) {
bool const finite_time = IsFinite(time - prediction_->last().time());
Instant const t = finite_time ? time : ephemeris_->t_max();
// This will not prolong the ephemeris if |time| is infinite (but it may do
// so if it is finite).
bool const reached_t = ephemeris_->FlowWithAdaptiveStep(
prediction_,
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
t,
prediction_adaptive_step_parameters_,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
if (!finite_time && reached_t) {
// This will prolong the ephemeris by |max_ephemeris_steps_per_frame|.
ephemeris_->FlowWithAdaptiveStep(
prediction_,
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
time,
prediction_adaptive_step_parameters_,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
}
}
FlowPrediction(last_time);
}

DiscreteTrajectory<Barycentric> const& Vessel::psychohistory() const {
@@ -263,9 +278,7 @@ void Vessel::WriteToMessage(
message->add_kept_parts(part_id);
}
history_->WriteToMessage(message->mutable_history(),
/*forks=*/{psychohistory_});
prediction_->WriteToMessage(message->mutable_prediction(),
/*forks=*/{});
/*forks=*/{psychohistory_, prediction_});
if (flight_plan_ != nullptr) {
flight_plan_->WriteToMessage(message->mutable_flight_plan());
}
@@ -277,6 +290,8 @@ not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
not_null<Ephemeris<Barycentric>*> const ephemeris,
std::function<void(PartId)> const& deletion_callback) {
bool const is_pre_cesàro = message.has_psychohistory_is_authoritative();
bool const is_pre_chasles = message.has_prediction();

// NOTE(egg): for now we do not read the |MasslessBody| as it can contain no
// information.
auto vessel = make_not_null_unique<Vessel>(
@@ -319,15 +334,20 @@ not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
if (message.psychohistory_is_authoritative()) {
vessel->psychohistory_ = vessel->history_->NewForkAtLast();
}
} else {
vessel->prediction_ = vessel->psychohistory_->NewForkAtLast();
vessel->FlowPrediction(InfiniteFuture);
} else if (is_pre_chasles) {
vessel->history_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{&vessel->psychohistory_});
vessel->prediction_ = vessel->psychohistory_->NewForkAtLast();
vessel->FlowPrediction(InfiniteFuture);
} else {
vessel->history_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
message.history(),
/*forks=*/{&vessel->psychohistory_, &vessel->prediction_});
}

vessel->prediction_ =
DiscreteTrajectory<Barycentric>::ReadFromMessage(message.prediction(),
/*forks=*/{});
if (message.has_flight_plan()) {
vessel->flight_plan_ = FlightPlan::ReadFromMessage(message.flight_plan(),
ephemeris);
@@ -353,8 +373,7 @@ Vessel::Vessel()
prediction_adaptive_step_parameters_(DefaultPredictionParameters()),
parent_(testing_utilities::make_not_null<Celestial const*>()),
ephemeris_(testing_utilities::make_not_null<Ephemeris<Barycentric>*>()),
history_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
prediction_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}
history_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

void Vessel::AppendToVesselTrajectory(
TrajectoryIterator const part_trajectory_begin,
@@ -404,32 +423,6 @@ void Vessel::AppendToVesselTrajectory(
}
}

void Vessel::FlowPrediction(Instant const& time) {
if (time > prediction_->last().time()) {
bool const finite_time = IsFinite(time - prediction_->last().time());
Instant const t = finite_time ? time : ephemeris_->t_max();
// This will not prolong the ephemeris if |time| is infinite (but it may do
// so if it is finite).
bool const reached_t = ephemeris_->FlowWithAdaptiveStep(
prediction_.get(),
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
t,
prediction_adaptive_step_parameters_,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
if (!finite_time && reached_t) {
// This will prolong the ephemeris by |max_ephemeris_steps_per_frame|.
ephemeris_->FlowWithAdaptiveStep(
prediction_.get(),
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
time,
prediction_adaptive_step_parameters_,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
}
}
}

} // namespace internal_vessel
} // namespace ksp_plugin
} // namespace principia
9 changes: 5 additions & 4 deletions ksp_plugin/vessel.hpp
Original file line number Diff line number Diff line change
@@ -138,7 +138,9 @@ class Vessel {
// Deletes the |flight_plan_|. Performs no action unless |has_flight_plan()|.
virtual void DeleteFlightPlan();

virtual void UpdatePrediction(Instant const& last_time);
// Tries to extend the prediction up to and including |last_time|. May not be
// able to do it next to a singularity.
virtual void FlowPrediction(Instant const& last_time);

virtual DiscreteTrajectory<Barycentric> const& psychohistory() const;

@@ -168,8 +170,6 @@ class Vessel {
TrajectoryIterator part_trajectory_end,
DiscreteTrajectory<Barycentric>& trajectory);

void FlowPrediction(Instant const& time);

GUID const guid_;
std::string name_;

@@ -187,7 +187,8 @@ class Vessel {
not_null<std::unique_ptr<DiscreteTrajectory<Barycentric>>> history_;
DiscreteTrajectory<Barycentric>* psychohistory_ = nullptr;

not_null<std::unique_ptr<DiscreteTrajectory<Barycentric>>> prediction_;
// The |prediction_| is forked off the end of the |psychohistory_|.
DiscreteTrajectory<Barycentric>* prediction_ = nullptr;

std::unique_ptr<FlightPlan> flight_plan_;
};
2 changes: 1 addition & 1 deletion ksp_plugin_test/mock_vessel.hpp
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ class MockVessel : public Vessel {

MOCK_METHOD0(DeleteFlightPlan, void());

MOCK_METHOD1(UpdatePrediction, void(Instant const& last_time));
MOCK_METHOD1(FlowPrediction, void(Instant const& last_time));

MOCK_CONST_METHOD0(psychohistory, DiscreteTrajectory<Barycentric> const&());
MOCK_CONST_METHOD0(psychohistory_is_authoritative, bool());
4 changes: 2 additions & 2 deletions ksp_plugin_test/vessel_test.cpp
Original file line number Diff line number Diff line change
@@ -227,7 +227,7 @@ TEST_F(VesselTest, Prediction) {
50.0 * Metre / Second,
40.0 * Metre / Second}))),
Return(true)));
vessel_.UpdatePrediction(astronomy::J2000 + 1 * Second);
vessel_.FlowPrediction(astronomy::J2000 + 1 * Second);

EXPECT_EQ(2, vessel_.prediction().Size());
auto it = vessel_.prediction().Begin();
@@ -293,7 +293,7 @@ TEST_F(VesselTest, PredictBeyondTheInfinite) {
60.0 * Metre / Second,
50.0 * Metre / Second}))),
Return(true)));
vessel_.UpdatePrediction(astronomy::InfiniteFuture);
vessel_.FlowPrediction(astronomy::InfiniteFuture);

EXPECT_EQ(3, vessel_.prediction().Size());
auto it = vessel_.prediction().Begin();
8 changes: 5 additions & 3 deletions physics/forkable_body.hpp
Original file line number Diff line number Diff line change
@@ -296,8 +296,10 @@ std::int64_t Forkable<Tr4jectory, It3rator>::Size() const {
// Go up the ancestry chain adding the sizes.
Tr4jectory const* parent = ancestor->parent_;
while (parent != nullptr) {
size += std::distance(parent->timeline_begin(),
*ancestor->position_in_parent_timeline_) + 1;
if (!parent->timeline_empty()) {
size += std::distance(parent->timeline_begin(),
*ancestor->position_in_parent_timeline_) + 1;
}
ancestor = parent;
parent = ancestor->parent_;
}
@@ -307,7 +309,7 @@ std::int64_t Forkable<Tr4jectory, It3rator>::Size() const {

template<typename Tr4jectory, typename It3rator>
bool Forkable<Tr4jectory, It3rator>::Empty() const {
// If this object has an ancestor surely it is hook off of a point in some
// If this object has an ancestor surely it is hooked off of a point in some
// timeline, so this object is not empty.
return timeline_empty() && parent_ == nullptr;
}
12 changes: 12 additions & 0 deletions physics/forkable_test.cpp
Original file line number Diff line number Diff line change
@@ -229,6 +229,18 @@ TEST_F(ForkableTest, ForkSuccess) {
EXPECT_THAT(times, ElementsAre(t1_, t2_, t4_));
}

TEST_F(ForkableTest, Size) {
EXPECT_TRUE(trajectory_.Empty());
trajectory_.push_back(t1_);
EXPECT_EQ(1, trajectory_.Size());
not_null<FakeTrajectory*> const fork1 =
trajectory_.NewFork(trajectory_.timeline_find(t1_));
EXPECT_EQ(1, fork1->Size());
not_null<FakeTrajectory*> const fork2 = fork1->NewFork(fork1->timeline_end());
fork2->push_back(t2_);
EXPECT_EQ(2, fork2->Size());
}

TEST_F(ForkableTest, ForkAtLast) {
trajectory_.push_back(t1_);
trajectory_.push_back(t2_);
2 changes: 1 addition & 1 deletion serialization/ksp_plugin.proto
Original file line number Diff line number Diff line change
@@ -134,7 +134,7 @@ message Vessel {
repeated fixed32 kept_parts = 15;
required DiscreteTrajectory history = 16;
optional bool psychohistory_is_authoritative = 17; // Pre-Cesàro.
required DiscreteTrajectory prediction = 18;
optional DiscreteTrajectory prediction = 18; // Pre-Chasles.
optional FlightPlan flight_plan = 4;

// Pre-Буняковский.