Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // assumes stable and circular (ap - pe < 500) orbit
- // set guidanceactive to false and vacLocLanderFinished to true, if you want to take over during landing
- if not (defined tgt) {
- if hastarget AND target:body = body AND (target:status = "landed" OR target:status = "splashed") {
- set tgt to target:geoposition.
- }
- else set tgt to ship:geoposition.
- }
- if not (defined terrainMargin) set terrainMargin to 1.
- if not (defined minApproachAngle) set minApproachAngle to 0.
- if not (defined terrRes) set terrRes to 30.
- if not (defined precision) set precision to terrainMargin/20.
- if not (defined minPeStep) set minPeStep to 1.
- set phases to list("INIT", "PLANNING", "SYNCRONISATION", "DEORBIT", "STAGING", "COASTING", "ACTIVE_GUIDANCE", "LANDING", "GUIDANCE_RELEASED", "TOUCHDOWN", "LANDED", "STOPPED").
- //user callable:
- function land {
- parameter minangle is 0.
- //lands at tgt
- if obt:eccentricity > 0.006 {
- print "Orbit is not circular enough.".
- print "aborting".
- return false.
- }
- if not (defined lowestSafeAltitude) set lowestSafeAltitude to periapsis - 100.
- set deorbitAltitude to periapsis + (apoapsis - periapsis)/2.
- set phase to "".
- on phase {print "Phase: " + phase. return (phase <> "LANDED" AND phase <> "STOPPED").}.
- engage(minangle).
- }.
- function launch {
- parameter _targetAltitude.
- parameter minangle is 0.
- if status <> "landed" {
- print "can only launch if landed".
- print "aborting".
- return false.
- }
- set tgt to ship:geoposition.
- if not (defined lowestSafeAltitude) OR lowestSafeAltitude >= (_targetAltitude - 100) set lowestSafeAltitude to _targetAltitude - 100.
- if not (defined thrSmoothing) set thrSmoothing to 100.
- set ascentAngle to calculateAscent(_targetAltitude).
- lock rawvertacc to ship:maxthrust/ship:mass * sin(ascentAngle).
- lock desvertacc to (choose getGravAcc(altitude) if (90 - vang(up:vector, velocity:orbit) > ascentAngle) else (rawvertacc + getGravAcc(altitude))).
- lock lp to max(minangle, arcsin(desvertacc/(ship:maxthrust/ship:mass))).
- on throttle lock steering to heading(90, lp).
- on status gear off.
- lock thr to (_targetAltitude - apoapsis)/1000 + 1e-3.
- for i in range(thrSmoothing) {lock throttle to min(i/thrSmoothing, thr). wait 0.01.}.
- lock throttle to thr.
- when apoapsis >= _targetAltitude then {
- lock throttle to 0.
- set steer to velocityat(ship, time:seconds + eta:apoapsis):orbit.
- lock steering to steer.
- print "at ap in " + round(eta:apoapsis) + " seconds".
- print "launch finished".
- }
- }.
- function touchandgo {
- parameter _targetAltitude is periapsis.
- parameter minangle is 0.
- fillOptionalParams().
- if not (defined lowestSafeAltitude) OR lowestSafeAltitude >= (_targetAltitude - 100) set lowestSafeAltitude to _targetAltitude - 100.
- if not (defined thrSmoothing) set thrSmoothing to 100.
- set vacLocLanderFinished to false.
- set ascentAngle to calculateAscent(_targetAltitude).
- when vacLocLanderFinished then {
- lock rawvertacc to ship:maxthrust/ship:mass * sin(ascentAngle).
- lock desvertacc to (choose getGravAcc(altitude) if (90 - vang(up:vector, velocity:orbit) > ascentAngle) else (rawvertacc + getGravAcc(altitude))).
- lock lp to max(minangle, arcsin(desvertacc/(ship:maxthrust/ship:mass))).
- lock steering to heading(90, lp).
- lock thr to (_targetAltitude - apoapsis)/1000 + 1e-3.
- for i in range(thrSmoothing) {lock throttle to min(i/thrSmoothing, thr). wait 0.01.}.
- lock throttle to thr.
- when apoapsis >= _targetAltitude then {
- lock throttle to 0.
- set steer to velocityat(ship, time:seconds + eta:apoapsis):orbit.
- lock steering to steer.
- print "at ap in " + round(eta:apoapsis) + " seconds".
- print "launch finished".
- }
- }
- set landedSettleTime to 0.
- land(minangle).
- }
- function grabandgo {
- parameter _targetAltitude is periapsis.
- parameter minangle is 0.
- fillOptionalParams().
- if not (defined lowestSafeAltitude) OR lowestSafeAltitude >= (_targetAltitude - 100) set lowestSafeAltitude to _targetAltitude - 100.
- if not (defined thrSmoothing) set thrSmoothing to 50.
- set vacLocLanderFinished to false.
- set ascentAngle to calculateAscent(_targetAltitude).
- set iParts to ship:parts:length.
- list engines in ieng.
- when ship:parts:length > iParts then {
- for e in ship:engines if not ieng:contains(e) e:shutdown().
- lock rawvertacc to ship:maxthrust/ship:mass * sin(ascentAngle).
- lock desvertacc to (choose getGravAcc(altitude) if (90 - vang(up:vector, velocity:orbit) > ascentAngle) else (rawvertacc + getGravAcc(altitude))).
- lock lp to max(minangle, arcsin(desvertacc/(ship:maxthrust/ship:mass))).
- lock steering to heading(90, lp).
- lock thr to (_targetAltitude - apoapsis)/1000 + 1e-3.
- for i in range(thrSmoothing) {lock throttle to min(i/thrSmoothing, thr). wait 0.01.}.
- gear off.
- lock throttle to thr.
- when apoapsis >= _targetAltitude then {
- lock throttle to 0.
- set steer to velocityat(ship, time:seconds + eta:apoapsis):orbit.
- lock steering to steer.
- print "at ap in " + round(eta:apoapsis) + " seconds".
- print "launch finished".
- }
- }
- set landedSettleTime to 0.
- set landingDescendSpeed to 0.5.
- set gearDeployAltitude to 0.
- landingOverride on.
- land(minangle).
- }
- //parameter checks
- function fillOptionalParams {
- if not (defined landingHeight) {
- local BottomBounds is ship:Bounds:furthestcorner(-ship:facing:vector).
- set landingHeight to (BottomBounds - vxcl(ship:facing:vector, BottomBounds)):mag.
- }
- set landingAltitude to tgt:terrainHeight + landingHeight.
- if not (defined landingVelocity) {
- if not (defined landingDescendSpeed) set landingDescendSpeed to 2.
- if not (defined landingGroundSpeed) set landingGroundSpeed to 0.
- }
- else {
- if (defined landingGroundSpeed) {
- questionableParams:add(list("landingVelocity, landingGroundSpeed", "note that landingVelocity always overrides landingGroundSpeed!")).
- }
- if (defined landingDescendSpeed) {
- questionableParams:add(list("landingVelocity, landingDescendSpeed", "note that landingVelocity always overrides landingDescendSpeed!")).
- }
- local landingHoriVel is vxcl((tgt:position - body:position), landingVelocity).
- local landingVertVel is landingVelocity - landingHoriVel.
- set landingGroundSpeed to landingHoriVel:mag.
- set landingDescendSpeed to landingVertVel:mag * ((vang(landingVertVel, (tgt:position - body:position)) - 90)/90).
- }
- if not (defined landingStage) set landingStage to stage:number.
- if not (defined terrainMargin) set terrainMargin to 5.
- if not (defined shipRollTime) set shipRollTime to 30.
- if not (defined deadzoneRCSstarboard) set deadzoneRCSstarboard to 0.3.
- if not (defined deadzoneRCStop) set deadzoneRCStop to 0.3.
- if not (defined glideTime) set glideTime to shipRollTime/2.
- if not (defined landedSettleTime) set landedSettleTime to 5.
- if not (defined thrustfactor) set thrustfactor to 1.
- if not (defined gearDeployAltitude) {
- if not (defined gearDeployTime) set gearDeployTime to 11.
- if glideTime >= gearDeployTime set gearDeployAltitude to landingDescendSpeed * gearDeployTime.
- else set gearDeployAltitude to 4 * landingDescendSpeed * gearDeployTime.
- }
- if not (defined debugPrinting) set debugPrinting to false.
- }.
- function checkParamsValidity {
- if deorbitAltitude < lowestSafeAltitude {
- invalidParams:add(list("lowestSafeAltitude, deorbitAltitude", "lowestSafeAltitude(" + lowestSafeAltitude + ") cannot be above deorbitAltitude(" + deorbitAltitude + ").")).
- }
- if deorbitAltitude <= 0 {
- invalidParams:add(list("deorbitAltitude", "must be bigger than 0 (" + deorbitAltitude + ").")).
- }
- if lowestSafeAltitude <= 0 {
- questionableParams:add(list("lowestSafeAltitude", "should be bigger than 0 (" + lowestSafeAltitude + ") unless you want to penetrate some terrain.")).
- }
- if terrainMargin < 0 {
- questionableParams:add(list("terrainMargin", "should be bigger than 0 (" + terrainMargin + ") unless you dont care about impacting some terrain.")).
- }
- if shipRollTime <= 0 {
- questionableParams:add(list("shipRollTime", "should be bigger than 0(" + shipRollTime + "). Will use 60 instead.")).
- set shipRollTime to 60.
- }
- if glideTime < 0 AND not (defined forceNegativeGlide AND forceNegativeGlide){
- invalidParams:add(list("glideTime", "cannot be smaller than 0(" + glideTime + "). This would result in an 'upwards' landing. If you want to force this, set param 'forceNegativeGlide' to true!")).
- }
- if gearDeployAltitude <= 0 {
- questionableParams:add(list("gearDeployAltitude", "should be bigger than 0(" + gearDeployAltitude + ") unless you want to land with retracted gear or deploy it manually.")).
- }
- return invalidParams:length = 0.
- }.
- //util
- function getApproachAngle {
- parameter _Ap.
- parameter _Pe.
- parameter _alt.
- if _alt <= _Pe OR _alt >= _Ap return 0.
- local h is body:radius + _alt.
- local c is _Ap - _Pe.
- local q is 2 * body:radius + _Ap + _Pe - h.
- local gamma is arccos((q^2 + h^2 - c^2) / (2 * q * h)).
- return gamma/2.
- }.
- function getAltitudeAtAnomaly {
- parameter _ta.
- parameter _Ap is apoapsis.
- parameter _Pe is periapsis.
- local sma is (_Ap + _Pe)/2 + body:radius.
- local le is sma - _Pe - body:radius.
- local ecc is le/sma.
- return sma * ((1 - ecc^2) / (1 + ecc * cos(_ta))) - body:radius.
- }.
- function getAnomaly {
- parameter _Ap.
- parameter _Pe.
- parameter _alt.
- if _alt <= _Pe return 0.
- if _alt >= _Ap return 180.
- local h is body:radius + _alt.
- local c is _Ap - _Pe.
- local q is 2 * body:radius + _Ap + _Pe - h.
- local beta is arccos((h^2 + c^2 - q^2) / (2 * h * c)).
- return 180 - beta.
- }.
- function calculateDeorbit {
- parameter minApproachAngle is 0.
- parameter terrRes is 30. //terrain check interval in meters (horizontal).
- parameter precision is terrainMargin/20.
- parameter minPeStep is 1.
- set deorbitPeriapsis to landingAltitude.
- until getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude) >= minApproachAngle {
- set deorbitPeriapsis to deorbitPeriapsis - minPeStep * 1000.
- print (" Approach angle: " + round(getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- until getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude) <= minApproachAngle {
- set deorbitPeriapsis to deorbitPeriapsis + minPeStep * 100.
- print (" Approach angle: " + round(getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- until getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude) >= minApproachAngle {
- set deorbitPeriapsis to deorbitPeriapsis - minPeStep * 10.
- print (" Approach angle: " + round(getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- until getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude) <= minApproachAngle {
- set deorbitPeriapsis to deorbitPeriapsis + minPeStep.
- print (" Approach angle: " + round(getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- set brr to 360/body:rotationPeriod.
- set deorbitSMA to (deorbitAltitude + deorbitPeriapsis)/2 + body:radius.
- set deorbitSpeed to getOrbitSpeed(deorbitSMA, deorbitAltitude).
- set deorbitPeriod to getOrbitPeriod(deorbitSMA).
- local stepsize is terrRes * 180 / (constant:pi * body:radius).
- local relAngle is 0.
- local landingAnomaly is getAnomaly(deorbitAltitude, deorbitPeriapsis, landingAltitude).
- local done is false.
- until done {
- set relAngle to relAngle + stepsize.
- set currLng to mod(900 + tgt:lng - 90 + deorbitPeriod * relAngle/360 * brr/4 + longitudeAtAnomalyOfAN(90 - relAngle, tgt:lat), 360) - 180.
- set currLat to getLatOfLng(currLng, tgt:lat, deorbitPeriod, brr, tgt:lng).
- set currTerrain to getTerrainMax(latlng(currLat, currLng), stepsize/3, stepsize/3).
- set currAlt to getAltitudeAtAnomaly(landingAnomaly + relAngle, deorbitAltitude, deorbitPeriapsis).
- if currAlt >= lowestSafeAltitude {
- set done to true.
- if debugPrinting print "above lsa.".
- break.
- }
- print (" Approach angle: " + round(getApproachAngle(deorbitAltitude, deorbitPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: " + round(100 * (currAlt - landingAltitude) / (lowestSafeAltitude - landingAltitude)) + "%"):padright(terminal:width) at(0,1).
- if currAlt < currTerrain + terrainMargin {
- local PeStep is (body:radius + deorbitPeriapsis)/10.
- until abs(currAlt - currTerrain - terrainMargin) < precision {
- if (currAlt - landingAltitude) < terrainMargin AND (currAlt - landingHeight) >= currTerrain {
- break.
- }
- if debugPrinting print (round(currAlt - currTerrain - terrainMargin, 5) + ", " + round(landingAnomaly + relAngle, 3) + ", " + round(PeStep, 5) + ", " + round(deorbitPeriapsis, 4)):padright(terminal:width) at(0,2).
- if currAlt > (currTerrain + terrainMargin) {
- if PeStep <= minPeStep break.
- set deorbitPeriapsis to deorbitPeriapsis + PeStep.
- set PeStep to PeStep/2.
- if PeStep <= minPeStep set PeStep to minPeStep.
- set deorbitPeriapsis to deorbitPeriapsis - PeStep.
- }
- else {
- set deorbitPeriapsis to deorbitPeriapsis - PeStep.
- }
- if deorbitPeriapsis < -body:radius {
- print "ERROR: " + deorbitPeriapsis + ", " + PeStep.
- set deorbitPeriapsis to -body:radius.
- }
- set landingAnomaly to getAnomaly(deorbitAltitude, deorbitPeriapsis, landingAltitude).
- set currAlt to getAltitudeAtAnomaly(landingAnomaly + relAngle, deorbitAltitude, deorbitPeriapsis).
- set deorbitSMA to (deorbitAltitude + deorbitPeriapsis)/2 + body:radius.
- set deorbitSpeed to getOrbitSpeed(deorbitSMA, deorbitAltitude).
- set deorbitPeriod to getOrbitPeriod(deorbitSMA).
- if deorbitPeriapsis <= -body:radius {
- print "XXX " + deorbitPeriapsis.
- break.
- }
- }
- }
- if deorbitPeriapsis <= -body:radius break.
- }
- //TODO: get rid of simResult structure
- set simResult:finalAngle to 180 - landingAnomaly.
- set simResult:duration to getDeorbitDuration(deorbitAltitude, deorbitPeriapsis, landingAnomaly).
- set simResult:ignitionTime to simResult:duration - 15.
- if debugPrinting {
- print " " + deorbitPeriapsis.
- print " " + landingAnomaly.
- print " " + simResult:finalAngle.
- }
- set deorbitCalcFinished to true.
- }.
- function calculateAscent {
- parameter targetAltitude.
- parameter minApproachAngle is 0.
- parameter terrRes is 30. //terrain check interval in meters (horizontal).
- parameter precision is terrainMargin/20.
- parameter minPeStep is 1.
- if not (defined landingHeight) AND status = "landed" {
- set landingHeight to alt:radar.
- set landingAltitude to tgt:terrainHeight + landingHeight.
- }
- if not (defined lowestSafeAltitude) set lowestSafeAltitude to targetAltitude - 100.
- set ascentPeriapsis to landingAltitude.
- until getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude) >= minApproachAngle {
- set ascentPeriapsis to ascentPeriapsis - minPeStep * 1000.
- print (" Ascent angle: " + round(getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- until getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude) <= minApproachAngle {
- set ascentPeriapsis to ascentPeriapsis + minPeStep * 100.
- print (" Ascent angle: " + round(getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- until getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude) >= minApproachAngle {
- set ascentPeriapsis to ascentPeriapsis - minPeStep * 10.
- print (" Ascent angle: " + round(getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- until getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude) <= minApproachAngle {
- set ascentPeriapsis to ascentPeriapsis + minPeStep.
- print (" Ascent angle: " + round(getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: 0%"):padright(terminal:width) at(0,1).
- }
- set brr to 360/body:rotationPeriod.
- set ascentSMA to (targetAltitude + ascentPeriapsis)/2 + body:radius.
- set ascentApSpeed to getOrbitSpeed(ascentSMA, targetAltitude).
- set ascentPeriod to getOrbitPeriod(ascentSMA).
- local stepsize is terrRes * 180 / (constant:pi * body:radius).
- local relAngle is 0.
- local ascentAnomaly is getAnomaly(targetAltitude, ascentPeriapsis, landingAltitude).
- local done is false.
- until done {
- set relAngle to relAngle + stepsize.
- set currLng to mod(900 + tgt:lng - 90 - ascentPeriod * relAngle/360 * brr/4 + longitudeAtAnomalyOfAN(90 + relAngle, tgt:lat), 360) - 180.
- set currLat to getLatOfLng(currLng, tgt:lat, ascentPeriod, brr, tgt:lng).
- set currTerrain to getTerrainMax(latlng(currLat, currLng), stepsize/3, stepsize/3).
- set currAlt to getAltitudeAtAnomaly(ascentAnomaly + relAngle, targetAltitude, ascentPeriapsis).
- if currAlt >= lowestSafeAltitude {
- set done to true.
- if (defined debugPrinting) AND debugPrinting print "above lsa.".
- break.
- }
- print (" Ascent angle: " + round(getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude), 2) + " deg"):padright(terminal:width) at(0,0).
- print (" Terrain check: " + round(100 * (currAlt - landingAltitude) / (lowestSafeAltitude - landingAltitude)) + "%"):padright(terminal:width) at(0,1).
- if currAlt < currTerrain + terrainMargin {
- local PeStep is (body:radius + ascentPeriapsis)/10.
- until abs(currAlt - currTerrain - terrainMargin) < precision {
- if (currAlt - landingAltitude) < terrainMargin AND (currAlt - landingHeight) >= currTerrain {
- break.
- }
- if (defined debugPrinting) AND debugPrinting print (round(currAlt - currTerrain - terrainMargin, 5) + ", " + round(ascentAnomaly + relAngle, 3) + ", " + round(PeStep, 5) + ", " + round(ascentPeriapsis, 4)):padright(terminal:width) at(0,2).
- if currAlt > (currTerrain + terrainMargin) {
- if PeStep <= minPeStep break.
- set ascentPeriapsis to ascentPeriapsis + PeStep.
- set PeStep to PeStep/2.
- if PeStep <= minPeStep set PeStep to minPeStep.
- set ascentPeriapsis to ascentPeriapsis - PeStep.
- }
- else {
- set ascentPeriapsis to ascentPeriapsis - PeStep.
- }
- if ascentPeriapsis < -body:radius {
- print "ERROR: " + ascentPeriapsis + ", " + PeStep.
- set ascentPeriapsis to -body:radius.
- }
- set ascentAnomaly to getAnomaly(targetAltitude, ascentPeriapsis, landingAltitude).
- set currAlt to getAltitudeAtAnomaly(ascentAnomaly + relAngle, targetAltitude, ascentPeriapsis).
- set ascentSMA to (targetAltitude + ascentPeriapsis)/2 + body:radius.
- set ascentApSpeed to getOrbitSpeed(ascentSMA, targetAltitude).
- set ascentPeriod to getOrbitPeriod(ascentSMA).
- if ascentPeriapsis <= -body:radius {
- print "XXX " + ascentPeriapsis.
- wait until false.
- break.
- }
- }
- }
- if ascentPeriapsis <= -body:radius break.
- }
- set ascentAngle to getApproachAngle(targetAltitude, ascentPeriapsis, landingAltitude).
- return ascentAngle.
- }.
- function getTerrainMax {
- parameter _gp.
- parameter dlng.
- parameter dlat.
- local th is list().
- th:add(_gp:terrainHeight).
- th:add(latlng(_gp:lat, _gp:lng - dlng):terrainHeight).
- th:add(latlng(_gp:lat, _gp:lng + dlng):terrainHeight).
- th:add(latlng(_gp:lat + dlat, _gp:lng):terrainHeight).
- th:add(latlng(_gp:lat + dlat, _gp:lng - dlng):terrainHeight).
- th:add(latlng(_gp:lat + dlat, _gp:lng + dlng):terrainHeight).
- th:add(latlng(_gp:lat - dlat, _gp:lng):terrainHeight).
- th:add(latlng(_gp:lat - dlat, _gp:lng - dlng):terrainHeight).
- th:add(latlng(_gp:lat - dlat, _gp:lng + dlng):terrainHeight).
- local hmax is th[0].
- for h in th {
- if h > hmax set hmax to h.
- }
- return hmax.
- }.
- function getDeorbitDuration {
- parameter _Ap.
- parameter _Pe.
- parameter _ta.
- parameter _step is 1.
- local beta is 180 - _ta.
- local rlist is list().
- local ca is 0.
- until ca >= beta {
- rlist:add(getAltitudeAtAnomaly(180 - ca, _Ap, _Pe) + body:radius).
- set ca to ca + _step.
- }
- rlist:add(getAltitudeAtAnomaly(beta, _Ap, _Pe) + body:radius).
- local fa is beta - ca + _step.
- local smajor is (_Ap + _Pe)/2 + body:radius.
- local sminor is smajor * sqrt(1 - ((_Ap - _Pe) / (2 * smajor))^2).
- local areaSpd is constant:pi * smajor * sminor / getOrbitPeriod(smajor).
- local duration is 0.
- local i is 1.
- until i >= rlist:length {
- if i = rlist:length - 1 set _step to fa.
- local aa is (rlist[i] + rlist[i-1])/2.
- local w is 2 * aa * sin(_step/2).
- local x is aa * cos(_step/2).
- local area is x * w/2.
- set duration to duration + area/areaSpd.
- set i to i + 1.
- }
- return duration.
- }.
- function planFlyover {
- parameter tgt is tgt.
- parameter allowOrbitReversal is false.
- local obtNormVec is vcrs(velocity:orbit, up:vector).
- local tgtNormVec is vcrs(latlng(tgt:lat, mod(181 + tgt:lng, 360) - 180):position - tgt:position, tgt:position - body:position).
- if allowOrbitReversal AND vang(obtNormVec, tgtNormVec) > 90 set tgtNormVec to -tgtNormVec.
- local ascAnVec is vcrs(obtNormVec, tgtNormVec).
- local descAnVec is vcrs(tgtNormVec, obtNormVec).
- local diffLDN is body:geopositionof(descAnVec + body:position):lng - tgt:lng.
- local diffLAN is body:geopositionof(ascAnVec + body:position):lng - tgt:lng.
- local alpha is vang(obtNormVec, tgtNormVec).
- if diffLDN < -180 set diffLDN to diffLDN + 360.
- if diffLAN < -180 set diffLAN to diffLAN + 360.
- local nodeVec is choose descAnVec if diffLDN > 0 else ascAnVec.
- local na is vang((nodeVec + body:position), up:vector).
- if vang(vcrs(nodeVec, up:vector), obtNormVec) > 90 set na to 360 - na.
- local nts is time:seconds + na * orbit:period/360.
- local spd is velocityAt(ship, nts):orbit:mag.
- add node(nts, 0, (choose spd if diffLDN > 0 else -spd) * sin(alpha), spd * cos(alpha) - spd).
- }
- //returns terrain normalVector at given latlng
- function getTerrainNormal {
- parameter posll.
- parameter resolution is 1.
- local _delta is 360 * resolution / (2 * constant:pi * body:radius).
- local _a is latlng(posll:lat, mod(180 + posll:lng + _delta, 360) - 180).
- local _b is latlng(mod(90 + posll:lat + _delta, 360) - 90, posll:lng).
- local terrNorm is vcrs(_b:position - posll:position, _a:position - posll:position):normalized.
- return terrNorm.
- }.
- //returns terrain slope in degrees at given latlng
- function getTerrainSlope {
- parameter posll. //geoCoordinates
- return vang(posll:position - body:position, getTerrainNormal(posll)).
- }.
- //returns magnitude of gravity in at given altitude
- function getGravAcc {
- parameter _alt.
- local r is body:radius + _alt.
- return body:mu/(r^2).
- }.
- //returns orbital speed as scalar in m/s at given semimajoraxis and altitude
- function getOrbitSpeed {
- parameter _sma.
- parameter _alt.
- return sqrt(body:mu * ((2/(body:radius + _alt)) - (1/_sma))).
- }.
- //returns orbital period in sec at given semimajoraxis
- function getOrbitPeriod {
- parameter _sma.
- return 2 * constant:pi * sqrt(_sma^3 / body:mu).
- }.
- //returns corrected steering vector to match delta-V vector under gravity
- function getDriftVector {
- parameter acceleration. //magnitute of your acceleration (through engines) as scalar (m/s^2)
- parameter targetVector. //direction you want to accelerate in as (normalized) vector
- parameter gravity. //gravity-acceleration as vector
- if targetVector:mag = 0 return targetVector.
- if acceleration = 0 return v(0,0,0).
- //intersect sphere with straight:
- local A is targetVector:x^2 + targetVector:y^2 + targetVector:z^2.
- local B is -2 * targetVector:x * gravity:x -2 * targetVector:y * gravity:y -2 * targetVector:z * gravity:z.
- local C is gravity:x^2 + gravity:y^2 + gravity:z^2 - acceleration^2.
- local t is -0.5*(B/A) + sqrt((0.5*(B/A))^2 - C/A).
- local aVec is t * targetVector - gravity.
- return aVec.
- }.
- //returns longitude delta relative to longitude at ascent-node given anomaly-angle as (true_anomaly + argument_of_periapsis)
- function longitudeAtAnomalyOfAN {
- parameter _anom, _inc.
- if abs(_inc) >= 90 {
- if _anom < 90 OR _anom > 270 return 0.
- if _anom = 90 OR _anom = 270 return 90.
- if _anom > 90 AND _anom < 270 return 180.
- }
- else if abs(_inc) < 0.1 {
- return _anom.
- }
- return arcsin(round(sin(_anom) * cos(_inc) / sqrt(1 - (sin(_anom) * sin(_inc))^2), 10)).
- }.
- //returns latitude given longitude, inclination, period (sec), bodyRotationRate(deg/sec) and longitudeOfFirstHighpoint ('groundtrack')
- function getLatOfLng {
- parameter _lng. //longitude. NOTE:
- // As the groundtrack shifts each orbit, (_lng + 360) will not return the same as (_lng)! (unless orbital period = x * body:rotationperiod; x E N...)
- // _lng = [0, 360[ refers to the initial orbit where it hits latlng(_inc, _hp)
- // _lng = [360, 720[ refers to the orbit after the initial orbit etc., where an orbit starts at lng0 and ends at lng360.
- //
- parameter _inc. //orbital inclination
- parameter _per. //orbital period
- parameter _brr. //body rotation rate (deg per second)
- parameter _hp. //longitude of first max latitude (_inc > 0), or first min latitude (_inc < 0)
- return _inc * cos(360 * (_lng - _hp) / (360 - _per * _brr)).
- }.
- //returns altitude of glideslope at current distance from target.
- function getGlideAltitude {
- parameter spd_h, spd_v, d.
- if spd_h = 0 return false.
- return d * spd_v/spd_h.
- }.
- //transforms gps-coordinates into a geoposition.
- function geopositionFromCoordinates {
- parameter _degN, _minN, _secN, _prefixN.
- parameter _degE, _minE, _secE, _prefixE.
- local pN is list("NORTH", "N").
- local pS is list("SOUTH", "S").
- local pE is list("EAST", "E").
- local pW is list("WEST", "W").
- local lat is 0.
- local lng is 0.
- if pN:contains(_prefixN) set lat to (_degN + _minN/60 + _secN/3600).
- else if pS:contains(_prefixN) set lat to -(_degN + _minN/60 + _secN/3600).
- else {
- print _prefixN + " is not a valid north/south direction.".
- return false.
- }
- if pE:contains(_prefixE) set lng to (_degE + _minE/60 + _secE/3600).
- else if pW:contains(_prefixE) set lng to -(_degE + _minE/60 + _secE/3600).
- else {
- print _prefixE + " is not a valid east/west direction.".
- return false.
- }
- return latlng(lat, lng).
- }.
- //plans and executes deorbit maneuver given anomaly and speed
- function deorbit { //assumes eccentricity = 0
- parameter _anomaly.
- parameter _speed.
- set orbitSpeed to getOrbitSpeed((apoapsis + periapsis)/2 + body:radius, (apoapsis + periapsis)/2).
- set deorbitDV to _speed - orbitSpeed.
- lock maxAcceleration to ship:maxthrust/ship:mass.
- if maxAcceleration = 0 { //no thrust
- print "no thrust abort placeholder".
- }
- set burnDuration to deorbitDV/maxAcceleration.
- add node(time:seconds + mod(720 + _anomaly - orbit:trueAnomaly, 360) * orbit:period/360, 0, 0, deorbitDV).
- set executeNodeComplete to false.
- //executeNode("lower_Pe", deorbitPeriapsis).
- executeNode().
- when executeNodeComplete then set deorbitComplete to true.
- }.
- function executeNode {
- parameter _condition is "NONE".
- parameter _conValue is 0.
- set nd to nextnode.
- if nd:deltav:mag = 0 {
- remove nd.
- set executeNodeComplete to true.
- return false.
- }
- lock max_acc to ship:maxthrust/ship:mass.
- set burnDuration to nd:deltav:mag/max_acc.
- set ignitionTime to burnDuration/2.
- lock steering to nd:deltav.
- when vang(nd:deltav, ship:facing:vector) < 1 then {
- warpto(time:seconds + nd:eta - ignitionTime - shipRollTime).
- when vang(nd:deltav, ship:facing:vector) < 0.05 then {
- warpto(time:seconds + nd:eta - ignitionTime - shipRollTime/5).
- when nd:eta <= (ignitionTime) then {
- set done to false.
- if _condition = "lower_Pe" {
- lock throttle to min(3*nd:deltav:mag/max_acc, min(max((periapsis - _conValue)/8000, 0.0001), 1)).
- lock steering to retrograde.
- when done OR periapsis <= _conValue then {
- if done return false.
- set done to true.
- lock throttle to 0.
- }
- }
- else {
- lock throttle to min(3*nd:deltav:mag/max_acc, 1).
- set dv0 to nd:deltav.
- when done OR vdot(dv0, nd:deltav) < 0 then {
- if done return false.
- lock throttle to 0.
- set done to true.
- }
- when done OR nd:deltav:mag < 0.1 then {
- if done return false.
- unlock steering.
- set steering to nd:deltav.
- lock throttle to max(min(nd:deltav:mag/max_acc, 1), 0.0001).
- wait until vdot(dv0, nd:deltav) < 0.2.
- lock throttle to 0.
- set done to true.
- }
- }
- when done then {
- unlock steering.
- unlock throttle.
- remove nd.
- set executeNodeComplete to true.
- }
- }
- }
- }
- }.
- function engage {
- parameter minangle is 0.
- //parameter checks
- set invalidParams to list().
- set questionableParams to list().
- set deorbitAltitude to periapsis.
- if not (defined lowestSafeAltitude) set lowestSafeAltitude to periapsis - 100.
- if lowestSafeAltitude > deorbitAltitude - 100 set lowestSafeAltitude to deorbitAltitude - 100.
- fillOptionalParams().
- if not checkParamsValidity() {
- print "Found invalid parameters:".
- print " ".
- for i in invalidParams {
- print i[0] + ": " + i[1].
- print " ".
- }
- print "aborting".
- return false.
- }
- if questionableParams:length > 0 {
- print "WARNING! Found questionable parameters:".
- print " ".
- for i in questionableParams {
- print i[0] + ": " + i[1].
- print " ".
- }
- print "continuing".
- }
- set phase to "INIT".
- set guidanceStatus to "INIT".
- set vacLocLanderFinished to false.
- //main code
- set phase to "PLANNING".
- set guidanceStatus to "SLEEPING".
- set simResult to lexicon("STATUS", "EMPTY").
- set deorbitCalcFinished to false.
- //TODO: get real descentStage values.
- if not (defined descentStageThrust) set descentStageThrust to ship:availablethrust.
- if not (defined descentStageMassFlow) {
- set descentStageMassFlow to 0.
- list engines in elist.
- for en in elist set descentStageMassFlow to descentStageMassFlow + en:maxMassFlow.
- }
- if not (defined descentStageMass) set descentStageMass to ship:mass.
- calculateDeorbit(minangle).
- when deorbitCalcFinished then {
- set phase to "SYNCRONISATION".
- set deorbitLongitude to mod(900 + tgt:lng - 90 + longitudeAtAnomalyOfAN(90 - simResult:finalAngle, abs(tgt:lat)) + 360/body:rotationperiod * simResult:duration, 360) - 180.
- //set inclinationDeadzone to arctan(((simResult:burn:stepLog[0][1] - landingAltitude) * crossrangeAbility)/body:radius).
- set deorbitComplete to false.
- //approach
- set guidanceStatus to "EXPERIMENTAL APPROACH".
- planFlyover(tgt).
- set executeNodeComplete to false.
- executeNode().
- when executeNodeComplete then {
- set phase to "DEORBIT".
- set touchdownArgumentOfAN to (choose 90 if tgt:lat > 0 else 270).
- set currANLNG to mod(900 + longitude - longitudeAtAnomalyOfAN(orbit:trueAnomaly + orbit:argumentOfPeriapsis, orbit:inclination), 360) - 180.
- set tarANLNG to mod(900 + tgt:lng - touchdownArgumentOfAN, 360) - 180.
- set diffANLNG to mod(720 + tarANLNG - currANLNG, 360).
- set deorbitLAN to mod(720 + orbit:LAN + diffANLNG + 0.5 * orbit:period * 360/body:rotationPeriod + 90 * orbit:period/body:rotationPeriod, 360).
- set totangle to 360 - vang(-body:position, tgt:position - body:position).
- set relangle to totangle - simResult:finalAngle + simResult:duration * 360/body:rotationperiod.
- set anom to mod(360 + orbit:trueAnomaly + relAngle + relAngle * orbit:period/body:rotationPeriod, 360).
- deorbit(anom, deorbitSpeed).
- }
- when deorbitComplete then {
- if vacLocLanderFinished return false.
- set timestampDeorbit to time:seconds.
- if stage:number > landingStage {
- set phase to "STAGING".
- lock steering to up.
- on time:second {
- if stage:ready AND vang(steering:vector, ship:facing:vector) < 1 {
- stage.
- }
- return stage:number > landingStage.
- }
- when stage:number <= landingStage then {
- set phase to "COASTING".
- lock steering to srfRetrograde.
- }
- }
- else {
- set phase to "COASTING".
- lock steering to srfRetrograde.
- }
- }
- when phase = "COASTING" AND time:seconds >= min(timestampDeorbit + simResult:ignitionTime * 0.8, timestampDeorbit + simResult:ignitionTime - shipRollTime * 3) then {
- if vacLocLanderFinished return false.
- set warp to 0.
- matchGlide().
- }
- when phase = "GUIDANCE_RELEASED" then {
- if vacLocLanderFinished return false.
- lock throttle to min(3-vang(steering:vector, ship:facing:vector), getGravAcc(altitude)*ship:mass/ship:availableThrust + max(0, 1 - (altitude - (tgt:terrainHeight + landingHeight)))*(-verticalSpeed - landingDescendSpeed)/ship:availableThrust).
- when status = "landed" OR status = "splashed" then {
- lock throttle to 0.
- if ship:groundspeed > 0.1 {
- set phase to "TOUCHDOWN".
- brakes on.
- when velocity:surface:mag < 0.01 then {
- unlock steering.
- set phase to "STOPPED".
- }
- }
- else {
- lock steering to ship:facing.
- set phase to "LANDED".
- }
- }
- }
- }
- when (phase = "LANDED" OR phase = "STOPPED") AND not (defined landingOverride) then {
- lock throttle to 0.
- lock steering to getTerrainNormal(latlng(latitude, longitude)):direction + R(0, 0, ship:facing:roll).
- set releaseTimestamp to time:seconds + landedSettleTime.
- when time:seconds > releaseTimestamp then {
- unlock steering.
- set vacLocLanderFinished to true.
- print "landing finished".
- }
- }
- }.
- function centerOfMass {
- parameter _plist.
- local tmass is 0.
- local tvec is v(0,0,0).
- for p in _plist {
- set tmass to tmass + p:mass.
- set tvec to tvec + p:mass * p:position.
- }
- return tvec/tmass.
- }
- //manages descent with active guidance towards landing spot
- function matchGlide {
- local elist is list().
- local avThrust is 0.
- local mxThrust is 0.
- local mxMass is 0.
- local avMass is 0.
- local slopeAlt is 0.
- local expMaxAcceleration is 0.
- list engines in elist.
- //TODO: only list active and usable engines
- for e in elist {
- set avThrust to avThrust + e:availableThrust.
- set mxThrust to mxThrust + e:maxThrust.
- set mxMass to mxMass + e:maxMassFlow.
- }
- set avMass to mxMass * avThrust / mxThrust.
- //main code
- lock landingPoint to (tgt:position - body:position):normalized * (body:radius + landingAltitude).
- if not (defined landingVelocity) {
- lock _landingVelocity to -landingPoint:normalized * landingDescendSpeed + vxcl(landingPoint, landingPoint + body:position):normalized * landingGroundSpeed.
- }
- else set _landingVelocity to landingVelocity.
- lock startPoint to landingPoint - _landingVelocity*glideTime.
- set brr to 360/body:rotationPeriod.
- lock vel_h to vxcl(ship:up:vector, velocity:surface).
- lock vel_v to velocity:surface - vel_h.
- lock vel_cr to vxcl(vxcl(ship:up:vector, startPoint + body:position), vel_h).
- lock vel_dr to vel_h - vel_cr.
- lock timeStart to vxcl(ship:up:vector, startPoint + body:position):mag / vel_h:mag.
- //TODO: find a way to make predAltitude more precise.
- lock predAltitude to (positionAt(ship, time:seconds + timeStart) - body:position):mag - body:radius.
- lock expMaxAcceleration to avThrust/ship:mass - getGravAcc(startPoint:mag - body:radius).
- lock maxAcceleration to ship:availableThrust/ship:mass.
- lock dVGlide to _landingVelocity - velocity:surface.
- lock btGlide to dvGlide:mag/expMaxAcceleration.
- lock predAltError to predAltitude - (startPoint:mag - body:radius).
- if landingGroundSpeed < 1e-5 lock slopeAlt to altitude.
- else lock slopeAlt to getGlideAltitude(landingGroundSpeed, landingDescendSpeed, vxcl(ship:up:vector, landingPoint + body:position):mag) + landingPoint:mag - body:radius.
- set phase to "ACTIVE_GUIDANCE".
- set guidanceStatus to "ARMED".
- set guidanceActive to true.
- set velCrMatch to false.
- set expAltMatch to false.
- set rcsActive to false.
- set hoverslam to false.
- if abs(predAltError) > 1e-3 {
- set guidanceStatus to "REDUCING_DOWNRANGE_ALTITUDE_ERROR".
- if predAltError > 10 {
- lock steering to heading(mod(180 + body:geopositionof(startPoint + body:position):heading, 360), 0).
- lock throttle to min(2 - vang(steering:vector, facing:vector), min(0.3, max(predAltError/100, 0.001))).
- when predAltError < 10 and not hoverslam then {
- lock throttle to 0.
- set expAltMatch to true.
- }
- }
- else if predAltError < 5 {
- lock steering to heading(mod(180 + body:geopositionof(startPoint + body:position):heading, 360), 90).
- lock throttle to min(2 - vang(steering:vector, facing:vector), min(0.3, max(-predAltError/100, 0.001))).
- when predAltError > 8 and not hoverslam then {
- lock throttle to 0.
- set expAltMatch to true.
- }
- }
- else set expAltMatch to true.
- }
- else set expAltMatch to true.
- when expAltMatch and not hoverslam then {
- if vacLocLanderFinished return false.
- if vel_cr:mag > 1e-3 {
- set guidanceStatus to "REDUCING_CROSSRANGE_SPEED".
- lock steering to -vel_cr.
- lock throttle to min(5 - vang(steering, facing:vector), max(vel_cr:mag/maxAcceleration, 0.005)).
- when vel_cr:mag < 1 and not hoverslam then {
- local vel_cr0 is vel_cr.
- lock steering to -vel_cr0.
- lock throttle to min(2 - vang(steering, facing:vector), max(vel_cr:mag/maxAcceleration, 0.01)).
- when vdot(vel_cr0, vel_cr) < 0 and not hoverslam then {
- lock throttle to 0.
- set velCrMatch to true.
- }
- }
- }
- else set velCrMatch to true.
- }
- when guidanceActive AND (velCrMatch OR hoverslam) then {
- if vacLocLanderFinished return false.
- if not hoverslam {
- set guidanceStatus to "RCS_ERROR_REDUCTION".
- lock steering to dVGlide + getGravAcc(altitude) * btGlide * ship:up:vector.
- }
- set rcsPrestate to lexicon().
- set rcsPrestate:active to RCS.
- set rcsPrestate:thrusters to list().
- set rcsThrusters to ship:modulesnamed("modulercsfx").
- for t in rcsThrusters {
- if t:allEventNames:contains("show actuation toggles") t:doevent("show actuation toggles").
- rcsPrestate:thrusters:add(list(t:getField("yaw"), t:getField("pitch"), t:getField("roll"), t:getField("port/stbd"), t:getField("dorsal/ventral"), t:getField("fore/aft"))).
- }
- lock downrange to vxcl(ship:up:vector, velocity:surface):normalized.
- lock nstar to vcrs(downrange, ship:up:vector):normalized.
- lock velTop to vxcl(nstar, vel_h).
- lock velStar to vxcl(downrange, vel_h).
- lock dvStar to vxcl(vxcl(ship:up:vector, _landingVelocity), vxcl(ship:up:vector, dVGlide)).
- lock dvTop to vxcl(ship:up:vector, dvGlide) - dvStar.
- set rcsActive to true.
- when vang(steering, facing:vector) < 5 AND abs(90 - vang(ship:facing:topvector, nstar)) < 5 then {
- for t in rcsThrusters {
- if not rcsPrestate:active {
- t:setField("yaw", false).
- t:setField("pitch", false).
- t:setField("roll", false).
- }
- t:setField("port/stbd", true).
- t:setField("dorsal/ventral", true).
- t:setField("fore/aft", true).
- rcs on.
- }
- on round(time:seconds*3) {
- if rcsActive {
- if guidanceStatus = "MINIMIZING_GROUNDSPEED" {
- set ship:control:top to 2 * velTop:mag * ((vang(velTop, downrange)-90)/90).
- set ship:control:starboard to velStar:mag * ((vang(velStar, nstar)-90)/90).
- }
- else if guidanceStatus = "MATCHING_GLIDESLOPE" {
- set ship:control:top to -3 * dvTop:mag * ((vang(dvTop, vxcl(ship:up:vector, _landingVelocity))-90)/90).
- set ship:control:starboard to dvStar:mag * ((vang(dvStar, vxcl(ship:up:vector, _landingVelocity)))/90). //missing '-90' is intentional!
- set ship:control:fore to max(slopeAlt, landingPoint:mag - body:radius) - altitude.
- }
- else if guidanceStatus = "MATCHING_GROUNDSPEED" {
- set ship:control:top to 0.
- set ship:control:starboard to 0.
- }
- else if abs(90 - vang(ship:facing:topvector, nstar)) < 5 {
- set ship:control:starboard to 5*vdot(vcrs(startPoint + body:position, ship:up:vector):normalized, -vel_cr).
- if guidanceStatus <> "HOVERSLAM_EXECUTION" set ship:control:top to -predAltError/30.
- else set ship:control:top to 0.
- if abs(ship:control:starboard) < deadzoneRCSstarboard set ship:control:starboard to 0.
- if abs(ship:control:top) < deadzoneRCStop set ship:control:top to 0.
- }
- else {
- set ship:control:starboard to 0.
- set ship:control:top to 0.
- }
- return true.
- }
- else {
- set rcs to rcsPrestate:active.
- local _i is 0.
- for t in rcsThrusters {
- t:setField("yaw", rcsPrestate:thrusters[_i][0]).
- t:setField("pitch", rcsPrestate:thrusters[_i][1]).
- t:setField("roll", rcsPrestate:thrusters[_i][2]).
- t:setField("port/stbd", rcsPrestate:thrusters[_i][3]).
- t:setField("dorsal/ventral", rcsPrestate:thrusters[_i][4]).
- t:setField("fore/aft", rcsPrestate:thrusters[_i][5]).
- set _i to _i + 1.
- }
- set ship:control:starboard to 0.
- set ship:control:top to 0.
- return false.
- }
- }
- }
- }
- when rcsActive OR timeStart < btGlide + shipRollTime/2 then {
- if vacLocLanderFinished return false.
- if not rcsActive {
- set guidanceStatus to "HOVERSLAM_PREPARATION".
- lock steering to dVGlide + getGravAcc(altitude) * btGlide * ship:up:vector.
- }
- set hoverslam to true.
- lock throttle to 0.
- when guidanceActive AND (vxcl(ship:up:vector, startPoint + body:position):mag <= (0.5 * (vxcl(ship:up:vector, velocity:surface):mag)^2 / (vxcl(ship:up:vector, ship:availableThrust * thrustFactor * steering:normalized):mag/ship:mass))) then {
- set phase to "FINAL_APPROACH".
- set guidanceStatus to "HOVERSLAM_EXECUTION".
- if not gear when alt:radar <= gearDeployAltitude then gear on.
- lock throttle to max(1e-50, min(1, dVGlide:mag/(max(1, timeStart) * ship:availableThrust/ship:mass))).
- lock steering to dVGlide + getGravAcc(altitude) * (btGlide/throttle) * ship:up:vector.
- when guidanceActive AND (vdot(velocity:surface, startPoint + body:position) < 0 OR dVGlide:mag < 0.5 OR (ship:groundspeed - landingGroundSpeed) < 0.5) then {
- set phase to "LANDING".
- set guidanceStatus to "MATCHING_GROUNDSPEED".
- lock downrange to heading(90, 0):vector:normalized.
- lock nstar to -heading(90, 0):starvector:normalized.
- lock throttle to max(dvGlide:mag/(ship:availableThrust/ship:mass), getGravAcc(altitude)*ship:mass/ship:availableThrust + max(0, 1 - (altitude - max(slopeAlt, landingPoint:mag - body:radius)))*(-verticalSpeed - landingDescendSpeed)/ship:availableThrust).
- when guidanceActive AND (abs(ship:groundspeed - landingGroundSpeed) < 0.5 ) then {
- if landingGroundSpeed < 1e-5 {
- set guidanceStatus to "MINIMIZING_GROUNDSPEED".
- lock steering to heading(90, 90, 180).
- lock throttle to min(10-vang(steering:vector, ship:facing:vector), getGravAcc(altitude)*ship:mass/ship:availableThrust + max(0, 1 - (altitude - max(slopeAlt, landingPoint:mag - body:radius)))*(-verticalSpeed - landingDescendSpeed)/ship:availableThrust).
- }
- else {
- gear on.
- set guidanceStatus to "MATCHING_GLIDESLOPE".
- lock throttle to 0.
- lock steering to heading(body:geopositionof(velocity:surface:normalized * 100):heading, 90, 180).
- lock throttle to min(3-vang(steering:vector, ship:facing:vector), getGravAcc(altitude)*ship:mass/ship:availableThrust + max(0, 1 - (altitude - max(slopeAlt, landingPoint:mag - body:radius)))*(-verticalSpeed - landingDescendSpeed)/ship:availableThrust).
- when guidanceActive AND mod(720 + longitude - tgt:lng, 360) > 180 then {
- rcs off.
- set rcsActive to false.
- }
- }
- }
- }
- }
- }
- when guidanceActive AND (status = "landed" OR status = "splashed" or altitude <= (landingPoint:mag - body:radius)) then {
- if vacLocLanderFinished return false.
- lock throttle to 0.
- rcs off.
- set rcsActive to false.
- set guidanceActive to false.
- if status = "landed" OR status = "splashed" {
- if ship:groundspeed > 0.1 {
- set phase to "TOUCHDOWN".
- brakes on.
- when velocity:surface:mag < 0.01 then {
- unlock steering.
- set phase to "STOPPED".
- }
- }
- else {
- set phase to choose "LANDED" if status = "landed" else "SPLASHED".
- }
- set guidanceStatus to "ENDED".
- }
- else {
- set phase to "GUIDANCE_RELEASED".
- set guidanceStatus to "ENDED".
- }
- }
- }.
- until not hasnode {remove nextnode. wait 0.}.
- clearscreen. for i in range(2) print " ".
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement