# PEGAS - Powered Explicit Guidance Ascent System - devlog

## Recommended Posts

First of all, I have tried following your discussion from pages 3 and 4 but I'm not really sure whether the problems you're discussing are a matter of PEGAS code, that is: does it do something wrong or fail in some case? If so, please make it clear what happens and when, and if you have a suggested solution - go ahead  I also welcome github issues or pull requests.

Now, to answer some of your posts:

On 24.08.2017 at 11:12 AM, Pand5461 said:

@Reddy can you explain your logic of control loop convergence?

@Pand5461 This is a bit tricky and very very empirical. I have tried approaches basing on steering vector and Tgo, trying to measure differences between the values calculated in consecutive iterations. The main problem that I was having was that UPFG sometimes converged (measured either way) on very wrong results (i.e. pointing 30+ degrees below the horizon and crashing) - especially on later stages. The basic logic is that I measure Tgo and see how it's changing. You have to be aware that kOS takes a good while to run through the entire UPFG routine, so some considerable time passes between the calls. What I'm doing is I measure that time and adjust the expected Tgo before comparing it with the algorithm's prediction. If the difference is small enough, I count that as a hit and run again. The point is to get 2-3 such hits in a row - this means that predicted Tgo is steadily decreasing with time.

Now comes the trick part. Sometimes after staging, UPFG would converge (that is, pass said verification algorithm), but the result would be rubbish (pointing down). I admit I have failed to find the cause of that, but I located the issue to be somewhere in the internal state of UPFG that has to be preserved between iterations. Simply reseting it in those situations would make things run smoothly. The very idea was to check whether the steering vector is similar to the "good" vector that the previous stage had. If they were very different (above 15 degrees), the UPFG state would be reset and reconverged with brand new state - for some reason, it would always (to the extent I tested) converge on a good solution (good = one that got it into orbit instead of RUD on reentry).

The reset mode would print a PRIORITY_CRITICAL message in the GUI upon being called. However, I haven't seen this message in a good while when flying my rockets - it might very well be the case that this behavior is not an issue anymore.

On 26.08.2017 at 11:03 PM, Jim DiGriz said:

@Reddy is this a bug in your CSE routine?

@Jim DiGriz It appears so, yes. I will fix this the next time I sit down to code.

The reason this was never a problem is that this branch of code is executed only when the alphas parameter is less than zero - and IIRC this can only happen when the vehicle is in a hyperbolic trajectory.

On 30.08.2017 at 12:31 AM, gsarducci said:

First, I am curious if there is a way to impart a spin on a stage prior to stage/ignition.

@gsarducci Currently there is no such option. This is kind of counterproductive, since the whole point of PEGAS is to not have the vehicle locked at one attitude, but continuously change it in order to maintain an optimal trajectory. Wait, haven't I replied you in issues?

Anyway, I'm considering implementing a more general event type - including one in which you could pass a function delegate into an event. This would basically let you do anything. Still, making the vehicle spin when PEGAS tries to change attitude (to a new steering vector calculated at every iteration) is not a good idea, because you would be effectively fighting against what it's trying to do.

##### Share on other sites

@Reddy You replied to my posting in Github on several subjects, and it was extremely helpful, thank you! For purposes of context on this forum, the question was related to early missions like on Able-Thor where the third stage was an unguided, spin stabilized solid rocket kick. Anyway, in many cases these launches involved a coast period anyway which PEGAS isn't set up for.

Very much looking forward to your continued improvements! Thanks, again!

##### Share on other sites

@Reddy I've been working through the derivation of the predictor in UPFG and might have found a sign error (which may exist in the original paper, or might be due to some + signs getting scanned in as - signs, but starting intently at the PDF suggests that they seem to really be - signs):

First of all L*phi + J*phidot should always be zero.  This isn't an accident and is because lambda is aligned with the vgo direction so vthrust should always point that way.

On this line phidot = - L/J * phi:

Algebraic rearrangement gives L * phi + J * phidot = 0, so two lines down can just be deleted:

