Skip to content

Commit

Permalink
Merge pull request #1562 from pleroy/1561
Browse files Browse the repository at this point in the history
Move the code that extends the prediction to Renderer
  • Loading branch information
pleroy authored Sep 21, 2017
2 parents 6ab31e2 + fe13210 commit 6c7b951
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 132 deletions.
8 changes: 0 additions & 8 deletions ksp_plugin/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,14 +792,6 @@ void principia__SetPartApparentDegreesOfFreedom(Plugin* const plugin,
return m.Return();
}

void principia__SetPredictionLength(Plugin* const plugin,
double const t) {
journal::Method<journal::SetPredictionLength> m({plugin, t});
CHECK_NOTNULL(plugin);
plugin->SetPredictionLength(t * Second);
return m.Return();
}

// Make it so that all log messages of at least |min_severity| are logged to
// stderr (in addition to logging to the usual log file(s)).
void principia__SetStderrLogging(int const min_severity) {
Expand Down
6 changes: 3 additions & 3 deletions ksp_plugin/interface_vessel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ void principia__VesselSetPredictionAdaptiveStepParameters(
journal::Method<journal::VesselSetPredictionAdaptiveStepParameters> m(
{plugin, vessel_guid, adaptive_step_parameters});
CHECK_NOTNULL(plugin);
plugin->GetVessel(vessel_guid)
->set_prediction_adaptive_step_parameters(
FromAdaptiveStepParameters(adaptive_step_parameters));
plugin->SetPredictionAdaptiveStepParameters(
vessel_guid,
FromAdaptiveStepParameters(adaptive_step_parameters));
return m.Return();
}

Expand Down
45 changes: 19 additions & 26 deletions ksp_plugin/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace principia {
namespace ksp_plugin {
namespace internal_plugin {

using astronomy::InfiniteFuture;
using astronomy::ParseTT;
using astronomy::KSPStockSystemFingerprint;
using astronomy::KSPStabilizedSystemFingerprint;
Expand Down Expand Up @@ -680,10 +681,25 @@ RelativeDegreesOfFreedom<AliceSun> Plugin::CelestialFromParent(
return result;
}

void Plugin::SetPredictionAdaptiveStepParameters(
GUID const& vessel_guid,
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters) const {
// If there is a target vessel, it is integrated with the same parameters as
// the given (current) vessel. This makes it possible to plot the prediction
// of the current vessel.
if (renderer_->HasTargetVessel()) {
renderer_->GetTargetVessel().set_prediction_adaptive_step_parameters(
prediction_adaptive_step_parameters);
}
FindOrDie(vessels_, vessel_guid)
->set_prediction_adaptive_step_parameters(
prediction_adaptive_step_parameters);
}

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

void Plugin::CreateFlightPlan(GUID const& vessel_guid,
Expand Down Expand Up @@ -730,11 +746,10 @@ void Plugin::ComputeAndRenderClosestApproaches(
Position<World> const& sun_world_position,
std::unique_ptr<DiscreteTrajectory<World>>& closest_approaches) const {
CHECK(renderer_->HasTargetVessel());
UpdatePredictionForRendering(begin.trajectory()->Size());

DiscreteTrajectory<Barycentric> apoapsides_trajectory;
DiscreteTrajectory<Barycentric> periapsides_trajectory;
ComputeApsides(renderer_->GetTargetVessel().prediction(),
ComputeApsides(renderer_->GetTargetVesselPrediction(current_time_),
begin,
end,
apoapsides_trajectory,
Expand All @@ -754,10 +769,6 @@ void Plugin::ComputeAndRenderNodes(
Position<World> const& sun_world_position,
std::unique_ptr<DiscreteTrajectory<World>>& ascending,
std::unique_ptr<DiscreteTrajectory<World>>& descending) const {
if (renderer_->HasTargetVessel()) {
UpdatePredictionForRendering(begin.trajectory()->Size());
}

auto const trajectory_in_plotting =
renderer_->RenderBarycentricTrajectoryInPlotting(begin, end);
DiscreteTrajectory<Navigation> ascending_trajectory;
Expand All @@ -782,10 +793,6 @@ void Plugin::ComputeAndRenderNodes(
PlanetariumRotation());
}

void Plugin::SetPredictionLength(Time const& t) {
prediction_length_ = t;
}

void Plugin::SetPredictionAdaptiveStepParameters(
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters) {
Expand Down Expand Up @@ -873,11 +880,6 @@ void Plugin::SetTargetVessel(GUID const& vessel_guid,
not_null<Celestial const*> const celestial =
FindOrDie(celestials_, reference_body_index).get();
not_null<Vessel*> const vessel = FindOrDie(vessels_, vessel_guid).get();
// Make sure that the current time is covered by the prediction.
if (current_time_ > vessel->prediction().t_max()) {
vessel->UpdatePrediction(current_time_ + prediction_length_);
}

renderer_->SetTargetVessel(vessel, celestial, ephemeris_.get());
}

Expand Down Expand Up @@ -1255,15 +1257,6 @@ void Plugin::UpdatePlanetariumRotation() {
to_planetarium;
}

void Plugin::UpdatePredictionForRendering(std::int64_t const size) const {
auto& vessel = renderer_->GetTargetVessel();
auto parameters = vessel.prediction_adaptive_step_parameters();
// Adding one to ensure that we set a strictly positive max_steps.
parameters.set_max_steps(size + 1);
vessel.set_prediction_adaptive_step_parameters(parameters);
vessel.UpdatePrediction(current_time_ + prediction_length_);
}

Velocity<World> Plugin::VesselVelocity(
Instant const& time,
DegreesOfFreedom<Barycentric> const& degrees_of_freedom) const {
Expand Down
12 changes: 5 additions & 7 deletions ksp_plugin/plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ class Plugin {
virtual RelativeDegreesOfFreedom<AliceSun> CelestialFromParent(
Index celestial_index) const;

virtual void SetPredictionAdaptiveStepParameters(
GUID const& vessel_guid,
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters) const;

// Updates the prediction for the vessel with guid |vessel_guid|.
void UpdatePrediction(GUID const& vessel_guid) const;

Expand Down Expand Up @@ -312,8 +317,6 @@ class Plugin {
std::unique_ptr<DiscreteTrajectory<World>>& ascending,
std::unique_ptr<DiscreteTrajectory<World>>& descending) const;

virtual void SetPredictionLength(Time const& t);

virtual void SetPredictionAdaptiveStepParameters(
Ephemeris<Barycentric>::AdaptiveStepParameters const&
prediction_adaptive_step_parameters);
Expand Down Expand Up @@ -406,10 +409,6 @@ class Plugin {
// whenever |main_body_| or |planetarium_rotation_| changes.
void UpdatePlanetariumRotation();

// NOTE(egg): this is an ugly hack to try to get a long enough trajectory
// while retaining a timeout.
void UpdatePredictionForRendering(std::int64_t size) const;

Velocity<World> VesselVelocity(
Instant const& time,
DegreesOfFreedom<Barycentric> const& degrees_of_freedom) const;
Expand Down Expand Up @@ -455,7 +454,6 @@ class Plugin {
Ephemeris<Barycentric>::FixedStepParameters history_parameters_;
Ephemeris<Barycentric>::AdaptiveStepParameters prolongation_parameters_;
Ephemeris<Barycentric>::AdaptiveStepParameters prediction_parameters_;
Time prediction_length_ = 1 * Hour;

// The thread pool for advancing vessels.
ThreadPool<void> vessel_thread_pool_;
Expand Down
56 changes: 39 additions & 17 deletions ksp_plugin/renderer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

#include "ksp_plugin/renderer.hpp"

#include <algorithm>

#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "physics/apsides.hpp"
Expand Down Expand Up @@ -40,7 +42,6 @@ void Renderer::SetTargetVessel(
not_null<Vessel*> const vessel,
not_null<Celestial const*> const celestial,
not_null<Ephemeris<Barycentric> const*> const ephemeris) {
CHECK(!vessel->prediction().Empty());
if (!target_ ||
target_->vessel != vessel ||
target_->celestial != celestial) {
Expand Down Expand Up @@ -72,6 +73,16 @@ Vessel const& Renderer::GetTargetVessel() const {
return *target_->vessel;
}

DiscreteTrajectory<Barycentric> const& Renderer::GetTargetVesselPrediction(
Instant const& time) const {
CHECK(target_);
target_->vessel->UpdatePrediction(time);
// The prediction may not have been prolonged to |time| if we are near a
// singularity.
CHECK_LE(time, target_->vessel->prediction().last().time());
return target_->vessel->prediction();
}

not_null<std::unique_ptr<DiscreteTrajectory<World>>>
Renderer::RenderBarycentricTrajectoryInWorld(
Instant const& time,
Expand All @@ -94,20 +105,22 @@ not_null<std::unique_ptr<DiscreteTrajectory<Navigation>>>
Renderer::RenderBarycentricTrajectoryInPlotting(
DiscreteTrajectory<Barycentric>::Iterator const& begin,
DiscreteTrajectory<Barycentric>::Iterator const& end) const {
CHECK(!target_ || !target_->vessel->prediction().Empty());

auto trajectory = make_not_null_unique<DiscreteTrajectory<Navigation>>();
if (target_ && begin != end) {
auto last = end;
--last;
target_->vessel->UpdatePrediction(last.time());
}
for (auto it = begin; it != end; ++it) {
Instant const& t = it.time();
if (target_) {
if (it.time() < target_->vessel->prediction().t_min()) {
if (t < target_->vessel->prediction().t_min()) {
continue;
} else if (it.time() > target_->vessel->prediction().t_max()) {
} else if (t > target_->vessel->prediction().t_max()) {
break;
}
}
trajectory->Append(
it.time(),
BarycentricToPlotting(it.time())(it.degrees_of_freedom()));
trajectory->Append(t, BarycentricToPlotting(t)(it.degrees_of_freedom()));
}
return trajectory;
}
Expand Down Expand Up @@ -158,7 +171,7 @@ Renderer::RenderPlottingTrajectoryInWorld(

RigidMotion<Barycentric, Navigation> Renderer::BarycentricToPlotting(
Instant const& time) const {
return GetPlottingFrame()->ToThisFrameAtTime(time);
return GetPlottingFrame(time)->ToThisFrameAtTime(time);
}

RigidTransformation<Barycentric, World> Renderer::BarycentricToWorld(
Expand Down Expand Up @@ -187,7 +200,6 @@ OrthogonalMap<Frenet<Navigation>, World> Renderer::FrenetToWorld(
NavigationManœuvre const& manœuvre,
Rotation<Barycentric, AliceSun> const& planetarium_rotation) const {
Instant const initial_time = manœuvre.initial_time();
NavigationFrame const& plotting_frame = *GetPlottingFrame();
return PlottingToWorld(time, planetarium_rotation) *
BarycentricToPlotting(initial_time).orthogonal_map() *
manœuvre.FrenetFrame();
Expand All @@ -204,8 +216,9 @@ OrthogonalMap<Frenet<Navigation>, World> Renderer::FrenetToWorld(
BarycentricToPlotting(time)(barycentric_degrees_of_freedom);
Rotation<Frenet<Navigation>, Navigation> const
frenet_frame_to_plotting_frame =
GetPlottingFrame()->FrenetFrame(time,
plotting_frame_degrees_of_freedom);
GetPlottingFrame(time)->FrenetFrame(
time,
plotting_frame_degrees_of_freedom);

return PlottingToWorld(time, planetarium_rotation) *
frenet_frame_to_plotting_frame.Forget();
Expand All @@ -230,15 +243,16 @@ OrthogonalMap<Frenet<Navigation>, World> Renderer::FrenetToWorld(

OrthogonalMap<Navigation, Barycentric> Renderer::PlottingToBarycentric(
Instant const& time) const {
return GetPlottingFrame()->FromThisFrameAtTime(time).orthogonal_map();
return GetPlottingFrame(time)->FromThisFrameAtTime(time).orthogonal_map();
}

RigidTransformation<Navigation, World> Renderer::PlottingToWorld(
Instant const& time,
Position<World> const& sun_world_position,
Rotation<Barycentric, AliceSun> const& planetarium_rotation) const {
return BarycentricToWorld(time, sun_world_position, planetarium_rotation) *
GetPlottingFrame()->FromThisFrameAtTime(time).rigid_transformation();
GetPlottingFrame(time)->
FromThisFrameAtTime(time).rigid_transformation();
}

OrthogonalMap<Navigation, World> Renderer::PlottingToWorld(
Expand Down Expand Up @@ -293,9 +307,17 @@ Renderer::Target::Target(
target_frame(
make_not_null_unique<
BodyCentredBodyDirectionDynamicFrame<Barycentric, Navigation>>(
ephemeris,
[this]() -> auto& { return this->vessel->prediction(); },
celestial->body())) {}
ephemeris,
[this]() -> auto& { return this->vessel->prediction(); },
celestial->body())) {}

not_null<NavigationFrame const*> Renderer::GetPlottingFrame(
Instant const& time) const {
if (target_) {
GetTargetVesselPrediction(time);
}
return GetPlottingFrame();
}

} // namespace internal_renderer
} // namespace ksp_plugin
Expand Down
22 changes: 16 additions & 6 deletions ksp_plugin/renderer.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <experimental/optional>
#include <functional>
#include <memory>

#include "base/not_null.hpp"
Expand Down Expand Up @@ -48,8 +49,7 @@ class Renderer {
virtual not_null<NavigationFrame const*> GetPlottingFrame() const;

// Overrides the current plotting frame with one that is centred on the given
// |vessel|. When using the operations below with a target vessel, the client
// must ensure that the |time| is covered by the vessel's prediction.
// |vessel|.
virtual void SetTargetVessel(
not_null<Vessel*> vessel,
not_null<Celestial const*> celestial,
Expand All @@ -65,6 +65,11 @@ class Renderer {
virtual Vessel& GetTargetVessel();
virtual Vessel const& GetTargetVessel() const;

// If there is a target vessel, returns its prediction after extending it up
// to |time|.
virtual DiscreteTrajectory<Barycentric> const& GetTargetVesselPrediction(
Instant const& time) const;

// Returns a trajectory in |World| corresponding to the trajectory defined by
// |begin| and |end|, as seen in the current plotting frame. In this function
// and others in this class, |sun_world_position| is the current position of
Expand Down Expand Up @@ -165,10 +170,6 @@ class Renderer {
not_null<Ephemeris<Barycentric> const*> ephemeris);

private:
not_null<Celestial const*> const sun_;

not_null<std::unique_ptr<NavigationFrame>> plotting_frame_;

struct Target {
Target(not_null<Vessel*> vessel,
not_null<Celestial const*> celestial,
Expand All @@ -177,6 +178,15 @@ class Renderer {
not_null<Celestial const*> const celestial;
not_null<std::unique_ptr<NavigationFrame>> const target_frame;
};

// Returns a plotting frame suitable for evaluation at |time|, possibly by
// extending the prediction if there is a target vessel.
not_null<NavigationFrame const*> GetPlottingFrame(Instant const& time) const;

not_null<Celestial const*> const sun_;

not_null<std::unique_ptr<NavigationFrame>> plotting_frame_;

std::experimental::optional<Target> target_;
};

Expand Down
14 changes: 11 additions & 3 deletions ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,17 @@ void Vessel::DeleteFlightPlan() {
}

void Vessel::UpdatePrediction(Instant const& last_time) {
prediction_ = make_not_null_unique<DiscreteTrajectory<Barycentric>>();
auto const last = psychohistory_->last();
prediction_->Append(last.time(), last.degrees_of_freedom());
// 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());
}
FlowPrediction(last_time);
}

Expand Down
3 changes: 1 addition & 2 deletions ksp_plugin_adapter/ksp_plugin_adapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,6 @@ private void FixedUpdate() {
prediction_length_tolerance_index_]};
plugin_.VesselSetPredictionAdaptiveStepParameters(
main_vessel.id.ToString(), adaptive_step_parameters);
plugin_.SetPredictionLength(double.PositiveInfinity);
plugin_.UpdatePrediction(main_vessel.id.ToString());
string target_id =
FlightGlobals.fetch.VesselTarget?.GetVessel()?.id.ToString();
Expand All @@ -944,7 +943,7 @@ private void FixedUpdate() {
// TODO(egg): Set the degrees of freedom of the origin of |World| (by
// toying with Krakensbane and FloatingOrigin) here.

// Now we let the game and Unity do their thing. among other things,
// Now we let the game and Unity do their thing. Among other things,
// the FashionablyLate callbacks, including ReportNonConservativeForces,
// then the FlightIntegrator's FixedUpdate will run, then the Vessel's,
// and eventually the physics simulation.
Expand Down
Loading

0 comments on commit 6c7b951

Please sign in to comment.