Jump to content

[1.4][1.7.7] GravityTurn continued - Automated Efficient Launches


AndyMt

Recommended Posts

I thought up another request. I've always wanted to compare my own ascent profile to GravityTurns and find out just where I'm having the most problems. It'd be cool if I could leave the GT window up while doing my own ascent, and have it continue to track all the statistics (Gravity Losses, Drag Losses, and Vector Losses).

Link to comment
Share on other sites

14 minutes ago, StevieC said:

One other feature that would be a godsend is a way to specify the periapsis that you want to have BEFORE the circularizing burn. That would be helpful in preventing expended lower stages from accumulating as debris.

That one is likely to be antithetical to the point of the mod - GravityTurn doesn't keep track of the periapsis, from what I can tell.  It only cares about the apoapsis, and the time to.

(I do wish KSP cleaned these up better, and I'm experimenting with a couple of different ways to handle them for myself, but I don't think this is specifically GravityTurn's problem, and I suspect it would be a major code change to work on - and it would likely decrease the efficiency of the launch at the same time.)

Link to comment
Share on other sites

13 minutes ago, StevieC said:

Some of us would consider it worth sacrificing fuel to prevent Kessler syndrome, is my point.

Oh, I can agree.  I just think it's likely to be something that's going to be more work than it's likely to be worth - as in, a complete change of the code base.

Link to comment
Share on other sites

On 9/27/2016 at 8:17 AM, steve_v said:

Quick FYI: GravityTurn 1.5 appears to be making large ammounts of garbage in 1.2.1540... to the tune of 40MB/s+. This induces much lag. :(
Nothing conerning in the log (exception-free, no noise from GravityTurn).
Screenies (same save, same craft, -/+ GravityTurn), note memgraph "last" value:

Can repro reliably (and grab logs etc. if you want them), GT is the only requirement to see a ~40MB/s increase in heap allocations.

Ouch.  This may need a de-Linq-ification like Squad's been doing (getting rid of "foreach" and "using System.Linq;").  A quick glance shows Linq is included in most of the files.

As a quick fix, just changing it so it doesn't do anything unless the main window is showing would help a lot - then it would only be slow while GravityTurn is doing something.

Basically wrap FixedUpdate and Update (https://github.com/AndyMt/GravityTurn/blob/master/GravityTurn/GravityTurn/GravityTurner.cs#L312-L327) in a "if (mainWindow.WindowVisible) { }".  Or maybe "if (Launching) { }" would make more sense?  If I get some time this week I could test this and put together a PR, but feel free to beat me to the punch. :) 

Link to comment
Share on other sites

I will definitely look into the memory garbage issue. Using mainWindow.WindowVisible is not a good idea because GT can still do it's job and be hidden after launch. But if(Launching) looks like the best way to do it as a first fix.

I was under the impression that de-Linq-ing is not necessary if you compile with Visual Studio? Because it compiles foreach differently?

Regarding feature requests:

@5thHorseman: I intended to make the statistics part a separate window anyway - so I'll think about this.
^^^^^^^^^^^^^^^ how do I "mention" someone and make the username formatted in this blue box?

 

Link to comment
Share on other sites

2 hours ago, AndyMt said:

^^^^^^^^^^^^^^^ how do I "mention" someone and make the username formatted in this blue box?

Looks like you did it correctly... Except when their name comes up in the dropbox, you MUST click it... Completely typing their whole name out does not seem to make it "linky".... Plus, even doing it correctly, seems to not work once in awhile... it seems very finicky to me...

Link to comment
Share on other sites

21 hours ago, AndyMt said:

I was under the impression that de-Linq-ing is not necessary if you compile with Visual Studio? Because it compiles foreach differently?

Linq and foreach are two different things.  You don't need to convert all your foreach loops into plain for loops unless the thing being enumerated happens to return an interface or class from GetEnumerator (even Squad no longer *need* to avoid foreach because Unity have updated the included compiler to fix the issue).  The problem with Linq is that quite a lot of the methods either create iterator objects or intermediate result arrays and these can get very large very quickly.  Some of the methods also make it very easy to create a closure where a lambda expression (=>, anonymous function) refers to something in local scope and this also creates garbage.

Link to comment
Share on other sites

21 hours ago, AndyMt said:

@5thHorseman: I intended to make the statistics part a separate window anyway - so I'll think about this.

^^^^^^^^^^^^^^^ how do I "mention" someone and make the username formatted in this blue box?

Cool thanks, and regarding the tagging problem...

18 hours ago, Stone Blue said:

Looks like you did it correctly... Except when their name comes up in the dropbox, you MUST click it... Completely typing their whole name out does not seem to make it "linky".... Plus, even doing it correctly, seems to not work once in awhile... it seems very finicky to me...

You can also arrow down and enter on the name. You also can NOT copy a name, hit @, and then paste the name.

Link to comment
Share on other sites

On 9/29/2016 at 11:06 AM, Padishar said:

Linq and foreach are two different things.  You don't need to convert all your foreach loops into plain for loops unless the thing being enumerated happens to return an interface or class from GetEnumerator (even Squad no longer *need* to avoid foreach because Unity have updated the included compiler to fix the issue).  The problem with Linq is that quite a lot of the methods either create iterator objects or intermediate result arrays and these can get very large very quickly.  Some of the methods also make it very easy to create a closure where a lambda expression (=>, anonymous function) refers to something in local scope and this also creates garbage.

Is there a wiki somewhere of good/bad practices with regards to making garbage for KSP?  I'm mostly working off of hearsay :)

Link to comment
Share on other sites

32 minutes ago, hab136 said:

Is there a wiki somewhere of good/bad practices with regards to making garbage for KSP?  I'm mostly working off of hearsay :)

There's nothing comprehensive or specific to KSP as far as I know, though there are various, more general, articles scattered about the internet about how to avoid garbage issues in Unity.  I've been intending to post a KSP specific guide (along with a description of how the memory allocation and garbage collection works) but technical writing isn't my strongest suit (nor do I particularly enjoy it) and I haven't yet found the time to get it together...

Link to comment
Share on other sites

16 hours ago, Padishar said:

There's nothing comprehensive or specific to KSP as far as I know, though there are various, more general, articles scattered about the internet about how to avoid garbage issues in Unity.  I've been intending to post a KSP specific guide (along with a description of how the memory allocation and garbage collection works) but technical writing isn't my strongest suit (nor do I particularly enjoy it) and I haven't yet found the time to get it together...

Well, I barely know what I'm doing but I can help write documentation :) 

http://wiki.kerbalspaceprogram.com/wiki/Garbage_Reduction

Feel free to edit!

Link to comment
Share on other sites

@hab136Thanks for that wiki entry, now I know more. Looks like foreach won't be an issue in this particular case - there aren't many and most are not affected. But I'll rewrite them anyway - just as second priority.

I looked into de-linqing the plugin. Well - most files have the "using System.Linq" just in there but don't actually use it.

Then there are 4 files left which actually make use of it. 2 of them should be easy to de-linq but FuelFlowSimulation.cs and StageController.cs look much more complicated. I've never used Linq in any "real" project - just because I find it hard to read. Too much of "syntactic suggar" if you ask me.

So I might have one or the other question in certain cases. But I'll give it a go.

Link to comment
Share on other sites

On 9/26/2016 at 9:23 PM, StevieC said:

Another feature that would be a godsend: Select another vessel as a target, and you're automatically set up to launch at the appropriate time, heading, and other parameters for a direct-ascent rendezvous with the target craft, at which point docking will be relatively easy. (direct-ascent rendezvous saves me so much fuel)

Ouch. I think that would be a rather difficult feature to have GT perform. Reason is that GT doesn't "predict" what the flight path is going to look like, it instead dynamically adjusts the throttle to make an optimal flight path. About the only way I can see getting this feature is to take note of the phase angle to the target at launch and then go through the entire launch and note the phase angle between the target and the AP of the flight. Then revert the flight back to the launch and use the phase angle of the previous launch and target to adjust the phase angle of the new launch by time warping. So you'll have to wait for *two* launches of GT to get the intercept you really want. And given how slow a GT launch is, do you really want to wait for it twice? And those phase angle calculations assume that the target is in a circular orbit. 

Link to comment
Share on other sites

7 hours ago, John Cochran said:

Ouch. I think that would be a rather difficult feature to have GT perform. Reason is that GT doesn't "predict" what the flight path is going to look like, it instead dynamically adjusts the throttle to make an optimal flight path.

Agreed.. and I'd go further to say that the requested feature is really outside GT's scope. GT is, pure and simple, only about getting you into orbit as efficiently as possible.

Link to comment
Share on other sites

So - I've de-linq-ed the plugin now - and by doing that introduced some new bugs I'd like to iron out first before the next release. I've noticed a considerable amount of GravityTurn's code is 1:1 copies from @sarbian's MechJeb. I'll update the thread before the next release to reflect that. But this fact helped me to de-linq these parts "easily".

Garbage is now reduced to below 10% of the initial amount. Currently it's just the UI which seems to be causing all the rest of the garbage. The way the UI is shown seems a bit strange - it's drawn and layouted every frame... But maybe that's the way UIs work in Unity (WinForms and WPF is my world). I'll check some other Plugins to see how they do it - and learn how to make the UI scaleable in the process.

I prepared the debug version of the dll to be used with @Kramer's Kramax Plugin Reload, so I don't have to restart KSP every time I change something :). This helps enormously!

Now I have to figure out how to actually use the debugger with it. Just cannot attach to the KSP process... Any ideas?

Link to comment
Share on other sites

1 hour ago, AndyMt said:

it's drawn and layouted every frame

It is how 'old' onGui works. The new Unity UI works as any modern UI (create once, callbacks and the usual) but it is a lot harder to do from code. You can also create it in the Unity editor and load them as assets. There are some talk about how to do that in the modding sections.

And yes, a lot of that code is from MJ :)

Link to comment
Share on other sites

combination for old (recompiled for 1.2PRE) + Ascent StartTime (for now as no mechjeb available) is here

sorry i discovered this thread only now (search engines shows old one, and all code already written :( )

if @AndyMt interested we could coordinate efforts to make AscentStartTime available as plugin to both addons (mechjeb and GravityTurn)

Link to comment
Share on other sites

12 hours ago, sarbian said:

It is how 'old' onGui works. The new Unity UI works as any modern UI (create once, callbacks and the usual) but it is a lot harder to do from code.

That's how I'm used to doing it for 20 years or more now... Except that the IDEs and designer tools for the "create once" part got much better during that time. So I think it will be easier for me to understand and I'll try the Unity editor and loading assets. If you could please point me to one of those discussions, I haven't spotted them yet.

As soon as (if) you've updated MJ I want to think about an elegant way of sharing components or code between the 2 plugins.

 

9 hours ago, okder said:

combination for old (recompiled for 1.2PRE) + Ascent StartTime (for now as no mechjeb available) is here

sorry i discovered this thread only now (search engines shows old one, and all code already written :( )

if @AndyMt interested we could coordinate efforts to make AscentStartTime available as plugin to both addons (mechjeb and GravityTurn)

Yes, sure I'm interested in providing an API like MechJeb does (as an example). But first I have to refactor the whole thing.

Edited by AndyMt
Link to comment
Share on other sites

1 hour ago, AndyMt said:

If you could please point me to one of those discussions, I haven't spotted them yet.

I still need to make a clear post that explain it to people who are not used to Unity...

In the mean time here are the steps :
 - Design your UI in Unity with no reference to KSP code (my messy example Unity project)
 - Create a prefab from the UI object
 - Add that prefab to an AssetBundle
 - Loads that asset bundle with code in KSP
 - Link your code to the UI (same link that previous step)

Link to comment
Share on other sites

On 10/1/2016 at 5:12 PM, AndyMt said:

@hab136Thanks for that wiki entry, now I know more. Looks like foreach won't be an issue in this particular case - there aren't many and most are not affected. But I'll rewrite them anyway - just as second priority.

I looked into de-linqing the plugin. Well - most files have the "using System.Linq" just in there but don't actually use it.

Then there are 4 files left which actually make use of it. 2 of them should be easy to de-linq but FuelFlowSimulation.cs and StageController.cs look much more complicated. I've never used Linq in any "real" project - just because I find it hard to read. Too much of "syntactic suggar" if you ask me.

So I might have one or the other question in certain cases. But I'll give it a go.

 

I've got my own version that I compile for v1.1.2,  I've taken a look at fuelflowsimulation.cs

It copies the lookup dictionary, this is my version to avoid the copy.

public FuelFlowSimulation(IList<Part> parts, bool dVLinearThrust)
        {
            KpaToAtmospheres = PhysicsGlobals.KpaToAtmospheres;

            // Create FuelNodes corresponding to each Part
            ICollection<FuelNode> nodes;
            var nodeLookup = new Dictionary<Part, FuelNode>();
            foreach(var p in parts)
            {
                nodeLookup[p] = new FuelNode(p, dVLinearThrust);
            }

            nodes = nodeLookup.Values;

            // Determine when each part will be decoupled
            Part rootPart = parts[0]; // hopefully always correct
            nodeLookup[rootPart].AssignDecoupledInStage(rootPart, nodeLookup, -1);

            // Set up the fuel flow graph
            if (HighLogic.LoadedSceneIsFlight)
            {
                for (int i = 0; i < parts.Count; i++)
                {
                    Part p = parts[i];
                    nodeLookup[p].SetupFuelLineSourcesFlight(p, nodeLookup);
                }
            }
            else
            {
                for (int i = 0; i < parts.Count; i++)
                {
                    Part p = parts[i];
                    nodeLookup[p].SetupFuelLineSourcesFlight(p, nodeLookup);
                    nodeLookup[p].SetupFuelLineSourcesEditor(p, nodeLookup);
                }
            }
            for (int i = 0; i < parts.Count; i++)
            {
                Part p = parts[i];
                nodeLookup[p].SetupRegularSources(p, nodeLookup);
            }

            simStage = StageManager.LastStage + 1;

            // Add a fake stage if we are beyond the first one Mostly usefull for the Node Executor
            // who use the last stage info and fail to get proper info when the ship was never staged
            // and some engine were activated manually
            if (StageManager.CurrentStage > StageManager.LastStage)
                simStage++;

            t = 0;
            nodeLookup.Clear();
        }

 

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...