vthrust = (L - 0.5*L*phi^2 - J*phi*phidot - 0.5*H*phidot^2)*lambda;

That's all you need for vthrust.  And setting the coefficient of lambdadot in the vthrust expression to zero is actually how the phidot = - L/J phi relationship is determined.  By the linear tangent steering law that is also equivalent to phidot = - phi / t_lambda where t_lambda is the time of the centroid of the burn, which is how the centroid of the burn is derived (t_lambda = J/L).  I think this is general for all/most implementations of PEG.

Now the weird thing is that I think the proper expression for rthrust is:

rthrust = (S - 0.5*S*phi^2 - Q*phi*phidot - 0.5*P*phidot^2)*lambda;

rthrust = rthrust + (S*phi + Q*phidot)*unit(lambdadot);

That second line there has a minus signed converted into a plus sign.  I cannot figure out where that minus sign comes from in the original paper.  IDK if that makes rockets fly better or worse yet and haven't implemented it yet.  Would love to know if you could whip that up in MATLAB and see if it was better or worse.

EDIT:  nope, very obviously bad without that minus sign.   So my guess is that it comes from interchanging ds dt / dt ds in the thrust integrals and probably dropping out of integration by parts or something like that.  Still the lambdadot term in vthrust is zero just algebraically.

Edited by Jim DiGriz

##### Share on other sites

hey,

Maybe i'm being dim but i am not sure what you mean in your instructions by defining vehicle and mission and sequence so i just get the immediate crash and the "No boot file loaded. Crashing..." message.

What am i doing wrong?

##### Share on other sites

@windystig The tutorial is what you're looking for.

