mockingbirdnest / Principia

đť‘›-Body and Extended Body Gravitation for Kerbal Space Program
MIT License
767 stars 69 forks source link

[Request] Multiple nodes editing #1936

Closed xiaoqianWX closed 5 years ago

xiaoqianWX commented 6 years ago

Now, in Principia, if you want to edit the earlier node after planning many nodes, you have to delete the node in front of it, and adding it back after finish editing that node, and the effect to the after node would be a problem, because there's not a way unless you add it back on. But when there's too many nodes, it's kind of impossible to delete them and add them on again. The request is I can edit nodes earlier anytime, so multiple node orbit planning could get a solution. Another request is choose to show how will next node be after completing this node, another way to say it is show the after node dynamically, so if there is a little error, caused by RCS or other things, Principia could still show wether the node you planned before is working or need fix, instead of delete the whole flight plan then add nodes back on again.

xiaoqianWX commented 6 years ago

Thanks

kc9jud commented 5 years ago

If I wanted to take a crack at this and come up with a PR, where should I start? It looks like ksp_plugin/interface_flight_plan.cpp, ksp_plugin/flight_plan.hpp, and ksp_plugin/flight_plan.cpp are relevant? Are there any particular caveats I should be aware of?

eggrobin commented 5 years ago

@kc9jud

where should I start

The first thing to do before starting to write code to resolve this issue is to figure out what the exact behaviour should be. We have been unsure about that, which is one of the reasons why we have not made progress here.

Right now, the manoeuvres are specified with an absolute time, conceptually, something like “starting at 2019-02-17T00:38:52 UTC, impart a Δv of 300 m/s in the tangent direction, 5 m/s in the normal direction, 10 m/s in the binormal direction, with the Frenet frame defined by the trajectory in the ECI frame”.

The problem is that with such a specification, changing an earlier burn is likely to turn later ones into nonsense. For instance, if the flight plan consists of a translunar injection (TLI) from a circular low earth orbit, followed by a capture into lunar orbit, changing the timing of the TLI will have the effect of putting the capture burn in the middle of nowhere, either on the way to the Moon or on the way back; it will cease to be a capture burn, and will have to be moved back to the right place to become one again.

We think a possible approach here would be to somehow define the manoeuvre timings with respect to trajectory “events”, e.g., to define a manoeuvre as “starting at 30 s before perigee, impart a Δv of 300 m/s in the tangent direction, 5 m/s in the normal direction, 10 m/s in the binormal direction, with the Frenet frame defined by the trajectory in the ECI frame”.

In our example, this would allow a lunar capture burn to be created with respect to the perilune, and thus to move with the injection, remaining a capture burn and requiring only minor adjustment after the rescheduling of the translunar injection.

There are however many issues about the precise semantics that need to be sorted out:

There are probably many more issues like this. We need to get to a good understanding of the desired behaviour (including error conditions: we should reject changes to the flight plan that would lead to overlapping manoeuvres, to reordering of manoeuvres, etc.).

Once we have figured out the exact details of the behaviour we want, we can start looking at the implementation (this will likely start with some changes to the FlightPlan* function in the serializable interface); but in a sense, this is the easy part (at least for us; this codebase is probably a bit daunting at first).

Are there any particular caveats I should be aware of?

The Principia codebase is rather complicated (for instance we have dedicated libraries for handling physical quantities, reference frames, etc.), so you may want to take some time to familiarize yourself with it. Unfortunately we don't really have much in the way of documentation (the documentation directory mostly has very specific technical notes like the documentation for the calculations performed by Geopotential), but the technical overview in the wiki might help you find your way around.

pleroy commented 5 years ago

@kc9jud

Indeed, helping us to figure out what to do would be extremely valuable, irrespective of the coding details. Maybe starting a shared document where we could throw ideas and have a discussion would be a good first step.

We also need to think of the UI, so we'd want to have rough mocks/scenarios to decide how the user would control burns anchored at an event. Clicking on the Ap/Pe marker might be a good model. In general we are not particularly happy with the current flight plan UI so a major revamp might make sense.

kc9jud commented 5 years ago

@eggrobin @pleroy

I'm completely on board with spec'ing this out before writing any code... I've spent enough time rewriting my own code to have learned that lesson. Some initial thoughts:

  1. Keeping the absolute times may not actually be so much of an issue -- my imagined workflow was that I'd likely rough in the entire flight plan sequentially, then make minor adjustments, e.g. fine-tuning Δv, iterating back and forth between different nodes. For the example involving a TLI, this would mean setting up the TLI and capture burns, then make minor timing and Δv adjustments to the TLI, then the capture, then the TLI, etc., until I "converge" to a result that's good enough. Obviously, this means I can't make large changes all at once, or the capture burn becomes nonsense; this may still be good enough.

  2. I'm intrigued by the idea of indexing them to trajectory events, however I can see the issues with events going in and out of "scope". One other idea I had, though I haven't tried sitting down to do the calculus of variations, is to try and minimize the change to trajectory after later nodes by changing the time of the next node. I'm thinking some kind of least-squares minimization of the difference between the two trajectories, where we adjust the next node time as the parameter. It seems like it might exist for a two-node plan, but might not make sense beyond that.

  3. I've taken a bit of a look at the source code -- it looks like it's a reasonably standard C++11/14 template library, so I'm not worried about that when we get there.

nornagon commented 5 years ago

Keeping the absolute times would match what vanilla does, and might be a "good enough" solution to unblock further work like #1964 :)

pleroy commented 5 years ago

(Sorry for dropping the ball, we were on vacation.)

I agree that a good first step would be to keep the absolute times while allowing the elements of the burn to edited. It seems simple enough, it would improve usability, and it would make it possible to evaluate the next steps.

There are two prerequisites to this:

  1. The UI code is in need of some serious cleanup and restructuring before we can even think of changing it. I started working on this, but it's a multi-kSLOC effort.
  2. The computation of the flight plan must be optimized so that only the required parts are recomputed, otherwise there will be too much lag, and probably done asynchronously.
pleroy commented 5 years ago

Would like to solicit input on error reporting. In the current UI (as of Fano), dragging a slider beyond the point that's acceptable (e.g., trying to move a manoeuvre after the end of the flight plan) causes the slider to effectively block and have no effect. It seems rather natural, although to be honest we don't tell you in any way why the slider blocks.

In the next version (Fáry) we support text entry. So you can enter, say, a new start time for the manoeuvre and have it reverted without explanation to the previous value. This is increasing the "mysteriousness" of the UI.

Once we start being able to edit manoeuvres other than the last there can be more failure modes: maybe the manoeuvre being edited overlaps with the next one or it causes some further integration to time out or the flight plan to go through a singularity (centre of a planet). How do we report this? We probably don't want to bring up a modal dialog box each time something goes awry but at the same time we want to communicate to the user details of what's happening.

This being largely a UI question I expect at least as many opinions as respondents. Also remember that there are limitations to what Unity will let us do, at least with the GUILayout that we are currently using.

scimas commented 5 years ago

I haven't played in many many days so I may remember things incorrectly.

How do we report this?

If I remember correctly, there is a text area under the flight plan length slider (or is it on the main Principia UI?) where you display a message whenever the flight plan times out. You could repurpose it to show all errors. If the rest of the UI becomes smaller, you could increase the size of the text field to make it really obvious. The text colour of that field and any reverted values can be set to red to make it clear which values the user would have to tweak again.

You may also want to make corrections to the flight plan silently in some cases; like extending the length of the flight plan if the entered node is farther in the future than currently permitted. This will of course place the responsibility on the user to not enter outrageously large value in there.