Skip to content

Commit

Permalink
Showing 4 changed files with 37 additions and 7 deletions.
6 changes: 4 additions & 2 deletions ksp_plugin/orbit_analyser.cpp
Original file line number Diff line number Diff line change
@@ -114,10 +114,12 @@ Status OrbitAnalyser::AnalyseOrbit(GuardedParameters const guarded_parameters) {
if (primary != nullptr) {
std::vector<not_null<DiscreteTrajectory<Barycentric>*>> trajectories = {
&trajectory};
auto instance = ephemeris_->NewInstance(
auto instance = ephemeris_->StoppableNewInstance(
trajectories,
Ephemeris<Barycentric>::NoIntrinsicAccelerations,
analysed_trajectory_parameters_);
RETURN_IF_STOPPED;

Time const analysis_duration = std::min(
parameters.extended_mission_duration.value_or(
parameters.mission_duration),
@@ -126,7 +128,7 @@ Status OrbitAnalyser::AnalyseOrbit(GuardedParameters const guarded_parameters) {
for (int n = 0; n <= progress_bar_steps; ++n) {
Instant const t =
parameters.first_time + n / progress_bar_steps * analysis_duration;
if (!ephemeris_->FlowWithFixedStep(t, *instance).ok()) {
if (!ephemeris_->FlowWithFixedStep(t, *instance.ValueOrDie()).ok()) {
// TODO(egg): Report that the integration failed.
break;
}
15 changes: 13 additions & 2 deletions physics/ephemeris.hpp
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
#include "base/jthread.hpp"
#include "base/not_null.hpp"
#include "base/status.hpp"
#include "base/status_or.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "google/protobuf/repeated_field.h"
@@ -36,6 +37,7 @@ using base::Error;
using base::jthread;
using base::not_null;
using base::Status;
using base::StatusOr;
using geometry::Instant;
using geometry::Position;
using geometry::Vector;
@@ -186,8 +188,9 @@ class Ephemeris {

virtual Status last_severe_integration_status() const;

// Prolongs the ephemeris up to at least |t|. After the call, |t_max() >= t|.
virtual void Prolong(Instant const& t) EXCLUDES(lock_);
// Prolongs the ephemeris up to at least |t|. Returns an error iff the thread
// is stopped. After a successful call, |t_max() >= t|.
virtual Status Prolong(Instant const& t) EXCLUDES(lock_);

// Creates an instance suitable for integrating the given |trajectories| with
// their |intrinsic_accelerations| using a fixed-step integrator parameterized
@@ -199,6 +202,14 @@ class Ephemeris {
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters);

// Same as above, but returns an error status if the thread is stopped.
virtual StatusOr<not_null<
std::unique_ptr<typename Integrator<NewtonianMotionEquation>::Instance>>>
StoppableNewInstance(
std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters);

// Integrates, until exactly |t| (except for timeouts or singularities), the
// |trajectory| followed by a massless body in the gravitational potential
// described by |*this|. If |t > t_max()|, calls |Prolong(t)| beforehand.
21 changes: 19 additions & 2 deletions physics/ephemeris_body.hpp
Original file line number Diff line number Diff line change
@@ -352,10 +352,10 @@ Status Ephemeris<Frame>::last_severe_integration_status() const {
}

template<typename Frame>
void Ephemeris<Frame>::Prolong(Instant const& t) {
Status Ephemeris<Frame>::Prolong(Instant const& t) {
// Short-circuit without locking.
if (t <= t_max()) {
return;
return Status::OK;
}

// Note that |t| may be before the last time that we integrated and still
@@ -375,8 +375,11 @@ void Ephemeris<Frame>::Prolong(Instant const& t) {
absl::MutexLock l(&lock_);
while (t_max() < t) {
instance_->Solve(t_final);
RETURN_IF_STOPPED;
t_final += fixed_step_parameters_.step_;
}

return Status::OK;
}

template<typename Frame>
@@ -386,6 +389,17 @@ Ephemeris<Frame>::NewInstance(
std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters) {
return StoppableNewInstance(trajectories, intrinsic_accelerations, parameters)
.ValueOrDie();
}

template<typename Frame>
StatusOr<not_null<std::unique_ptr<typename Integrator<
typename Ephemeris<Frame>::NewtonianMotionEquation>::Instance>>>
Ephemeris<Frame>::StoppableNewInstance(
std::vector<not_null<DiscreteTrajectory<Frame>*>> const& trajectories,
IntrinsicAccelerations const& intrinsic_accelerations,
FixedStepParameters const& parameters) {
IntegrationProblem<NewtonianMotionEquation> problem;

problem.equation.compute_acceleration =
@@ -427,6 +441,7 @@ Ephemeris<Frame>::NewInstance(
// The construction of the instance may evaluate the degrees of freedom of the
// bodies.
Prolong(trajectory_last_time + parameters.step_);
RETURN_IF_STOPPED;

return parameters.integrator_->NewInstance(
problem, append_state, parameters.step_);
@@ -501,6 +516,7 @@ Status Ephemeris<Frame>::FlowWithFixedStep(
typename Integrator<NewtonianMotionEquation>::Instance& instance) {
if (empty() || t > t_max()) {
Prolong(t);
RETURN_IF_STOPPED;
}
if (instance.time() == DoublePrecision<Instant>(t)) {
return Status::OK;
@@ -1244,6 +1260,7 @@ Status Ephemeris<Frame>::FlowODEWithAdaptiveStep(
trajectory_last_time + fixed_step_parameters_.step()),
t);
Prolong(t_final);
RETURN_IF_STOPPED;

IntegrationProblem<ODE> problem;
problem.equation.compute_acceleration = std::move(compute_acceleration);
2 changes: 1 addition & 1 deletion physics/mock_ephemeris.hpp
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ class MockEphemeris : public Ephemeris<Frame> {
planetary_integrator,
FixedStepSizeIntegrator<NewtonianMotionEquation> const&());

MOCK_METHOD1_T(Prolong, void(Instant const& t));
MOCK_METHOD1_T(Prolong, Status(Instant const& t));
MOCK_METHOD3_T(
NewInstance,
not_null<std::unique_ptr<

0 comments on commit 7765178

Please sign in to comment.