Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the code that extends the prediction to Renderer #1562

Merged
merged 8 commits into from
Sep 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -936,7 +936,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 @@ -952,7 +951,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