Noiredd / PEGAS

Powered Explicit Guidance Ascent System - a KSP & RO autopilot using the Space Shuttle guidance algorithm, UPFG
http://forum.kerbalspaceprogram.com/index.php?/topic/142213-pegas-powered-explicit-guidance-ascent-system-devlog
MIT License
114 stars 31 forks source link

gLim disengages #47

Open theLXMB opened 2 years ago

theLXMB commented 2 years ago

Hey, updating from v1.2 to v1.3 for most of my rockets the g limiter disengages between fairing separation and burnout of the first stage. This happens to all rockets where the fairings separate after PEGAS throttles the engines for constant acceleration. Nothing in the boot scripts changed, although I have changed the PEGAS code in a few ways: In 1.2:

In 1.3

This is the same launch vehicle with the same script, just going from 1.2 to 1.3 including everything mentioned above. The scaling is different, but the sudden throttling is easily noticable: Seeotter-I0145Pegas1 2 Seeotter-I0145Pegas1 3

And here the boot script as it originally was:

GLOBAL vehicle IS LIST(
        LEXICON(
            "name", "Seeotter-I Hauptstufe",
            "massTotal", 350767,
            "massFuel", 129898+158765,
            "gLim", 4.5,
            "minThrottle", 0.4,
            "engines", LIST(LEXICON("isp", 339.0, "thrust", 5939700)),
            "staging", LEXICON(
                    "jettison", FALSE,
                    "ignition", FALSE
                    )
            ),
        LEXICON(
            "name", "Polarfuchs-I 1",
            "massTotal", 42773,
            "massFuel", 6149+28931,
            "gLim", 1.6,
            "minThrottle", 0.0,
            "engines", LIST(LEXICON("isp", 468.0, "thrust", 240000)),
            "staging", LEXICON(
                    "jettison", TRUE,
                    "waitBeforeJettison", 0.5,
                    "ignition", TRUE,
                    "waitBeforeIgnition", 0.5,
                    "ullage", "rcs",
                    "ullageBurnDuration", 2,
                    "postUllageBurn", 4
                    )
            )
).
GLOBAL sequence IS LIST(
        LEXICON("time", -1.5, "type", "stage", "message", "Zuendung"),
        LEXICON("time", 0, "type", "stage", "message", "Start"),
        LEXICON("time", 155, "type", "jettison", "massLost", 2214, "message", "Abwurf Nutzlastverkleidung")
).  
GLOBAL controls IS LEXICON(
            "launchTimeAdvance", 150,
            "verticalAscentTime", 7,
            "pitchOverAngle", 5,
            "upfgActivation", 89
).
SET STEERINGMANAGER:ROLLTS TO 20.
SWITCH TO 0.
cd(seeotter).
CLEARSCREEN. 
run seeottertest.

With this rocket I could mitigate the problem by moving fairing separation within seconds of burnout without losing an appreciable amount of payload, as there is a around five second delay from jettison to 100% throttle. But with some vehicles it's immediate and I'd need to carry the fairings to way outside the atmosphere.

Apart from that, the ascent trajectory is so much smoother in 1.3, so really good work on that! I (mostly) really enjoy using PEGAS. ;)

Noiredd commented 2 years ago

Thanks for the super detailed report. So if I understand correctly: v1.2 correctly held constant acceleration, even if a jettison event occurred during the const-acc phase, but v1.3 suddenly throttles up at this event? And you're sure it's a throttle up, i.e. it's not possible that the mass drops so low that your engine even at the lowest throttle setting cannot hold the requested acceleration? (From the look of those awesome plots I suppose not, but just making sure.) If so, this certainly shouldn't happen. Sounds like an issue with the virtual stage generation, and if so, should be fairly easy to track. I'll look at this as soon as I can.

Also thanks for pointing out the issue with engine spool up. I've noticed this in my own designs, I'm pondering on how to do this. I'll open a separate issue for this and ping you there if I have any ideas.

Also thanks for the proof of concept for solving #45. I'll test it and push a fix.

Oh boy, v1.3.1 here we go ;D

theLXMB commented 2 years ago

