Skip to content

Commit

Permalink
events: sort out the chaos between UPFG control, staging, and UI
Browse files Browse the repository at this point in the history
This introduces one big change to how things are handled: previously,
the flag `stagingInProgress` was FALSE during the time between exiting
the passive guidance loop and engaging UPFG for the first time. From
now on, this flag will be TRUE whenever any transition between actively
guided happens - including the first one.

Additionally, several extra flags to explicitly convey information
about the current state of the vehicle and guidance are added:
* `activeGuidanceMode`
* `prestageHold`
* `upfgEngaged`
* `"isSustainer"`, internal to each vehicle stage.
None of those introduce any new concept, it's just giving clear names
to existing concepts and rewriting some code to use those concepts in
a transparent fashion, as well as updating the UI to present those
concepts to the user.
Consult upfgSteeringControl for a more in-depth explanation.
  • Loading branch information
Noiredd committed Aug 25, 2022
1 parent 2fafa90 commit e8c051b
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 47 deletions.
9 changes: 6 additions & 3 deletions kOS/pegas.ks
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ GLOBAL throttleSetting IS 1. // This is what actually controls the throttle,
GLOBAL throttleDisplay IS 1. // and this is what to display on the GUI - see throttleControl() for details.
GLOBAL steeringVector IS LOOKDIRUP(SHIP:FACING:FOREVECTOR, SHIP:FACING:TOPVECTOR).
GLOBAL steeringRoll IS 0.
GLOBAL upfgConverged IS FALSE.
GLOBAL stagingInProgress IS FALSE.
GLOBAL activeGuidanceMode IS FALSE. // Set to TRUE at UPFG activation time (as defined in controls)
GLOBAL upfgConverged IS FALSE. // See upfgSteeringControl comments
GLOBAL upfgEngaged IS FALSE. // See upfgSteeringControl comments
GLOBAL stagingInProgress IS FALSE. // See upfgSteeringControl comments
GLOBAL prestageHold IS FALSE. // See upfgSteeringControl comments

