From 451e454ff97e08ceb21e589c5539a698230be095 Mon Sep 17 00:00:00 2001 From: pleroy Date: Sat, 17 Dec 2022 18:03:39 +0100 Subject: [PATCH 1/3] Fix Clang errors. --- numerics/global_optimization.hpp | 2 +- numerics/global_optimization_body.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/numerics/global_optimization.hpp b/numerics/global_optimization.hpp index 2ef6096aa4..330909f15d 100644 --- a/numerics/global_optimization.hpp +++ b/numerics/global_optimization.hpp @@ -117,7 +117,7 @@ class MultiLevelSingleLinkage { Box const box_; NormType const box_diametre_; - Box::Measure const box_measure_; + typename Box::Measure const box_measure_; Field const f_; Field, Argument> const grad_f_; diff --git a/numerics/global_optimization_body.hpp b/numerics/global_optimization_body.hpp index c4ebb29fcd..68bb7321a9 100644 --- a/numerics/global_optimization_body.hpp +++ b/numerics/global_optimization_body.hpp @@ -31,7 +31,7 @@ using quantities::Pow; constexpr int64_t pcp_tree_max_values_per_cell = 20; template -MultiLevelSingleLinkage::Box::Measure +typename MultiLevelSingleLinkage::Box::Measure MultiLevelSingleLinkage::Box::measure() const { if constexpr (dimensions == 1) { return 2 * vertices[0].Norm(); From 7e9c30ac68f95e2a79296c5f0346a696538d3010 Mon Sep 17 00:00:00 2001 From: pleroy Date: Sat, 17 Dec 2022 18:04:34 +0100 Subject: [PATCH 2/3] After every change to the flight plan, make sure that the prediction of the target vessel is long enough to display the flight plan. --- ksp_plugin/interface_flight_plan.cpp | 52 ++++++++++++++++------------ ksp_plugin/plugin.cpp | 50 +++++++++++++++++++++++--- ksp_plugin/plugin.hpp | 4 +++ 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/ksp_plugin/interface_flight_plan.cpp b/ksp_plugin/interface_flight_plan.cpp index 5335ca1de2..f600c9b4d6 100644 --- a/ksp_plugin/interface_flight_plan.cpp +++ b/ksp_plugin/interface_flight_plan.cpp @@ -170,18 +170,6 @@ NavigationManoeuvre ToInterfaceNavigationManoeuvre( } // namespace -Status* __cdecl principia__FlightPlanInsert(Plugin const* const plugin, - char const* const vessel_guid, - Burn const burn, - int const index) { - journal::Method m( - {plugin, vessel_guid, burn, index}); - CHECK_NOTNULL(plugin); - return m.Return( - ToNewStatus(GetFlightPlan(*plugin, vessel_guid) - .Insert(FromInterfaceBurn(*plugin, burn), index))); -} - int __cdecl principia__FlightPlanCount(Plugin const* const plugin, char const* const vessel_guid) { journal::Method m({plugin, vessel_guid}); @@ -360,6 +348,19 @@ principia__FlightPlanGetManoeuvreFrenetTrihedron(Plugin const* const plugin, return m.Return(result); } +Status* __cdecl principia__FlightPlanInsert(Plugin const* const plugin, + char const* const vessel_guid, + Burn const burn, + int const index) { + journal::Method m( + {plugin, vessel_guid, burn, index}); + CHECK_NOTNULL(plugin); + auto const status = GetFlightPlan(*plugin, vessel_guid) + .Insert(FromInterfaceBurn(*plugin, burn), index); + plugin->ExtendPredictionForFlightPlan(vessel_guid); + return m.Return(ToNewStatus(status)); +} + int __cdecl principia__FlightPlanNumberOfAnomalousManoeuvres( Plugin const* const plugin, char const* const vessel_guid) { @@ -396,6 +397,7 @@ Status* __cdecl principia__FlightPlanRebase(Plugin const* const plugin, CHECK_NOTNULL(plugin); auto const status = plugin->GetVessel(vessel_guid)->RebaseFlightPlan(mass_in_tonnes * Tonne); + plugin->ExtendPredictionForFlightPlan(vessel_guid); return m.Return(ToNewStatus(status)); } @@ -404,8 +406,9 @@ Status* __cdecl principia__FlightPlanRemove(Plugin const* const plugin, int const index) { journal::Method m({plugin, vessel_guid, index}); CHECK_NOTNULL(plugin); - return m.Return( - ToNewStatus(GetFlightPlan(*plugin, vessel_guid).Remove(index))); + auto const status = GetFlightPlan(*plugin, vessel_guid).Remove(index); + plugin->ExtendPredictionForFlightPlan(vessel_guid); + return m.Return(ToNewStatus(status)); } void __cdecl principia__FlightPlanRenderedApsides( @@ -533,9 +536,10 @@ Status* __cdecl principia__FlightPlanReplace(Plugin const* const plugin, burn, index}); CHECK_NOTNULL(plugin); - return m.Return( - ToNewStatus(GetFlightPlan(*plugin, vessel_guid) - .Replace(FromInterfaceBurn(*plugin, burn), index))); + auto const status = GetFlightPlan(*plugin, vessel_guid) + .Replace(FromInterfaceBurn(*plugin, burn), index); + plugin->ExtendPredictionForFlightPlan(vessel_guid); + return m.Return(ToNewStatus(status)); } void __cdecl principia__FlightPlanSelect(Plugin const* const plugin, @@ -564,9 +568,11 @@ Status* __cdecl principia__FlightPlanSetAdaptiveStepParameters( CHECK_NOTNULL(plugin); auto const parameters = FromFlightPlanAdaptiveStepParameters( flight_plan_adaptive_step_parameters); - return m.Return(ToNewStatus( + auto const status = GetFlightPlan(*plugin, vessel_guid) - .SetAdaptiveStepParameters(parameters.first, parameters.second))); + .SetAdaptiveStepParameters(parameters.first, parameters.second); + plugin->ExtendPredictionForFlightPlan(vessel_guid); + return m.Return(ToNewStatus(status)); } Status* __cdecl principia__FlightPlanSetDesiredFinalTime( @@ -577,9 +583,11 @@ Status* __cdecl principia__FlightPlanSetDesiredFinalTime( vessel_guid, final_time}); CHECK_NOTNULL(plugin); - return m.Return( - ToNewStatus(GetFlightPlan(*plugin, vessel_guid) - .SetDesiredFinalTime(FromGameTime(*plugin, final_time)))); + auto const status = + GetFlightPlan(*plugin, vessel_guid) + .SetDesiredFinalTime(FromGameTime(*plugin, final_time)); + plugin->ExtendPredictionForFlightPlan(vessel_guid); + return m.Return(ToNewStatus(status)); } } // namespace interface diff --git a/ksp_plugin/plugin.cpp b/ksp_plugin/plugin.cpp index e60698c94e..4ad4ff2455 100644 --- a/ksp_plugin/plugin.cpp +++ b/ksp_plugin/plugin.cpp @@ -895,13 +895,31 @@ void Plugin::SetPredictionAdaptiveStepParameters( // 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. + auto& vessel = *FindOrDie(vessels_, vessel_guid); if (renderer_->HasTargetVessel()) { - renderer_->GetTargetVessel().set_prediction_adaptive_step_parameters( - prediction_adaptive_step_parameters); - } - FindOrDie(vessels_, vessel_guid) - ->set_prediction_adaptive_step_parameters( + auto& target_vessel = renderer_->GetTargetVessel(); + if (vessel.has_flight_plan()) { + // If there is a target vessel and our vessel has a flight plan, make sure + // that we don't shorten the target vessel's prediction as it would hurt + // our flight plan. + auto const target_prediction_adaptive_step_parameters = + target_vessel.prediction_adaptive_step_parameters(); + target_vessel.set_prediction_adaptive_step_parameters( + Ephemeris::AdaptiveStepParameters( + prediction_adaptive_step_parameters.integrator(), + std::max(target_prediction_adaptive_step_parameters.max_steps(), + prediction_adaptive_step_parameters.max_steps()), + prediction_adaptive_step_parameters + .length_integration_tolerance(), + prediction_adaptive_step_parameters + .speed_integration_tolerance())); + } else { + target_vessel.set_prediction_adaptive_step_parameters( prediction_adaptive_step_parameters); + } + } + vessel.set_prediction_adaptive_step_parameters( + prediction_adaptive_step_parameters); } void Plugin::UpdatePrediction(std::vector const& vessel_guids) const { @@ -947,6 +965,28 @@ void Plugin::CreateFlightPlan(GUID const& vessel_guid, DefaultBurnParameters()); } +void Plugin::ExtendPredictionForFlightPlan(GUID const& vessel_guid) const { + auto& vessel = *FindOrDie(vessels_, vessel_guid); + + // If there is a target vessel, and the prediction of the target is too short + // for the flight plan, multiply the number of steps by 4 (one notch in the + // UI). We don't wait for the prediction to be computed, though, so there is + // no guarantee that it will be long enough. Presumably the user will keep + // increasing the flight plan length and get what they want, ultimately. + if (renderer_->HasTargetVessel() && vessel.has_flight_plan()) { + auto& target_vessel = renderer_->GetTargetVessel(); + if (target_vessel.prediction()->back().time < + vessel.flight_plan().actual_final_time()) { + auto prediction_adaptive_step_parameters = + target_vessel.prediction_adaptive_step_parameters(); + prediction_adaptive_step_parameters.set_max_steps( + prediction_adaptive_step_parameters.max_steps() * 4); + target_vessel.set_prediction_adaptive_step_parameters( + prediction_adaptive_step_parameters); + } + } +} + void Plugin::ComputeAndRenderApsides( Index const celestial_index, Trajectory const& trajectory, diff --git a/ksp_plugin/plugin.hpp b/ksp_plugin/plugin.hpp index 8e9c8aca27..d7951a7fbb 100644 --- a/ksp_plugin/plugin.hpp +++ b/ksp_plugin/plugin.hpp @@ -347,6 +347,10 @@ class Plugin { Instant const& final_time, Mass const& initial_mass) const; + // If there is a target vessel, increases the size of the prediction to try + // and cover the actual final time of the flight plan. + void ExtendPredictionForFlightPlan(GUID const& vessel_guid) const; + // Computes the apsides of the trajectory defined by |begin| and |end| with // respect to the celestial with index |celestial_index|. virtual void ComputeAndRenderApsides( From 8af84d17b23fb7e4d590d338d06dd654e4cf4583 Mon Sep 17 00:00:00 2001 From: pleroy Date: Sun, 18 Dec 2022 10:16:35 +0100 Subject: [PATCH 3/3] Adding mocking for the new function. --- ksp_plugin/plugin.hpp | 2 +- ksp_plugin_test/interface_flight_plan_test.cpp | 3 +++ ksp_plugin_test/mock_plugin.hpp | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ksp_plugin/plugin.hpp b/ksp_plugin/plugin.hpp index d7951a7fbb..b413964ede 100644 --- a/ksp_plugin/plugin.hpp +++ b/ksp_plugin/plugin.hpp @@ -349,7 +349,7 @@ class Plugin { // If there is a target vessel, increases the size of the prediction to try // and cover the actual final time of the flight plan. - void ExtendPredictionForFlightPlan(GUID const& vessel_guid) const; + virtual void ExtendPredictionForFlightPlan(GUID const& vessel_guid) const; // Computes the apsides of the trajectory defined by |begin| and |end| with // respect to the celestial with index |celestial_index|. diff --git a/ksp_plugin_test/interface_flight_plan_test.cpp b/ksp_plugin_test/interface_flight_plan_test.cpp index d9a0288cec..e878225db6 100644 --- a/ksp_plugin_test/interface_flight_plan_test.cpp +++ b/ksp_plugin_test/interface_flight_plan_test.cpp @@ -78,6 +78,7 @@ using quantities::si::Second; using quantities::si::Tonne; using testing_utilities::AlmostEquals; using ::testing::AllOf; +using ::testing::AnyNumber; using ::testing::ByMove; using ::testing::DoAll; using ::testing::Invoke; @@ -147,6 +148,8 @@ TEST_F(InterfaceFlightPlanTest, FlightPlan) { .WillRepeatedly(Return(true)); EXPECT_CALL(vessel, flight_plan()) .WillRepeatedly(ReturnRef(flight_plan)); + EXPECT_CALL(*plugin_, ExtendPredictionForFlightPlan(vessel_guid)) + .Times(AnyNumber()); EXPECT_TRUE(principia__FlightPlanExists(plugin_.get(), vessel_guid)); diff --git a/ksp_plugin_test/mock_plugin.hpp b/ksp_plugin_test/mock_plugin.hpp index 29be8f6fae..4186ffa13b 100644 --- a/ksp_plugin_test/mock_plugin.hpp +++ b/ksp_plugin_test/mock_plugin.hpp @@ -83,6 +83,11 @@ class MockPlugin : public Plugin { Mass const& initial_mass), (const, override)); + MOCK_METHOD(void, + ExtendPredictionForFlightPlan, + (GUID const& vessel_guid), + (const, override)); + MOCK_METHOD(void, SetPredictionAdaptiveStepParameters, (GUID const& vessel_guid,