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: 619a8237818c
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 41926f3e2936
Choose a head ref

Commits on Feb 2, 2019

  1. Fix comments in Vessel.

    pleroy committed Feb 2, 2019
    Copy the full SHA
    f6b19e5 View commit details
  2. Split FlowPrediction.

    pleroy committed Feb 2, 2019
    Copy the full SHA
    f3a8005 View commit details
  3. Copy the full SHA
    ffa7234 View commit details

Commits on Feb 3, 2019

  1. Copy the full SHA
    5862347 View commit details
  2. Copy the full SHA
    56fdbe6 View commit details
  3. Copy the full SHA
    e6b0955 View commit details
  4. First run of the predictor.

    pleroy committed Feb 3, 2019
    Copy the full SHA
    76af579 View commit details
  5. Shutdown.

    pleroy committed Feb 3, 2019
    Copy the full SHA
    66005be View commit details
  6. Copy the full SHA
    1f220dd View commit details
  7. Copy the full SHA
    f153063 View commit details
  8. Trajectory cleanup.

    pleroy committed Feb 3, 2019
    Copy the full SHA
    3d9494e View commit details
  9. Psychohistory locking.

    pleroy committed Feb 3, 2019
    Copy the full SHA
    d3d2186 View commit details

Commits on Feb 8, 2019

  1. Copy the full SHA
    1645a8f View commit details

Commits on Feb 9, 2019

  1. Copy the full SHA
    2467b46 View commit details
  2. Copy the full SHA
    e7b8c20 View commit details
  3. Copy the full SHA
    2412d4c View commit details
  4. Copy the full SHA
    3c51bb8 View commit details
  5. Prognostication.

    pleroy committed Feb 9, 2019
    Copy the full SHA
    050189c View commit details
  6. Fix some crashes.

    pleroy committed Feb 9, 2019
    Copy the full SHA
    5d62a21 View commit details
  7. Copy the full SHA
    cee2ef1 View commit details
  8. Copy the full SHA
    8885950 View commit details
  9. Vessel tests passing.

    pleroy committed Feb 9, 2019
    Copy the full SHA
    29e178d View commit details
  10. Fix a test.

    pleroy committed Feb 9, 2019
    Copy the full SHA
    803e67f View commit details
  11. All tests passing.

    pleroy committed Feb 9, 2019
    Copy the full SHA
    db85600 View commit details

Commits on Feb 10, 2019

  1. Cleanup.

    pleroy committed Feb 10, 2019
    Copy the full SHA
    f0a59e3 View commit details
  2. Copy the full SHA
    8f9d377 View commit details
  3. Cleanup.

    pleroy committed Feb 10, 2019
    Copy the full SHA
    575bbd3 View commit details
  4. Copy the full SHA
    564eff0 View commit details
  5. Copy the full SHA
    f1500bc View commit details
  6. Copy the full SHA
    8cd0456 View commit details

Commits on Feb 11, 2019

  1. Copy the full SHA
    46dc24b View commit details

Commits on Feb 16, 2019

  1. Merge.

    pleroy committed Feb 16, 2019
    Copy the full SHA
    caa264d View commit details
  2. Copy the full SHA
    59efa2b View commit details
  3. Copy the full SHA
    5336aea View commit details
  4. Copy the full SHA
    b87c855 View commit details
  5. Copy the full SHA
    b29b863 View commit details
  6. Copy the full SHA
    0a6514f View commit details
  7. Start the prognosticator on-demand when flowing the prediction. Skip …

    …the computation if the parameters have not changed.
    pleroy committed Feb 16, 2019
    Copy the full SHA
    4077a3b View commit details

Commits on Feb 17, 2019

  1. Add a missing lock.

    pleroy committed Feb 17, 2019
    Copy the full SHA
    2c32af9 View commit details
  2. Fix status.

    pleroy committed Feb 17, 2019
    Copy the full SHA
    67feeea View commit details
  3. Copy the full SHA
    764c657 View commit details
  4. Remove traces.

    pleroy committed Feb 17, 2019
    Copy the full SHA
    4c345bb View commit details

