Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 51cc0a2dbfe3
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f6590f49e711
Choose a head ref
  • 5 commits
  • 12 files changed
  • 1 contributor

Commits on Aug 2, 2020

  1. insertion

    eggrobin committed Aug 2, 2020
    Copy the full SHA
    1b56fa2 View commit details
  2. Fix rebasing.

    eggrobin committed Aug 2, 2020
    Copy the full SHA
    83f1735 View commit details

Commits on Aug 3, 2020

  1. After pleroy’s review

    eggrobin committed Aug 3, 2020
    Copy the full SHA
    cf15c3c View commit details
  2. _

    eggrobin committed Aug 3, 2020
    Copy the full SHA
    4f8b751 View commit details
  3. Merge pull request #2661 from eggrobin/insert

    Insertion and out-of-order removal of manœuvres
    eggrobin authored Aug 3, 2020
    Copy the full SHA
    f6590f4 View commit details
80 changes: 47 additions & 33 deletions ksp_plugin/flight_plan.cpp
Original file line number Diff line number Diff line change
@@ -97,22 +97,24 @@ NavigationManœuvre const& FlightPlan::GetManœuvre(int const index) const {
return manœuvres_[index];
}

Status FlightPlan::Append(NavigationManœuvre::Burn const& burn) {
Status FlightPlan::Insert(NavigationManœuvre::Burn const& burn,
int const index) {
CHECK_GE(index, 0);
CHECK_LE(index, number_of_manœuvres());
NavigationManœuvre const manœuvre(
manœuvres_.empty() ? initial_mass_ : manœuvres_.back().final_mass(),
index == 0 ? initial_mass_ : manœuvres_[index - 1].final_mass(),
burn);
if (manœuvre.IsSingular()) {
return Singular();
}
if (!manœuvre.FitsBetween(start_of_last_coast(), desired_final_time_)) {
if (!manœuvre.FitsBetween(start_of_previous_coast(index),
start_of_burn(index))) {
return DoesNotFit();
}
// Reset the last coast and integrate it followed by a burn followed by a new
// last coast;
manœuvres_.push_back(manœuvre);
ResetLastSegment();
return ComputeSegments(manœuvres_.begin() + manœuvres_.size() - 1,
manœuvres_.end());
manœuvres_.insert(manœuvres_.begin() + index, manœuvre);
UpdateInitialMassOfManœuvresAfter(index);
PopSegmentsAffectedByManœuvre(index);
return ComputeSegments(manœuvres_.begin() + index, manœuvres_.end());
}

void FlightPlan::ForgetBefore(Instant const& time,
@@ -154,14 +156,13 @@ void FlightPlan::ForgetBefore(Instant const& time,
initial_degrees_of_freedom_ = root_begin->degrees_of_freedom;
}

Status FlightPlan::RemoveLast() {
CHECK(!manœuvres_.empty());
manœuvres_.pop_back();
PopLastSegment(); // Last coast.
PopLastSegment(); // Last burn.
// Clear and recompute the last coast.
ResetLastSegment();
return ComputeSegments(manœuvres_.end(), manœuvres_.end());
Status FlightPlan::Remove(int index) {
CHECK_GE(index, 0);
CHECK_LT(index, number_of_manœuvres());
manœuvres_.erase(manœuvres_.begin() + index);
UpdateInitialMassOfManœuvresAfter(index);
PopSegmentsAffectedByManœuvre(index);
return ComputeSegments(manœuvres_.begin() + index, manœuvres_.end());
}

Status FlightPlan::Replace(NavigationManœuvre::Burn const& burn,
@@ -191,21 +192,10 @@ Status FlightPlan::Replace(NavigationManœuvre::Burn const& burn,
// follow as they may have a different initial mass. Also pop the segments
// that we'll recompute.
manœuvres_[index] = manœuvre;
PopLastSegment(); // Last coast.
PopLastSegment(); // Last burn.

Mass initial_mass = manœuvre.final_mass();
for (int i = index + 1; i < manœuvres_.size(); ++i) {
manœuvres_[i] = NavigationManœuvre(initial_mass, manœuvres_[i].burn());
initial_mass = manœuvres_[i].final_mass();
PopLastSegment(); // Last coast.
PopLastSegment(); // Last burn.
}
UpdateInitialMassOfManœuvresAfter(index);

// TODO(phl): Recompute as late as possible.
// At this point the last coast is the one to which |manœuvre| gets attached.
// Clear it and recompute everything that follows.
ResetLastSegment();
PopSegmentsAffectedByManœuvre(index);
return ComputeSegments(manœuvres_.begin() + index, manœuvres_.end());
}

@@ -477,14 +467,38 @@ void FlightPlan::PopLastSegment() {
}
}

void FlightPlan::PopSegmentsAffectedByManœuvre(int const index) {
// We will keep, for each manœuvre in [0, index[, its burn and the coast
// preceding it, as well as the coast preceding manœuvre |index|.
int const segments_kept = 2 * index + 1;
while (number_of_segments() > segments_kept) {
PopLastSegment();
}
ResetLastSegment();
}

void FlightPlan::UpdateInitialMassOfManœuvresAfter(int const index) {
if (index >= manœuvres_.size()) {
return;
}
Mass initial_mass = manœuvres_[index].final_mass();
for (int i = index + 1; i < manœuvres_.size(); ++i) {
manœuvres_[i] = NavigationManœuvre(initial_mass, manœuvres_[i].burn());
initial_mass = manœuvres_[i].final_mass();
}
}

Instant FlightPlan::start_of_last_coast() const {
return manœuvres_.empty() ? initial_time_ : manœuvres_.back().final_time();
}

Instant FlightPlan::start_of_burn(int const index) const {
return index == manœuvres_.size() ? desired_final_time_
: manœuvres_[index].initial_time();
}

Instant FlightPlan::start_of_next_burn(int const index) const {
return index == manœuvres_.size() - 1
? desired_final_time_
: manœuvres_[index + 1].initial_time();
return start_of_burn(index + 1);
}

Instant FlightPlan::start_of_previous_coast(int const index) const {
30 changes: 21 additions & 9 deletions ksp_plugin/flight_plan.hpp
Original file line number Diff line number Diff line change
@@ -73,12 +73,12 @@ class FlightPlan {
// [0, number_of_manœuvres()[.
virtual NavigationManœuvre const& GetManœuvre(int index) const;

// Appends a manœuvre using the specified |burn|. |index| must be in
// [0, number_of_manœuvres()[. Returns an error and has no effect if the
// given |burn| cannot fit between the preceding burn and the end of the
// flight plan. Otherwise, updates the flight plan and returns the
// integration status.
virtual Status Append(NavigationManœuvre::Burn const& burn);
// Inserts a manœuvre at the given |index| using the specified |burn|. |index|
// must be in [0, number_of_manœuvres()]. Returns an error and has no effect
// if the given |burn| cannot fit between the preceding burn and the following
// one or the end of the flight plan. Otherwise, updates the flight plan and
// returns the integration status.
virtual Status Insert(NavigationManœuvre::Burn const& burn, int index);

// Forgets the flight plan at least before |time|. The actual cutoff time
// will be in a coast trajectory and may be after |time|. |on_empty| is run
@@ -88,8 +88,9 @@ class FlightPlan {
std::function<void()> const& on_empty);


// Removes the last manœuvre.
virtual Status RemoveLast();
// Removes the manœuvre with the given |index|, which must be in
// [0, number_of_manœuvres()[.
virtual Status Remove(int index);

// Replaces a manœuvre with one using the specified |burn|. |index| must be
// in [0, number_of_manœuvres()[. Returns an error and has no effect if the
@@ -98,7 +99,7 @@ class FlightPlan {
virtual Status Replace(NavigationManœuvre::Burn const& burn, int index);

// Updates the desired final time of the flight plan. Returns an error and
// has no effect |desired_final_time| is before the beginning of the last
// has no effect if |desired_final_time| is before the beginning of the last
// coast.
virtual Status SetDesiredFinalTime(Instant const& desired_final_time);

@@ -182,9 +183,20 @@ class FlightPlan {
// anomalous trajectories, their number is decremented and may become 0.
void PopLastSegment();

// Pops the burn of the manœuvre with the given index and all following
// segments, then resets the last segment (which is the coast preceding
// |manœuvres_[index]|).
void PopSegmentsAffectedByManœuvre(int index);

// Reconstructs each manœuvre after |manœuvres_[index]| (starting with
// |manœuvres_[index + 1]|), keeping the same burns but recomputing the
// initial masses from |manœuvres_[index].final_mass()|.
void UpdateInitialMassOfManœuvresAfter(int index);

Instant start_of_last_coast() const;

// In the following functions, |index| refers to the index of a manœuvre.
Instant start_of_burn(int index) const;
Instant start_of_next_burn(int index) const;
Instant start_of_previous_coast(int index) const;

22 changes: 13 additions & 9 deletions ksp_plugin/interface_flight_plan.cpp
Original file line number Diff line number Diff line change
@@ -169,13 +169,16 @@ NavigationManoeuvre ToInterfaceNavigationManoeuvre(

} // namespace

Status* __cdecl principia__FlightPlanAppend(Plugin const* const plugin,
Status* __cdecl principia__FlightPlanInsert(Plugin const* const plugin,
char const* const vessel_guid,
Burn const burn) {
journal::Method<journal::FlightPlanAppend> m({plugin, vessel_guid, burn});
Burn const burn,
int const index) {
journal::Method<journal::FlightPlanInsert> m(
{plugin, vessel_guid, burn, index});
CHECK_NOTNULL(plugin);
return m.Return(ToNewStatus(GetFlightPlan(*plugin, vessel_guid)
.Append(FromInterfaceBurn(*plugin, burn))));
return m.Return(
ToNewStatus(GetFlightPlan(*plugin, vessel_guid)
.Insert(FromInterfaceBurn(*plugin, burn), index)));
}

void __cdecl principia__FlightPlanCreate(Plugin const* const plugin,
@@ -354,12 +357,13 @@ Status* __cdecl principia__FlightPlanRebase(Plugin const* const plugin,
return m.Return(ToNewStatus(status));
}

Status* __cdecl principia__FlightPlanRemoveLast(Plugin const* const plugin,
char const* const vessel_guid) {
journal::Method<journal::FlightPlanRemoveLast> m({plugin, vessel_guid});
Status* __cdecl principia__FlightPlanRemove(Plugin const* const plugin,
char const* const vessel_guid,
int const index) {
journal::Method<journal::FlightPlanRemove> m({plugin, vessel_guid, index});
CHECK_NOTNULL(plugin);
return m.Return(
ToNewStatus(GetFlightPlan(*plugin, vessel_guid).RemoveLast()));
ToNewStatus(GetFlightPlan(*plugin, vessel_guid).Remove(index)));
}

void __cdecl principia__FlightPlanRenderedApsides(
2 changes: 1 addition & 1 deletion ksp_plugin/vessel.cpp
Original file line number Diff line number Diff line change
@@ -336,7 +336,7 @@ Status Vessel::RebaseFlightPlan(Mass const& initial_mass) {
i < original_flight_plan->number_of_manœuvres();
++i) {
auto const& manœuvre = original_flight_plan->GetManœuvre(i);
flight_plan_->Append(manœuvre.burn());
flight_plan_->Insert(manœuvre.burn(), i - first_manœuvre_kept);
}
return Status::OK;
}
24 changes: 15 additions & 9 deletions ksp_plugin_adapter/burn_editor.cs
Original file line number Diff line number Diff line change
@@ -9,12 +9,12 @@ public BurnEditor(PrincipiaPluginAdapter adapter,
Vessel vessel,
double initial_time,
int index,
BurnEditor previous_burn) {
Func<int, BurnEditor> get_burn_at_index) {
adapter_ = adapter;
vessel_ = vessel;
initial_time_ = initial_time;
index_ = index;
previous_burn_ = previous_burn;
this.index = index;
get_burn_at_index_ = get_burn_at_index;
Δv_tangent_ =
new DifferentialSlider(label : "Δv tangent",
unit : "m / s",
@@ -60,7 +60,8 @@ public BurnEditor(PrincipiaPluginAdapter adapter,
// changed.
public bool Render(string header,
bool anomalous,
double burn_final_time) {
double burn_final_time,
Action delete) {
bool changed = false;
previous_coast_duration_.max_value = burn_final_time - time_base;
using (new UnityEngine.GUILayout.HorizontalScope()) {
@@ -73,6 +74,10 @@ public bool Render(string header,
UnityEngine.GUILayout.Label(
frame_info,
Style.RightAligned(Style.Info(UnityEngine.GUI.skin.label)));
if (UnityEngine.GUILayout.Button("Delete", GUILayoutWidth(2))) {
delete();
changed = true;
}
}
using (new UnityEngine.GUILayout.VerticalScope()) {
// When we are first rendered, the |initial_mass_in_tonnes_| will just have
@@ -132,8 +137,8 @@ public bool Render(string header,
}
}
UnityEngine.GUILayout.Label(
index_ == 0 ? "Time base: start of flight plan"
: $"Time base: end of manœuvre #{index_}",
index == 0 ? "Time base: start of flight plan"
: $"Time base: end of manœuvre #{index}",
style : new UnityEngine.GUIStyle(UnityEngine.GUI.skin.label){
alignment = UnityEngine.TextAnchor.UpperLeft});
using (new UnityEngine.GUILayout.HorizontalScope()) {
@@ -288,13 +293,15 @@ internal bool TryParsePreviousCoastDuration(string text, out double value) {
return true;
}

private double time_base => previous_burn_?.final_time ??
private double time_base => previous_burn?.final_time ??
plugin.FlightPlanGetInitialTime(
vessel_.id.ToString());

private double final_time => initial_time_ + duration_;

private IntPtr plugin => adapter_.Plugin();
public int index { private get; set; }
private BurnEditor previous_burn => get_burn_at_index_(index - 1);

private bool is_inertially_fixed_;
private readonly DifferentialSlider Δv_tangent_;
@@ -317,8 +324,7 @@ internal bool TryParsePreviousCoastDuration(string text, out double value) {

// Not owned.
private readonly Vessel vessel_;
private readonly int index_;
private readonly BurnEditor previous_burn_;
private readonly Func<int, BurnEditor> get_burn_at_index_;
private readonly PrincipiaPluginAdapter adapter_;

private bool changed_reference_frame_ = false;
Loading