// Load user addons
scanAddons().
Expand Down Expand Up @@ -150,7 +153,7 @@ UNTIL ABORT {
// Iterate UPFG and preserve its state
SET upfgInternal TO upfgSteeringControl(vehicle, upfgStage, upfgTarget, upfgState, upfgInternal).
// Manage throttle, with the exception of initial portion of guided flight (where we're technically still flying the first stage).
IF upfgStage >= 0 { throttleControl(). }
IF activeGuidanceMode { throttleControl(). }
// Transition to the attitude hold mode for the final seconds of the flight
IF upfgConverged AND upfgInternal["tgo"] < upfgFinalizationTime { BREAK. }
// UI
Expand Down
29 changes: 23 additions & 6 deletions kOS/pegas_events.ks
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,17 @@ FUNCTION spawnStagingEvents {
LOCAL stagingEvent IS LEXICON(
"time", stageActivationTime,
"type", "_upfgstage",
"isVirtual", vehicleIterator:VALUE["isVirtualStage"]
).
// Insert it into sequence
insertEvent(stagingEvent).
// But we also want to demark this exact moment as transition to active guidance mode
LOCAL stagingEvent IS LEXICON(
"time", stageActivationTime,
"type", "_activeon",
"isVirtual", vehicleIterator:VALUE["isVirtualStage"],
"message", "active guidance on" // todo: clarify all messages related to staging and virtual stages
).
// Insert it into sequence
insertEvent(stagingEvent).
// Compute burnout time for this stage and add to sAT (this involves activation time and burn time)
SET stageActivationTime TO stageActivationTime + getStageDelays(vehicleIterator:VALUE) + vehicleIterator:VALUE["maxT"].
Expand All @@ -51,16 +58,14 @@ FUNCTION spawnStagingEvents {
LOCAL stagingEvent IS LEXICON(
"time", stageActivationTime - stagingTransitionTime,
"type", "_prestage",
"isVirtual", vehicleIterator:VALUE["isVirtualStage"],
"message", vehicleIterator:VALUE["name"]
"isVirtual", vehicleIterator:VALUE["isVirtualStage"]
).
insertEvent(stagingEvent).
// Construct & insert staging event
LOCAL stagingEvent IS LEXICON(
"time", stageActivationTime,
"type", "_upfgstage",
"isVirtual", vehicleIterator:VALUE["isVirtualStage"],
"message", vehicleIterator:VALUE["name"]
"isVirtual", vehicleIterator:VALUE["isVirtualStage"]
).
insertEvent(stagingEvent).
// Compute next stage time
Expand All @@ -78,6 +83,7 @@ FUNCTION eventHandler {
// "vehicle" as list
// "liftoffTime" as timespan
// "stagingInProgress" as bool
// "prestageHold" as bool
// "steeringRoll" as scalar
// "throttleSetting" as scalar
// "throttleDisplay" as scalar
Expand Down Expand Up @@ -114,6 +120,9 @@ FUNCTION eventHandler {
ELSE IF eType = "delegate" OR eType = "d" {
userEvent_delegate(event).
}
ELSE IF eType = "_activeon" {
internalEvent_activeModeOn().
}
ELSE IF eType = "_prestage" {
internalEvent_preStage().
}
Expand All @@ -139,12 +148,18 @@ FUNCTION eventHandler {

// EVENT HANDLING SUBROUTINES

// Handle transition to active guidance mode
FUNCTION internalEvent_activeModeOn {
SET activeGuidanceMode TO TRUE.
}

// Handle the pre-staging event
FUNCTION internalEvent_preStage {
// Switch to staging mode, increment the stage counter and force UPFG reconvergence.
// Rationale is not changed: we want to maintain constant attitude while the current stage is still burning,
// but at the same time start converging guidance for the subsequent stage.
SET stagingInProgress TO TRUE.
SET prestageHold TO TRUE.
SET upfgStage TO upfgStage + 1.
SET upfgConverged TO FALSE.
usc_convergeFlags:CLEAR().
Expand All @@ -156,6 +171,9 @@ FUNCTION internalEvent_staging {
// Instead of breaking it down into multiple individual events (understood as sequence items), we use the
// trigger mechanism to handle them. When staging occurs, several triggers are scheduled to handle every
// single step of the procedure in a timely manner.
// First, clear the flag informing of the previous stage end-of-burn attitude hold
SET prestageHold TO FALSE.
// Now we can get to work
LOCAL currentTime IS TIME:SECONDS.
LOCAL event IS vehicle[upfgStage]["staging"].
LOCAL stageName IS vehicle[upfgStage]["name"].
Expand Down Expand Up @@ -225,7 +243,6 @@ FUNCTION internalEvent_staging {
} ELSE {
// If this event does not need ignition, staging is over at this moment
SET stagingInProgress TO FALSE.
// If this was the sustainer stage activation event, we also have to:
updateStageEndTime().
}

Expand Down
73 changes: 49 additions & 24 deletions kOS/pegas_misc.ks
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ FUNCTION createUI {
PRINT "|-----------------------------------------|".
PRINT "| Stage: |". // Vehicle info
PRINT "| Stage type: |".
PRINT "| Veh. status: |".
PRINT "| UPFG status: |".
PRINT "| Tgo(stage) = s Tgo = s |".
PRINT "| Throttle = % Vgo = m/s |".
Expand Down Expand Up @@ -124,14 +125,25 @@ FUNCTION timePrint {

// Just fill in the blanks, do not redraw the whole GUI.
FUNCTION refreshUI {
// Expects global variables "liftoffTime" as timespan, "throttleDisplay" as scalar, "controls", "mission", "upfgTarget" and "upfgInternal" as lexicon and "upfgConverged" as bool.
// Expects global variables:
// "liftoffTime" as timespan
// "throttleDisplay" as scalar
// "controls" as lexicon
// "mission" as lexicon
// "upfgTarget" as lexicon
// "upfgInternal" as lexicon
// "activeGuidanceMode" as bool
// "upfgConverged" as bool
// "upfgEngaged" as bool
// "stagingInProgress" as bool
// "prestageHold" as bool

// Print and acquire current time
LOCAL currentTime IS timePrint().

// Section offsets, for easier extendability
LOCAL vehicleInfoOffset IS 8. // Reads: vehicle info section starts at row 8
LOCAL orbitalInfoOffset IS vehicleInfoOffset + 8.
LOCAL orbitalInfoOffset IS vehicleInfoOffset + 9.
LOCAL currentOrbitOffset IS 15. // Horizontal offset for the current orbit info
LOCAL targetOrbitOffset IS 29. // Horizontal offset for the target orbit info
LOCAL messageBoxOffset IS orbitalInfoOffset + 9.
Expand All @@ -142,6 +154,8 @@ FUNCTION refreshUI {
LOCAL isActive IS FALSE.
LOCAL stageName IS "".
LOCAL stageType IS "".
LOCAL stageVirtual IS FALSE.
LOCAL vehicleStatus IS "".
LOCAL upfgStatus IS "".
LOCAL stageTgo IS 0.
LOCAL totalTgo IS 0.
Expand All @@ -155,6 +169,7 @@ FUNCTION refreshUI {
// Passive guidance phase
SET stageName TO "".
SET stageType TO "passively guided".
SET vehicleStatus TO "nominal".
SET upfgStatus TO "inactive".
// Time until activation of UPFG
SET stageTgo TO liftoffTime:SECONDS + controls["upfgActivation"] - currentTime:SECONDS.
Expand All @@ -163,6 +178,8 @@ FUNCTION refreshUI {
SET isActive TO TRUE.
SET stageName TO vehicle[upfgStage]["name"].
SET stageType TO vehicle[upfgStage]["virtualStageType"].
SET stageVirtual TO vehicle[upfgStage]["isVirtualStage"].
SET stageSustainer TO vehicle[upfgStage]["isSustainer"].
SET currentVelocity TO SHIP:VELOCITY:ORBIT:MAG.
// Time until the stage burns out (basing on ignition time and cumulative burn time - can be off by 1-2s)
IF stageEndTime > currentTime {
Expand All @@ -175,45 +192,53 @@ FUNCTION refreshUI {
} ELSE {
SET stageTgo TO 0.
}
// Print convergence flag
// Print vehicle status flag
IF stagingInProgress {
SET stageName TO "".
IF vehicle[upfgStage]["isVirtualStage"] {
SET upfgStatus TO "transition (virtual)".
} ELSE {
SET upfgStatus TO "STAGING".
IF stageVirtual {
// virtual (post-jettison)xxx
SET vehicleStatus TO "virtual stage transition".
}
} ELSE {
IF upfgConverged {
SET upfgStatus TO "CONVERGED".
SET totalTgo TO upfgInternal["tgo"].
SET totalVgo TO upfgInternal["vgo"]:MAG.
} ELSE {
SET upfgStatus TO "converging...".
ELSE IF stageSustainer {
SET vehicleStatus TO "sustainer - preconvergence".
}
ELSE {
SET vehicleStatus TO CHOOSE "preparing to stage" IF prestageHold ELSE "staging".
}
}
ELSE {
SET vehicleStatus TO "NOMINAL".
}
// Print UPFG convergence flag
IF upfgConverged {
SET upfgStatus TO CHOOSE "ENGAGED" IF upfgEngaged ELSE "converged & waiting".
SET totalTgo TO upfgInternal["tgo"].
SET totalVgo TO upfgInternal["vgo"]:MAG.
} ELSE {
SET upfgStatus TO "converging...".
}
}

// Print physical information
textPrint(stageName, vehicleInfoOffset + 0, 9, 41).
textPrint(stageType, vehicleInfoOffset + 1, 14, 41).
textPrint(upfgStatus, vehicleInfoOffset + 2, 15, 41).
textPrint(stageType, vehicleInfoOffset + 1, 15, 41).
textPrint(vehicleStatus, vehicleInfoOffset + 2, 15, 41).
textPrint(upfgStatus, vehicleInfoOffset + 3, 15, 41).
IF isFlying {
// Don't print time until next event while we're still on the ground
numberPrint(stageTgo, vehicleInfoOffset + 3, 17, 21, 0).
numberPrint(stageTgo, vehicleInfoOffset + 4, 17, 21, 0).
}
IF NOT isActive {
textPrint("N/A", vehicleInfoOffset + 3, 33, 37, "R").
textPrint("N/A", vehicleInfoOffset + 4, 33, 37, "R").
textPrint("N/A", vehicleInfoOffset + 5, 33, 37, "R").
} ELSE IF upfgConverged {
numberPrint(totalTgo, vehicleInfoOffset + 3, 33, 37, 0).
numberPrint(totalVgo, vehicleInfoOffset + 4, 33, 37, 0).
numberPrint(totalTgo, vehicleInfoOffset + 4, 33, 37, 0).
numberPrint(totalVgo, vehicleInfoOffset + 5, 33, 37, 0).
}
LOCAL throttle_ IS throttleDisplay.
LOCAL currentAcc IS (SHIP:AVAILABLETHRUST * throttle_) / (SHIP:MASS).
numberPrint(100*throttle_, vehicleInfoOffset + 4, 17, 21, 0).
numberPrint(currentAcc, vehicleInfoOffset + 5, 17, 21).
numberPrint(currentAcc / CONSTANT:g0, vehicleInfoOffset + 5, 28, 32, 1).
numberPrint(100*throttle_, vehicleInfoOffset + 5, 17, 21, 0).
numberPrint(currentAcc, vehicleInfoOffset + 6, 17, 21).
numberPrint(currentAcc / CONSTANT:g0, vehicleInfoOffset + 6, 28, 32, 1).

// Print current vehicle orbital info
numberPrint(SHIP:ALTITUDE/1000, orbitalInfoOffset + 0, currentOrbitOffset, currentOrbitOffset + 7).
Expand Down
Loading

0 comments on commit e8c051b

Please sign in to comment.