Commits on Feb 19, 2019

  1. Copy the full SHA
    0b390e7 View commit details
  2. Merge.

    pleroy committed Feb 19, 2019
    Copy the full SHA
    45386ef View commit details

Commits on Mar 7, 2019

  1. Copy the full SHA
    ba1a514 View commit details
  2. New compiler, same old bugs.

    pleroy committed Mar 7, 2019
    Copy the full SHA
    76fcdb5 View commit details

Commits on Mar 8, 2019

  1. Copy the full SHA
    e2f85ac View commit details
  2. Copy the full SHA
    064820f View commit details
  3. Copy the full SHA
    21c72fa View commit details

Commits on Mar 9, 2019

  1. Merge.

    pleroy committed Mar 9, 2019
    Copy the full SHA
    f8d4b3a View commit details
2 changes: 1 addition & 1 deletion astronomy/trappist_dynamics_test.cpp
Original file line number Diff line number Diff line change
@@ -88,7 +88,7 @@ using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;

using namespace std::chrono_literals; // NOLINT.
using namespace std::chrono_literals; // NOLINT(build/namespaces)

namespace astronomy {

8 changes: 2 additions & 6 deletions ksp_plugin/plugin.cpp
Original file line number Diff line number Diff line change
@@ -54,7 +54,6 @@ namespace principia {
namespace ksp_plugin {
namespace internal_plugin {

using astronomy::InfiniteFuture;
using astronomy::ParseTT;
using astronomy::KSPStockSystemFingerprint;
using astronomy::KSPStabilizedSystemFingerprint;
@@ -844,7 +843,7 @@ void Plugin::SetPredictionAdaptiveStepParameters(

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

void Plugin::CreateFlightPlan(GUID const& vessel_guid,
@@ -901,10 +900,7 @@ void Plugin::ComputeAndRenderClosestApproaches(
if (begin != end) {
auto last = end;
--last;
target_vessel.FlowPrediction(last.time());
// The prediction may not have been prolonged enough if we are near a
// singularity.
CHECK_LE(last.time(), target_vessel.prediction().last().time());
CHECK_OK(target_vessel.FlowPrediction(last.time()));
}
ComputeApsides(target_vessel.prediction(),
begin,
5 changes: 1 addition & 4 deletions ksp_plugin/renderer.cpp
Original file line number Diff line number Diff line change
@@ -302,10 +302,7 @@ Renderer::Target::Target(
not_null<NavigationFrame const*> Renderer::GetPlottingFrame(
Instant const& time) const {
if (target_) {
target_->vessel->FlowPrediction(time);
// The prediction may not have been prolonged enough if we are near a
// singularity.
CHECK_LE(time, target_->vessel->prediction().last().time());
CHECK_OK(target_->vessel->FlowPrediction(time));
}
return GetPlottingFrame();
}
193 changes: 162 additions & 31 deletions ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ namespace internal_vessel {

using astronomy::InfiniteFuture;
using base::Contains;
using base::Error;
using base::FindOrDie;
using base::make_not_null_unique;
using geometry::BarycentreCalculator;
@@ -32,6 +33,21 @@ using quantities::si::Metre;
constexpr std::int64_t max_dense_intervals = 10'000;
constexpr Length downsampling_tolerance = 10 * Metre;

bool operator!=(Vessel::PrognosticatorParameters const& left,
Vessel::PrognosticatorParameters const& right) {
return left.first_time != right.first_time ||
left.first_degrees_of_freedom != right.first_degrees_of_freedom ||
&left.adaptive_step_parameters.integrator() !=
&right.adaptive_step_parameters.integrator() ||
left.adaptive_step_parameters.max_steps() !=
right.adaptive_step_parameters.max_steps() ||
left.adaptive_step_parameters.length_integration_tolerance() !=
right.adaptive_step_parameters.length_integration_tolerance() ||
left.adaptive_step_parameters.speed_integration_tolerance() !=
right.adaptive_step_parameters.speed_integration_tolerance() ||
left.shutdown != right.shutdown;
}

Vessel::Vessel(GUID const& guid,
std::string const& name,
not_null<Celestial const*> const parent,
@@ -51,6 +67,16 @@ Vessel::Vessel(GUID const& guid,

Vessel::~Vessel() {
LOG(INFO) << "Destroying vessel " << ShortDebugString();
// Ask the prognosticator to shut down. This may take a while. Make sure
// that we handle the case where |PrepareHistory| was not called.
if (prognosticator_.joinable()) {
{
absl::MutexLock l(&prognosticator_lock_);
CHECK(prognosticator_parameters_);
prognosticator_parameters_->shutdown = true;
}
prognosticator_.join();
}
}

GUID const& Vessel::guid() const {
@@ -167,6 +193,10 @@ void Vessel::ForAllParts(std::function<void(Part&)> action) const {
}
}

DiscreteTrajectory<Barycentric> const& Vessel::psychohistory() const {
return *psychohistory_;
}

DiscreteTrajectory<Barycentric> const& Vessel::prediction() const {
return *prediction_;
}
@@ -175,6 +205,9 @@ void Vessel::set_prediction_adaptive_step_parameters(
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters) {
prediction_adaptive_step_parameters_ = prediction_adaptive_step_parameters;
absl::MutexLock l(&prognosticator_lock_);
prognosticator_parameters_->adaptive_step_parameters =
prediction_adaptive_step_parameters;
}

Ephemeris<Barycentric>::AdaptiveStepParameters const&
@@ -192,6 +225,10 @@ bool Vessel::has_flight_plan() const {
}

void Vessel::AdvanceTime() {
// Squirrel away the prediction so that we can reattach it if we don't have a
// prognostication.
auto prediction = prediction_->DetachFork();

history_->DeleteFork(psychohistory_);
AppendToVesselTrajectory(&Part::history_begin,
&Part::history_end,
@@ -200,7 +237,14 @@ void Vessel::AdvanceTime() {
AppendToVesselTrajectory(&Part::psychohistory_begin,
&Part::psychohistory_end,
*psychohistory_);
prediction_ = psychohistory_->NewForkAtLast();
{
absl::MutexLock l(&prognosticator_lock_);
if (prognostication_ == nullptr) {
AttachPrediction(std::move(prediction));
} else {
AttachPrediction(std::move(prognostication_));
}
}

for (auto const& pair : parts_) {
Part& part = *pair.second;
@@ -209,9 +253,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 or prediction. We cannot use the parts
// because they may have been moved to the future already.
// Make sure that the history keeps at least one point and 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()));
if (flight_plan_ != nullptr) {
flight_plan_->ForgetBefore(time, [this]() { flight_plan_.reset(); });
@@ -240,34 +284,37 @@ void Vessel::DeleteFlightPlan() {
flight_plan_.reset();
}

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).ok();
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);
}
void Vessel::RefreshPrediction() {
absl::MutexLock l(&prognosticator_lock_);
prognosticator_parameters_ =
PrognosticatorParameters{psychohistory_->last().time(),
psychohistory_->last().degrees_of_freedom(),
prediction_adaptive_step_parameters_,
/*shutdown=*/false};
StartPrognosticatorIfNeeded();
if (prognostication_ != nullptr) {
AttachPrediction(std::move(prognostication_));
}
}

DiscreteTrajectory<Barycentric> const& Vessel::psychohistory() const {
return *psychohistory_;
Status Vessel::FlowPrediction(Instant const& time) {
// Make sure that the prognosticator recomputes a complete prediction from
// time to time.
RefreshPrediction();

if (time <= prediction_->last().time()) {
return Status::OK;
}

// If the prediction is not long enough, extend it explicitly. This is
// blocking.
return ephemeris_->FlowWithAdaptiveStep(
prediction_,
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
time,
prediction_adaptive_step_parameters_,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
}

void Vessel::WriteToMessage(not_null<serialization::Vessel*> const message,
@@ -345,13 +392,11 @@ not_null<std::unique_ptr<Vessel>> Vessel::ReadFromMessage(
vessel->psychohistory_ = vessel->history_->NewForkAtLast();
}
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(),
@@ -395,6 +440,81 @@ Vessel::Vessel()
ephemeris_(testing_utilities::make_not_null<Ephemeris<Barycentric>*>()),
history_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

void Vessel::StartPrognosticatorIfNeeded() {
prognosticator_lock_.AssertHeld();
CHECK(prognosticator_parameters_);
if (!prognosticator_.joinable()) {
prognosticator_ =
std::thread(std::bind(&Vessel::RepeatedlyFlowPrognostication, this));
}
}

void Vessel::RepeatedlyFlowPrognostication() {
std::optional<PrognosticatorParameters> previous_prognosticator_parameters;
for (;;) {
// No point in going faster than 50 Hz.
std::chrono::steady_clock::time_point const wakeup_time =
std::chrono::steady_clock::now() + std::chrono::milliseconds(20);

// The thread is only started after the parameters have been set, so we
// should always find parameters here.
std::optional<PrognosticatorParameters> prognosticator_parameters;
{
absl::ReaderMutexLock l(&prognosticator_lock_);
CHECK(prognosticator_parameters_);
prognosticator_parameters = prognosticator_parameters_;
}

if (prognosticator_parameters->shutdown) {
break;
}

// Do not reflow if the parameters have not changed: the same causes would
// produce the same effects.
if (!previous_prognosticator_parameters ||
*previous_prognosticator_parameters != prognosticator_parameters) {
auto prognostication =
std::make_unique<DiscreteTrajectory<Barycentric>>();
prognostication->Append(
prognosticator_parameters->first_time,
prognosticator_parameters->first_degrees_of_freedom);
Status status;
status = ephemeris_->FlowWithAdaptiveStep(
prognostication.get(),
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
ephemeris_->t_max(),
prognosticator_parameters->adaptive_step_parameters,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
bool const reached_t_max = status.ok();
if (reached_t_max) {
// This will prolong the ephemeris by |max_ephemeris_steps_per_frame|.
status = ephemeris_->FlowWithAdaptiveStep(
prognostication.get(),
Ephemeris<Barycentric>::NoIntrinsicAcceleration,
InfiniteFuture,
prognosticator_parameters->adaptive_step_parameters,
FlightPlan::max_ephemeris_steps_per_frame,
/*last_point_only=*/false);
}
LOG_IF(INFO, !status.ok())
<< "Prognostication from " << prognosticator_parameters->first_time
<< " finished at " << prognostication->last().time() << " with "
<< status.ToString() << " for " << ShortDebugString();

// Publish the prognostication if the computation was not cancelled.
if (status.error() != Error::CANCELLED) {
absl::MutexLock l(&prognosticator_lock_);
prognostication_.swap(prognostication);
prognosticator_status_ = status;
}
previous_prognosticator_parameters = prognosticator_parameters;
}

std::this_thread::sleep_until(wakeup_time);
}
}

void Vessel::AppendToVesselTrajectory(
TrajectoryIterator const part_trajectory_begin,
TrajectoryIterator const part_trajectory_end,
@@ -443,6 +563,17 @@ void Vessel::AppendToVesselTrajectory(
}
}

void Vessel::AttachPrediction(
not_null<std::unique_ptr<DiscreteTrajectory<Barycentric>>> trajectory) {
trajectory->ForgetBefore(psychohistory_->last().time());
if (trajectory->Empty()) {
prediction_ = psychohistory_->NewForkAtLast();
} else {
prediction_ = trajectory.get();
psychohistory_->AttachFork(std::move(trajectory));
}
}

} // namespace internal_vessel
} // namespace ksp_plugin
} // namespace principia
Loading