Thank you for taking this on so quickly :D That is correct, in v1.2 gLim worked flawlessly with this exact launch vehicle. Apart from updating the PEGAS files I did nothing to the game. Reverting back to 1.2 eliminated the issue. Setting minThrottle to 0.0 didn't help. Fairing jettison happened - depending on payload mass - broadly in the middle between gLim engagement and burnout, so never too close to staging.

I remember vaguely, I had a similar problem when going from 1.1 to 1.2, but that was while designing a new launch vehicle, so I didn't think much of it and it has never happened since. Apart from what I mentioned above I don't remember changing anything else about the code in v1.2.

Great, I'll have a look into the spool up issue ;)

So yes, the #45 solution is more of a brute force approach. I noticed PEGAS crashing, saw this issue and simply went on reducing everything by 1. Don't know if this is a good solution, or simply works in this particular instance. The workaround didn't crash with other vehicles, so maybe it's ok :D Left is as in the release, right with my changes: Pegas1 3FlightPlan5ItemsPegas1 3FlightPlan4Items

Noiredd commented 1 year ago

Hi @theLXMB and sorry for the delay. I've pushed fixes for #45 and #46, feel free to check them out. However, this one will require more of my attention and time - I'll ask for a bit more of your patience, as I'll be unable to work on this for the next 3 weeks, perhaps longer.

In the meantime, if you were so kind to provide any details on your first stage (total & fuel mass, engine parameters) to make it easier for me to reproduce your case, I'd be very grateful.

theLXMB commented 1 year ago

Hey @Noiredd, I haven't had the time to play KSP myself for the last few weeks, so no problem ;) If I'm lucky I'll be able to have a look at your fixes next weekend. Although after I posted my "solution" for #45 I already had a launch vehicle which broke it, though I only tinkered with it for a few minutes after that... Hopefully your fix works. I'll admit that specific rocket is a bit of an edge case and I don't know if it'll work anyway, but I'll give you all the specifics in case it still crashes.

Regarding the gLim problem: calculated from the boot script above the dry mass of the first stage alone should be 17117, propellant 129898+158765, isp and thrust 339.0/5393700 I'll double check just in case.

Don't sweat it, take the time you need ;) I'm very thankful you're working on this!

Noiredd commented 1 year ago

Oh damn, I completely missed the "jettison", FALSE, ignition", FALSE in your script and for some reason thought that I'm not seeing the actual first stage (i.e. that you boost with something else and then switch to that one). Got it now, everything makes sense! :D

When I get back to this, I'll start with building something that resembles your vehicle as closely as I can, to hopefully reproduce the issue.

Noiredd commented 1 year ago