@Jim DiGriz I've just tried it. After changing this to +, it failed spectacularly. Although it's a nice find on the phidot identity - nothing should change and indeed nothing changes if this line is removed. It is very strange, why is this term even there (I'm thinking about figure 5-6 in the block diagram for block 5 in the original UPFG paper). In the current form it introduces nothing - vehicles fly perfectly with and without it. Changing it to anything else just makes things crash in all sorts of ways. It's just hard to believe that they would burden the GN&C computer with such a heavy line if it does exactly nothing...

Edited by Reddy

##### Share on other sites
On 10/28/2017 at 5:51 PM, Reddy said:

@windystig The tutorial is what you're looking for.

@Jim DiGriz I've just tried it. After changing this to +, it failed spectacularly. Although it's a nice find on the phidot identity - nothing should change and indeed nothing changes if this line is removed. It is very strange, why is this term even there (I'm thinking about figure 5-6 in the block diagram for block 5 in the original UPFG paper). In the current form it introduces nothing - vehicles fly perfectly with and without it. Changing it to anything else just makes things crash in all sorts of ways. It's just hard to believe that they would burden the GN&C computer with such a heavy line if it does exactly nothing...

Pretty certain this algorithm never actually flew in the GN&C computer, this was just the first rough draft...

Also the vthrust lambdadot term being zero more precisely falls out of the requirement that the dot product of lambda and lambdaDot is zero.  Its not so much a choice as a requirement of how the linear tangent law is constructed (although I guess technically that's a choice there, but its a bit more fundamental of a choice).  Still don't know where that minus sign comes from...

##### Share on other sites

PEGAS v1.1 is out now! Get it while it's still hot!

List of new features includes:

• inter-CPU communication system by Patrykz94,
• roll control via user events,
• better throttle control via user events,
• new user event type (jettison) to account for the amount of jettisoned mass,
• stages can explicitly shut down engines (useful for Falcon 9 style missions),
• LAN and inclination as optional parameters (default inclination will be equal to launch site latitude, defualt LAN will be set for the launch to occur in 30 seconds from "now"),
• launch direction (northerly and southerly, as well as "nearest opportunity"),
• automatic seizing control from the kOS CPU part,

as well as a few bugfixes:

• throttling now obeys the way Realism Overhaul works,
• sustainer-type stages are now handled properly,
• minor code clean-ups, GUI and documentation fixes.

@Jim DiGriz I am tempted to shamelessly say that plus or minus, what matters is that it flies  To be honest, I just don't have as much time as I used to, certainly not enough to research the intricacies of the algorithm again. I have already limited my activity to maintenance, bugfixes and features related mostly to KSP-side infrastructure (like events, stage handling, action group support etc.). For anything that touches the UPFG itself: I will review pull requests, perhaps assist in testing, but digging deep into it like I did in mid 2016 - unlikely. Though I am curious to read about your findings!

You know, I started fiddling around with kOS in early 2015 because I pretty much mastered the game and flying a hundred ascents to build&resupply my orbital station became boring. This was when I wrote my first autopilot. Soon, in search of a bigger challenge, I tried RO, but found that my toy-level script was no longer sufficient. Later I found Orbiter forums and PEG, and this was about the last time I've really played KSP. Ever since it was only pencil&paper, MATLAB and if I ever launched the game, it was just to test/debug PEGAS. Rendesvouz launches were always on the horizon of what I wanted to do (orbital station servicing, right?) and initially I thought this could be done with the basic PEG the Orbiter wiki describes (or some extensions of it). Realization that it's not was what pushed me to research further, to come across UPFG and subsequently to spend another year working on this project. Implementing the algorithm made PEGAS everything that I ever wanted it to be. It might not do everything, there might be things that it could do better, and sure I do have more ideas to add - but for most practical purposes it's more than enough. To me it's at its pinnacle as a tool. Of course it's not over yet: there will be more bugs and fixes, requests and features - bigger and smaller, but for now I am happy with how it turned out.

I feel kind of like the South Park guys at the end of the "Make Love Not Warcraft" episode. I can finally play the game

Edited by Reddy
• 3

##### Share on other sites

Personally I find the potential of this tool to be awesome! I had been waiting for RSS and RO to update to the latest KSP versions but this makes we want to just scale Galileo up and use SMURFF. Most autopilots for KSP can take inclination into account but struggles with LAN and especially upper stages with far less TWR. I want to be able to do 14 minute Centaur style burns to LEO so I cant wait to try this.

If you are taking requests about missions you can use this for. I would like to see the Soviet N1 launcher use this. A lunar mission if possible but even just using it to add something to your station would be fun to watch. Or perhaps one of the classic Atlas rockets that used SRBs and the 1.5 staging. It would be fun to see this adapting to those odd launchers. Like you showed in your last video with the Atlas V.

##### Share on other sites

Nice mod you developed!

I just tried to get behind the numbers of your "tutorial"-vehicle, the AtlasV-532.

AtlasV-532.ks:

GLOBAL vehicle IS LIST(
LEXICON(
//    This is a sustainer-type stage. It ignites on the pad, but UPFG takes control over it mid-flight.
//    Therefore, no ignition or separation happens, and the actual mass of the stage at activation is
//    inferred automatically.
"name", "Common Core Booster",
"massTotal", 334872,
"massFuel", 207720+76367,

My version of the RSB AtlasV-532 common core booster has a wet mass of 299200 kg, what do i have to add to get to 334872?

The rest of the numbers are clear.

Thanks

##### Share on other sites

Thanks, @JohnMcLane!

One thing you must be aware of is that masses are not for the individual stages, but for the entire vehicle at this stage. So the CCB mass in PEGAS must also include the Centaur upper stage. I will make this more clear in the next update of the tutorial

• 1

##### Share on other sites

@Reddy   Thanks for the response

I read the tutorial again, maybe i overread it the last time or i forgot it.

"total mass of the entire vehicle at the moment of ignition of each stage," is stated under vehicle. So its should be clear....

maybe, in the example AtlasV-532 file put something like this: "massTotal", 334872,   //the massTotal is common booster core + engine+ centaur upper stage.. that would help people like me a lot

EDIT: For my AtlasV-532 with a 5t payload, i get a massTotal of 343899kg without clamps, launch tower, srb's. Its ~10t difference to your number.

EDIT2: Forget Edit, the RSB craft files have liquid fuel and oxidizer plus lqdoxygen and kerosene in the tanks, somehow RO doesnt get rid of that. Without the unnecessary fuel load and payload i have the same Totalmass.

One question remains: why does PEGAS stage my payload (its the last stage), in the mission.ks there is my payload weight listet and in the sequence list is no additional command, there are only the standard commands of the example AtlasV-532.ks file.

The more launches i made, with different launchers, the happier i get. Man, nice program. WOW!!!

Edited by JohnMcLane

##### Share on other sites

Thank you =)

Staging a payload can only occur if you have a sequence event set up... or if there is stage in vehicle but no corresponding physical stage to be dropped. PM me with the details of this issue as it sounds weird.

• 1

##### Share on other sites

I will take a look at my problem again tomorrow and message you then. Thank you for the reply!

##### Share on other sites

I've tested my own implementation of UPFG in 3.2x system. It works, although I found that analytical CSE routine is imprecise in the sense it does not give results coherent with the internal trajectory prediction.

I found that simple Verlet integration gives much more accurate results.

I'm now wondering if that 5 km error in apses in your video is due to CSE and can be eliminated by using more precise trajectory prediction.

##### Share on other sites

I take back my words. CSE is reasonably accurate on the time span needed for UPFG. The apses difference is due to cutoff velocity errors. Not much to do with this in RO, given limited (or no at all) engine throttleability.

The performance of CSE routine is not very good, however. I've rewritten the routine according to (H.D. Curtis, Orbital Mechanics for Engineering Students) and it needs 80 ms to converge at 200 IPU as opposed to 0.56 s for your implementation.

Do you mind if I add a PR to replace the CSER?

• 1

##### Share on other sites
On 12.12.2017 at 7:36 PM, Pand5461 said:

Do you mind if I add a PR to replace the CSER?

Not at all, this is what the PRs are for - all improvements are very welcome, thank you @Pand5461!

I've researched the apses difference thing back during the prototyping days - it's interesting, but the error is always there, even in a MATLAB simulation running at 1ms precision. Something tells me that this is just how the UPFG is and nothing that can be done about it at all. As Jim DiGriz said a few posts above, this implementation most likely never really flew the Shuttle - it was a good first draft, but likely received many improvements before actually being used in the GN&C. And there had to be something to improve on, right?

Edited by Reddy

##### Share on other sites

That's strange because in my tests with 3.2x GPP I managed to get apses within 1 km difference, 0.5 m/s velocity vector difference from horizontal circular speed.

But I needed a bit more sophisticated logic than just locking orientation in one direction and waiting for cutoff.

Sikharulidze says, in the last seconds before cutoff turning rate was frozen and the predicted final position is used as the desired final position. I instead stopped recomputing desired final position and used the last computed rd and lambdadot to update Vgo and Vt in the last ten seconds. Last second is just finalizing burn with the last computed Vgo.

##### Share on other sites

Actually that's a bit odd because the CSER routine in that paper you've (reddy) implemented I believe is a Goodyear's Universal Variables implementation with Battin's normalized units, and my C# implementation of that handily beats KSPs Orbit class even though I haven't done the work to feed the prior solution back into the next solution as a hint.  I think the code that ran in the Shuttle was more complicated due to needing to handle J^2 oblateness, but the CSER you've got should be pretty industrial strength (and fast because it had to run on the potatoputer in the Shuttle).  At the same time, though, simplicity of code and validation of accuracy probably trumps everything else.  If I could tame the inverse rotation / Krankensbane issues and just use the Orbit class, I would.

And for terminal guidance, what I've found you need to do in the corrector is:

- project rp into the iy plane

- compute rd and vd from your targetting

- if you are at tgo < 40 seconds you must release the target constraints with `rd = rp`

- then do the normal vmiss and updating of vgo calcs

The other trick then (from McHenry 1979) is that lambdaDot calculations are frozen at tgo < 40 seconds, so you DO NOT run the TURNR code:

- rgo = rd - ( r + v * tgo + rgrav ) + rbias

- rgo = rgo + ( S - Vector3d.Dot(lambda, rgo) ) * lambda;

-  lambdaDot = ( rgo - S * lambda ) / QP;

Looks like rgrav estimate doesn't need updating in the early block either, etc.  I suppose technically if you're not computing and using rgo in the TURNR code it doesn't matter what you do in the corrector with rd, but setting rd = rp keeps the meaning correct.

Then during the last 10 seconds of guidance you should completely stop updating PEG and fly on the last computation of lambda, lambdaDot and K / t_lambda.

Also during the last 10 seconds of guidance you should be counting down tgo and vgo based only on elapsed time and sensed acceleration.  You can terminate the burn when tgo < TimeWarp.fixedDeltaTime.  When you do, vgo should be 0.1 or 0.2 or some other very close to zero value.  If it is not then there's either a bug in your vessel parameters, or there's a bug in your sensed acceleration, and those need to get fixed.

The terminal guidance of PEG actually gets dramatically worse if your sensed acceleration adjustment to vgo is not fairly precise.  I was seeing issues at 50-60-ish seconds out due to having botched the sensed dV.  This is a known issue/feature of PEG (I think one of the two references below mentions it)

I also had one kind of derpy issue due to incorrectly rooting my rocket to the payload decoupler on the injection stage and not having the root in the payload, which threw off the mass, threw off the acceleration and threw off the delta V calc of the stage, and i was winding up with vgo of 12-ish m/s and wasn't reaching the right orbit (and even if I'd burned to a condition like meeting the angular momentum requirements of the target orbit, or vgo nearly being zero, then the final calculations of lambda and K / t_lambda and vgo for the frozen value of lambdaDot at 10 seconds would have been off because the thrust integral calculations would have been off).

I also included a phiMax / lambdaDot.mag * K clamp like:

double clamp = 4.5 * Math.Pow(10, ( tgo - 40 ) / 40 ) * UtilMath.Deg2Rad;

That is just because KSP users may do burns of less than 10 seconds or may do stuff like only use 10 seconds of a TLI stage upper to finish up orbital insertion.  With the former you need at least one run through PEG to converge with a sensible clamped lambdaDot and with the latter its just going to give PEG fits in the terminal guidance period.  So the clamp starts at 45 degrees at 80 seconds out (allowing rd position constraints to be fully satisfied until then) and the exponentially decays to 4.5 degrees at 40 seconds and 0.8 degrees at 10 seconds.  Basically forcing it to progressively just burn towards vgo and not worry about turning rate -- but a very kerballed up solution to possible kerbal issues.  The problem with clamping lambdaDot, though, is that when you do it, you're implicitly releasing the position constraint and creating a non-zero rbias term.

Some light reading on PEG thrust integral stability analysis:

I did a build of the most recent / most stable MJ code I have earlier today:

That also wires up PEG to the node executor and I managed to get one of the worst rockets I have into a 185.2x185.4 orbit and then it successfully executed an ~9 minute burn from parking orbit that nearly hit Mars dead center.  It is, however, using the CSESimple calc-101-based debugging routine right now so it might run slow on slower computers.

Edited by Jim DiGriz

##### Share on other sites

If you want a really up-to-date CSE routine along with some interesting historical background:

##### Share on other sites
8 hours ago, Jim DiGriz said:

Actually that's a bit odd because the CSER routine in that paper you've (reddy) implemented I believe is a Goodyear's Universal Variables implementation with Battin's normalized units, and my C# implementation of that handily beats KSPs Orbit class even though I haven't done the work to feed the prior solution back into the next solution as a hint.

I would guess it's peculiarity of kOS's virtual machine. On a real machine, trig functions are far from being a single instruction.

Maybe when Steven Mading will introduce concept of "flops" to kOS, breaking down complex expression with trig functions to series summation will make sense in kOS. Now there isn't much incentive to it.

And AFAIK Shuttle computer used numerical integration instead of analytical CSE at ascent, so the code was in fact much simpler and easily adaptable for oblateness effects, residual aero drag and reactive force from tank venting.

##### Share on other sites
8 hours ago, Pand5461 said:

I would guess it's peculiarity of kOS's virtual machine. On a real machine, trig functions are far from being a single instruction.

Ah yeah, on kOS if you can trade continued fractions for single trig functions you'll come out way ahead, that makes total sense...

8 hours ago, Pand5461 said:

And AFAIK Shuttle computer used numerical integration instead of analytical CSE at ascent, so the code was in fact much simpler and easily adaptable for oblateness effects, residual aero drag and reactive force from tank venting.

Also yes you're correct about all of the above.

##### Share on other sites

Hey,

got a problem with my rcs and PEGAS:

-  If i activate RCS via 'R' during active Pegas, rcs is coming out of every rcs engine nozzle....

-  If pegas completes his mission and i/or smart a.s.s (mechjeb) try to use rcs to change attitude of the craft also the rcs comes out of each nozzle and it seams a invisible force (like SAS, but SAS is deactivated) tries to keep the ship in the same direction (with quicksave and quickload the problem is gone)....

Thanks!

##### Share on other sites

Hello!

I have written a boot config by myself, but I just get a "converging" all the time. I'm wondering if I have done something wrong. Tried many times but still failed.

Here is the code. I use the Real scale booster to built the Delta.

```GLOBAL vehicle IS LIST(
LEXICON(
"name", "Delta IV Common Booster Core",
"massTotal", 399238,
"massDry", 61362,
"gLim", 4.5,
"minThrottle", 0.56,
"engines", LIST(LEXICON("isp", 409, "thrust", 3370000)),
"staging", LEXICON(
"jettison", FALSE,
"ignition", FALSE
)
),
LEXICON(
"name", "DCSS",
"massTotal", 34645,
"massDry", 7444,
"engines", LIST(LEXICON("isp", 465.0, "thrust", 110100)),
"staging", LEXICON(
"jettison", TRUE,
"waitBeforeJettison", 5,
"ignition", TRUE,
"waitBeforeIgnition", 2,
"ullage", "rcs",
"ullageBurnDuration", 3,
"postUllageBurn", 2
)
)
).
GLOBAL sequence IS LIST(
LEXICON("time", -4, "type", "stage", "message", "RS-68 ignition"),
LEXICON("time", 0, "type", "stage", "message", "LIFT OFF"),
LEXICON("time", 90, "type", "stage", "message", "GEM 60 jettison"),
LEXICON("time", 300, "type", "jettison", "message", "Fairing jettison", "massLost", 1760*2)
).
GLOBAL controls IS LEXICON(
"verticalAscentTime", 7,
"pitchOverAngle", 13,
"upfgActivation", 110
).
GLOBAL mission IS LEXICON(
"periapsis", 200,
"apoapsis", 200,
"inclination", 0
).
SWITCH TO 0.
CLEARSCREEN.
PRINT "Loaded boot file: DeltaIV_M+_(5,4)".```

##### Share on other sites
On 25.12.2017 at 4:41 PM, JohnMcLane said:

Hey,

got a problem with my rcs and PEGAS:

-  If i activate RCS via 'R' during active Pegas, rcs is coming out of every rcs engine nozzle....

-  If pegas completes his mission and i/or smart a.s.s (mechjeb) try to use rcs to change attitude of the craft also the rcs comes out of each nozzle and it seams a invisible force (like SAS, but SAS is deactivated) tries to keep the ship in the same direction (with quicksave and quickload the problem is gone)....

Thanks!

It sounds like a common problem with kOS and RCS steering. Try to run something like this:

```LOCK STEERING TO RETROGRADE.
WAIT 20.
UNLOCK STEERING.```

and see what happens. If you observe the same symptoms, it's the kOS fault (or your vehicle, but I'm not sure).

@LAND ASAP I see you're trying to launch to zero inclination orbit. Where is your launch site located?

##### Share on other sites
2 hours ago, Reddy said:

```
LOCK STEERING TO RETROGRADE.
WAIT 20.
UNLOCK STEERING.```

Thanks!

to my shame i have to say i use mechjeb right now and stopped with kos, because MJ has PEG for RO now and its very easy to use

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account