Skip to content

Commit

Permalink
Merge pull request #3781 from pleroy/UI
Browse files Browse the repository at this point in the history
Clean up the optimization UI
  • Loading branch information
pleroy authored Oct 15, 2023
2 parents 9b67be6 + 62bbee8 commit 805e19b
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 158 deletions.
151 changes: 84 additions & 67 deletions ksp_plugin/interface_flight_plan.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "ksp_plugin/interface.hpp"

#include <vector>
#include <utility>

#include "base/not_null.hpp"
Expand Down Expand Up @@ -220,6 +221,16 @@ bool __cdecl principia__FlightPlanExists(
return m.Return(plugin->GetVessel(vessel_guid)->has_flight_plan());
}

double __cdecl principia__FlightPlanGetActualFinalTime(
Plugin const* const plugin,
char const* const vessel_guid) {
journal::Method<journal::FlightPlanGetActualFinalTime> m(
{plugin, vessel_guid});
return m.Return(
ToGameTime(*plugin,
GetFlightPlan(*plugin, vessel_guid).actual_final_time()));
}

FlightPlanAdaptiveStepParameters __cdecl
principia__FlightPlanGetAdaptiveStepParameters(
Plugin const* const plugin,
Expand All @@ -233,16 +244,6 @@ principia__FlightPlanGetAdaptiveStepParameters(
flight_plan.generalized_adaptive_step_parameters()));
}

double __cdecl principia__FlightPlanGetActualFinalTime(
Plugin const* const plugin,
char const* const vessel_guid) {
journal::Method<journal::FlightPlanGetActualFinalTime> m(
{plugin, vessel_guid});
return m.Return(
ToGameTime(*plugin,
GetFlightPlan(*plugin, vessel_guid).actual_final_time()));
}