I managed to (roughly) recreate your vehicle today, getting most of the numbers pretty close - masses to within 1 ton, engines a little bit off since I couldn't find the exact parts you're using. Hence I ended up flying triple RD-191's on the first stage, with Isp 337 (vs your 338) and total thrust 6255kN (5% more than yours), and triple RL-10B/CECE (CECE Base config), with Isp 460 (vs your 468) and 201kN total thrust (16% less than yours). I needed to adjust the booster ignition delay from -1.5 to -3.5 seconds, but didn't make the same changes as you did to override the watchdog (wasn't necessary). This is about all the difference from your scenario, but the key factor - mass jettison during const-acc phase - remained very much the same.

I estimated the mission parameters from your screenshot, although I had to guess the payload mass, so I put 13 tons on it (a bit too much, it missed orbit narrowly but that's irrelevant).

The issue you're describing occurred in my test as well. It is caused by an apparent bug in initializeVehicleForUPFG, where the order of operations seems to be off. It handles mass jettisons and engine shutdowns first, and acceleration limiting second; something is clearly wrong with this logic. I've made dumps of vehicle struct throughout the procedure and it looks like this:

For some reason which eludes me at the moment, this post-jettison virtual stage 1 is not being transformed into a pair of const-thrust and const-acc stages, even though it still has the gLim flag. I'm digging into it now, retracing the entire computation and logic to find the culprit.


Funny enough, I had one difficulty reproducing your problem, and on the way found another bug: initially, the vehicle flew perfectly well because PEGAS completely ignored the jettison event in the calculations. That was because the event happened exactly between the two stages how they would look like if there was no gLim condition - this line kicked in because stageActiveAtTime doesn't consider a stage as running until all its delay times have elapsed.

So, thank you for pointing those two bugs to me. I'm working on them both now.

Noiredd commented 1 year ago

I cracked it. The direct reason is line 723 in util. After handling the jettisons, PEGAS proceeds to handle the acceleration limits. It detects one regular stage, splits it into two, the latter of which becomes constant-acceleration, and moves to the post-jettison stage. gLim flag is recognized and accLimTime is being computed - that is the time after which the stage will reach the given acceleration limit. Normally you would start at say 1.8g and reach 4.5 in a while. But for a post-jettison stage scheduled during the const-acc phase, it might already be way past this limit (on default throttle setting), so the time turns out negative. L723 tests out false (since accLimTime > 0 - it is not a stupid precaution by the way; otherwise we'd create a really broken stage with negative values which would upset UPFG) and we essentially ignore the situation, leaving that portion of a stage in mode 0 (i.e. constant thrust) which you observe as an acceleration spike.

There exists a simple fix to the issue: just insert the following alternate clause after the 723-745 block:

            } ELSE IF accLimTime < 0 {
                SET vehicle[i]["mode"] TO 2.
                SET vehicle[i]["maxT"] TO constAccBurnTime(vehicle[i]).
                SET vehicle[i]["isVirtualStage"] TO TRUE.
                SET vehicle[i]["virtualStageType"] TO "virtual (const-acc)".
                SET vehicle[i]["isSustainer"] TO FALSE.
            }

This essentially switches the entire stage to the constant acceleration mode and the vehicle performs normally. At least my recreation of your vehicle seemed to ;)


Now that was a simple and slightly hacky fix which still leaves the second problem (missing the jettison event). I don't think I'll end up committing the above code into the repo, since there is a better way to fix all the bugs in one fell swoop (also making the code more understandable in the process). The real issue behind all those bugs is that initializeVehicleForUPFG looks at the vehicle first from the sequence point of view (to handle jettisons and shutdowns), and then from the vehicle pov (to handle const-acc). This is wrong: it should always look at it from the vehicle pov. That means:

This ensures that no combination of events will be a surprise, i.e. any order can be dealt with. Additionally, this almost automatically resolves the final issue (user event too close to UPFG-scheduled staging), a situation which cannot be smoothly detected in the current state. Of course it can be argued that this is a user error (one should've either moved the jettison earlier, later, or merge it with the ordinary staging), but at least we will be able to detect the potential issue and emit a warning.

theLXMB commented 1 year ago

Wow, that's brilliant! I'll let you know my results once I get around to testing your fix.

Thank you so much for working on this!

theLXMB commented 1 year ago

So, it took a while but I finally got around to playing KSP again.

Including your new code after line 745, here are my results with the same vehicle I from my initial post:

Bildschirm­foto 2023-03-11 um 19 22 30

There's this very brief blip right where before it went to full throttle. This only takes about half a second reading from the actual G indicator. So it really doesn't affect vehicle performance in any meaningful way and if you're not planning to put this hack into the repo anyway, I think this works quite well for now ! ;) I haven't tested most of my launch vehicles yet, but so far none have shown the initial problem.

Also, you were extremely close with your payload mass guess! It's 12.25t.

As for the UPFG/User event overlap/proximity problem: I've had another rocket show some really bizarre staging/scheduling behaviour, although I've not flown it that often before so I don't know yet if this is a PEGAS/User Script problem or if I'm missing something that has changed with the actual vehicle. I'm gonna dig into it.

Noiredd commented 1 year ago

That looks promising indeed! That throttle blip would be a pretty serious issue if that was a real world launch vehicle, but let's not analyze that too deeply for now. I'm about to send a PR which completely overhauls initializeVehicleForUPFG (basically a rewrite of the whole algorithm that generates virtual stages for gLim stages, jettisons, and engine shutdowns). I'll ping you as soon as I get it github-ready.