OrbitAnalysis* __cdecl principia__FlightPlanGetCoastAnalysis(
Plugin const* const plugin,
char const* const vessel_guid,
Expand Down Expand Up @@ -409,6 +410,79 @@ int __cdecl principia__FlightPlanNumberOfSegments(
return m.Return(GetFlightPlan(*plugin, vessel_guid).number_of_segments());
}

int __cdecl principia__FlightPlanOptimizationDriverInProgress(
Plugin const* const plugin,
char const* const vessel_guid) {
journal::Method<journal::FlightPlanOptimizationDriverInProgress> m(
{plugin, vessel_guid});
CHECK_NOTNULL(plugin);
auto& vessel = *plugin->GetVessel(vessel_guid);
auto const maybe_parameters = vessel.FlightPlanOptimizationDriverInProgress();
if (maybe_parameters.has_value()) {
return m.Return(maybe_parameters->index);
} else {
return m.Return(-1);
}
}

void __cdecl principia__FlightPlanOptimizationDriverMake(
Plugin const* const plugin,
char const* const vessel_guid,
double const distance,
double const* const inclination_in_degrees,
int const celestial_index,
NavigationFrameParameters const navigation_frame_parameters) {
journal::Method<journal::FlightPlanOptimizationDriverMake> m(
{plugin,
vessel_guid,
distance,
inclination_in_degrees,
celestial_index,
navigation_frame_parameters});
CHECK_NOTNULL(plugin);
auto& vessel = *plugin->GetVessel(vessel_guid);
const auto& celestial = plugin->GetCelestial(celestial_index);

std::vector<FlightPlanOptimizer::MetricFactory> factories = {
FlightPlanOptimizer::ForCelestialDistance(
/*celestial=*/&celestial,
/*target_distance=*/distance * Metre),
FlightPlanOptimizer::ForΔv()};
std::vector<double> weights = {1, 1e3};
if (inclination_in_degrees != nullptr) {
factories.push_back(FlightPlanOptimizer::ForInclination(
&celestial,
[plugin, navigation_frame_parameters]() {
return NewNavigationFrame(*plugin, navigation_frame_parameters);
},
*inclination_in_degrees * Degree));
weights.push_back(1e6);
}

vessel.MakeFlightPlanOptimizationDriver(
FlightPlanOptimizer::LinearCombination(factories, weights));

return m.Return();
}

void __cdecl principia__FlightPlanOptimizationDriverStart(
Plugin const* const plugin,
char const* const vessel_guid,
int const manœuvre_index) {
journal::Method<journal::FlightPlanOptimizationDriverStart> m(
{plugin,
vessel_guid,
manœuvre_index});
CHECK_NOTNULL(plugin);
auto& vessel = *plugin->GetVessel(vessel_guid);

vessel.StartFlightPlanOptimizationDriver(
{.index = manœuvre_index,
.Δv_tolerance = 1 * Micro(Metre) / Second});

return m.Return();
}

Status* __cdecl principia__FlightPlanRebase(Plugin const* const plugin,
char const* const vessel_guid,
double const mass_in_tonnes) {
Expand Down Expand Up @@ -578,63 +652,6 @@ int __cdecl principia__FlightPlanSelected(Plugin const* const plugin,
return m.Return(plugin->GetVessel(vessel_guid)->selected_flight_plan_index());
}

bool __cdecl principia__FlightPlanOptimizationInProgress(
Plugin const* const plugin,
char const* const vessel_guid) {
journal::Method<journal::FlightPlanOptimizationInProgress> m(
{plugin, vessel_guid});
CHECK_NOTNULL(plugin);
auto const* driver =
plugin->GetVessel(vessel_guid)->flight_plan_optimization_driver();
return m.Return(driver != nullptr && !driver->done());
}

void __cdecl principia__FlightPlanOptimizeManoeuvre(
Plugin const* const plugin,
char const* const vessel_guid,
int const manœuvre_index,
int const celestial_index,
double const distance,
double const inclination_in_degrees,
NavigationFrameParameters const navigation_frame_parameters) {
journal::Method<journal::FlightPlanOptimizeManoeuvre> m(
{plugin,
vessel_guid,
manœuvre_index,
celestial_index,
distance,
inclination_in_degrees,
navigation_frame_parameters});
CHECK_NOTNULL(plugin);
auto& vessel = *plugin->GetVessel(vessel_guid);
{
auto* const old_driver = vessel.flight_plan_optimization_driver();
if (old_driver != nullptr) {
old_driver->Interrupt();
}
}
vessel.MakeFlightPlanOptimizationDriver(
FlightPlanOptimizer::LinearCombination(
{FlightPlanOptimizer::ForCelestialDistance(
/*celestial=*/&plugin->GetCelestial(celestial_index),
/*target_distance=*/distance * Metre),
FlightPlanOptimizer::ForInclination(
&plugin->GetCelestial(celestial_index),
[plugin, navigation_frame_parameters]() {
return NewNavigationFrame(*plugin,
navigation_frame_parameters);
},
inclination_in_degrees * Degree),
FlightPlanOptimizer::ForΔv()},
{1, 1e6, 1e3}));

const FlightPlanOptimizationDriver::Parameters parameters{
.index = manœuvre_index,
.Δv_tolerance = 1 * Micro(Metre) / Second};
vessel.flight_plan_optimization_driver()->RequestOptimization(parameters);
return m.Return();
}

Status* __cdecl principia__FlightPlanSetAdaptiveStepParameters(
Plugin const* const plugin,
char const* const vessel_guid,
Expand Down
31 changes: 25 additions & 6 deletions ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,35 @@ void Vessel::MakeFlightPlanOptimizationDriver(
CHECK(has_deserialized_flight_plan());
auto& [flight_plan, optimization_driver] =
std::get<OptimizableFlightPlan>(selected_flight_plan());
if (optimization_driver != nullptr) {
optimization_driver->Interrupt();
}
optimization_driver = make_not_null_unique<FlightPlanOptimizationDriver>(
*flight_plan, std::move(metric_factory));
}

void Vessel::StartFlightPlanOptimizationDriver(
FlightPlanOptimizationDriver::Parameters const& parameters) {
CHECK(has_deserialized_flight_plan());
auto const& driver = std::get<OptimizableFlightPlan>(selected_flight_plan())
.optimization_driver;
CHECK_NOTNULL(driver);
last_optimization_parameters_ = parameters;
driver->RequestOptimization(parameters);
}

std::optional<FlightPlanOptimizationDriver::Parameters>
Vessel::FlightPlanOptimizationDriverInProgress() const {
auto const& driver = std::get<OptimizableFlightPlan>(selected_flight_plan())
.optimization_driver;
if (driver != nullptr && !driver->done()) {
CHECK(last_optimization_parameters_.has_value());
return last_optimization_parameters_;
} else {
return std::nullopt;
}
}

bool Vessel::UpdateFlightPlanFromOptimization() {
CHECK(has_deserialized_flight_plan());
auto& [flight_plan, optimization_driver] =
Expand All @@ -371,12 +396,6 @@ bool Vessel::UpdateFlightPlanFromOptimization() {
return false;
}

FlightPlanOptimizationDriver* Vessel::flight_plan_optimization_driver() {
CHECK(has_deserialized_flight_plan());
return std::get<OptimizableFlightPlan>(selected_flight_plan())
.optimization_driver.get();
}

void Vessel::ReadFlightPlanFromMessage() {
if (!flight_plans_.empty() &&
std::holds_alternative<serialization::FlightPlan>(
Expand Down
15 changes: 13 additions & 2 deletions ksp_plugin/vessel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,21 @@ class Vessel {
// flight plan or the flight plan has not been deserialized.
virtual FlightPlan& flight_plan() const;

// Constructs a new driver for the given metric (but doesn't start it). If
// there is a driver currently running it is interrupted and destroyed.
virtual void MakeFlightPlanOptimizationDriver(
FlightPlanOptimizer::MetricFactory metric_factory);

virtual bool UpdateFlightPlanFromOptimization();
// Starts an optimization with the given parameters.
virtual void StartFlightPlanOptimizationDriver(
FlightPlanOptimizationDriver::Parameters const& parameters);

// If an optimization is in progress, returns the parameters of the
// optimization.
virtual std::optional<FlightPlanOptimizationDriver::Parameters>
FlightPlanOptimizationDriverInProgress() const;

virtual FlightPlanOptimizationDriver* flight_plan_optimization_driver();
virtual bool UpdateFlightPlanFromOptimization();

// Deserializes the flight plan if it is held lazily by this object. Does
// nothing if there is no such flight plan. If |has_flight_plan| returns
Expand Down Expand Up @@ -433,6 +442,8 @@ class Vessel {

std::vector<LazilyDeserializedFlightPlan> flight_plans_;
int selected_flight_plan_index_ = -1;
std::optional<FlightPlanOptimizationDriver::Parameters>
last_optimization_parameters_;

std::optional<OrbitAnalyser> orbit_analyser_;

Expand Down
22 changes: 20 additions & 2 deletions ksp_plugin_adapter/burn_editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,9 @@ public Event Render(
index == 0
? L10N.CacheFormat(
"#Principia_BurnEditor_TimeBase_StartOfFlightPlan")
: L10N.CacheFormat("#Principia_BurnEditor_TimeBase_EndOfManœuvre",
index),
: L10N.CacheFormat(
"#Principia_BurnEditor_TimeBase_EndOfManœuvre",
index),
style : new UnityEngine.GUIStyle(UnityEngine.GUI.skin.label){
alignment = UnityEngine.TextAnchor.UpperLeft
});
Expand All @@ -259,6 +260,23 @@ public Event Render(
UnityEngine.GUILayout.Label(L10N.CacheFormat(
"#Principia_BurnEditor_Duration",
duration_.ToString("0.0")));

if (adapter_.plotting_frame_selector_.
Centre() is CelestialBody centre) {
string vessel_guid = vessel_.id.ToString();
int optimized_index =
plugin.FlightPlanOptimizationDriverInProgress(vessel_guid);
if (optimized_index == index) {
UnityEngine.GUILayout.Label(
L10N.CacheFormat("#Principia_BurnEditor_OptimizingThis"));
} else if (optimized_index != -1) {
UnityEngine.GUILayout.Label(
L10N.CacheFormat("#Principia_BurnEditor_OptimizingOther"));
} else if (UnityEngine.GUILayout.Button(
L10N.CacheFormat("#Principia_BurnEditor_Optimize"))) {
plugin.FlightPlanOptimizationDriverStart(vessel_guid, index);
}
}
}
UnityEngine.GUILayout.Label(engine_warning_,
Style.Warning(UnityEngine.GUI.skin.label));
Expand Down
Loading

0 comments on commit 805e19b

Please sign in to comment.