sumguytwitches

VTOL hover experimental hathi

Aug 17th, 2023
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //VTOL hover script with side translation - Ozin
  2. // !runscript xeNy4xmv
  3. clearscreen.
  4. core:doaction("open terminal",true).
  5. clearvecdraws().
  6. clearguis().
  7. sas off.
  8. HUDTEXT("Running script: VTOL hover for jets & propellers",20,2,22,white,false).
  9.  
  10. //===[Setup shitload of vars]=== A lot of these get updated in triggers and functions but need to be delcared here first with initial values.
  11. if not(defined places) and exists("0:/json/" + body:name + ".json") set places to readjson("0:/json/" + body:name + ".json").
  12.  
  13. if vang(up:vector,facing:vector) > 60 toggle ag2.
  14.  
  15. set props to false.
  16.  
  17.  
  18. set estNeutral to 0.
  19. set tarAOA to 0.
  20.  
  21. set mathThingy to 2 * constant:pi * 5.8 * 460/60.
  22. function bladeAOA { parameter ang.
  23.     set tarAOA to ang.
  24.     for rotor in rotors {
  25.         set relSpd to vdot(rotor[0]:facing:vector * rotor[1], vel).
  26.         set estNeutral to arctan(abs(relSpd)/mathThingy) * relSpd/abs(relSpd).
  27.         for i in range(2,rotor:length) {
  28.             rotor[i]:setfield("deploy angle",estNeutral + ang).
  29.         }
  30.     }
  31. }
  32.  
  33. set vtol to true.
  34. set steeringmanager:rollcontrolanglerange to 180.
  35. set steeringmanager:rollpid:kp to 0.4.
  36. set steeringmanager:rollpid:ki to 0.04.
  37. set steeringmanager:rollpid:kd to 0.25.
  38. set steeringmanager:yawpid:kd to 0.15.
  39. set steeringmanager:maxstoppingtime to 6.
  40.  
  41. set flipSteering to false.
  42. set face to facing.
  43. set bnds to ship:bounds.
  44. set st to lookdirup(up:vector, face:topvector).
  45. lock hdg to 90. lock sl to 0.
  46. set relVelVec to v(0,0,0).
  47. lock tAltOverride to 0.
  48. set terSlope to 0.
  49. set twr to 1.
  50. set grav to 9.
  51. set acc to 10.
  52. lock height to 20.
  53. set hvel to v(0,0,0).
  54. set vel to velocity:surface.
  55. set velOld to vel.
  56. lock terAlt to max(0,ship:geoposition:terrainheight).
  57. lock talt to choose tAltOverride if tAltOverride <> 0 else height + terAlt.
  58. set altErr to altitude - talt.
  59. set tiltOutwards to 0.
  60. lock vsOverride to 0.
  61. set vsMin to -100.
  62. set vsMax to 200.
  63. set vs to 0.
  64. set vsErr to 0.
  65. set stTopVector to face:topvector.
  66. set terI to 1.
  67. set terSteps to 15.
  68. set terStepDist to 0.25.
  69. set terSlope2 to 0.
  70. set terJ to 0.
  71. set mul to 0.
  72. set followDist to 0.
  73. set hdgLag to hdg.
  74. lock tv to heading(hdgLag,0):vector * sl.
  75. set tvCopy to tv.
  76. set tvCopyMag to 0.
  77. set pitchoffset to 0.
  78.  
  79. if ship:partsnamedpattern("grap"):length > 0 {
  80.     set localport to ship:partsnamedpattern("grap")[0].
  81. } else if ship:dockingports:length > 0 {
  82.     set localport to ship:dockingports[0].
  83. } else {
  84.     set localport to false.
  85. }
  86. set mode to "Heading".
  87. set tgt to false.
  88. set alignTerrainHeight to 10.
  89. set race to false.
  90. when alt:radar > 10 then gear off.
  91.  
  92.  
  93. set menu to gui(260, 30). Set menu:x to -30. set menu:y to 300. menu:show.
  94. menu:addlabel("<b><color=yellow>VTOL 2-axis script</color></b>").
  95. set m0 to menu:addlabel("Mode:").
  96. set m1 to menu:addlabel("SL:").
  97. set m2 to menu:addlabel("HDG:").
  98. set m3 to menu:addlabel("Height:").
  99. set m4 to menu:addlabel("tAltOverride:").
  100. set m5 to menu:addlabel("vsOverride:").
  101. set m6 to menu:addlabel("alt:radar:").
  102. set m7 to menu:addlabel("trackCam:").
  103. set m8 to menu:addlabel("alignTerrainHeight:").
  104. set m9 to menu:addlabel("tiltOutwards:").
  105. set m10 to menu:addlabel("Localport:").
  106. set mLast to menu:addlabel("Functions: <color=white>goToTarget(), goToPosition(<geopos or position>), goTo(<Name>), resetSteering()</color>").
  107. set mLast2 to menu:addlabel("Additional vars: <color=white>vsMin, vsMax, sideTiltMult</color>").
  108. set mIPU to menu:addlabel("IPU: ").
  109. set mLast3 to menu:addlabel(".").
  110. set mLast4 to menu:addlabel(".").
  111. set mAOA to menu:addlabel(".").
  112.  
  113.  
  114. for txt in menu:widgets { set txt:style:fontsize to 14. set txt:style:padding:v to 1. }
  115. set m3:style:margin:top to 15.
  116. set m5:style:margin:bottom to 15.
  117.  
  118. wait 1.
  119. //===[Functions]===
  120.  
  121.  
  122. function vertThrust {
  123.     if props return max(1, vdot(rotor1:facing:vector, up:vector) * 20).
  124.    
  125.     set vth to 0.
  126.     for e in engs if e:ignition {
  127.         set vth to vth + vdot(up:vector, e:facing:vector * (choose -1 if e:tag = "reverse" else 1)) * e:availablethrust.
  128.     }
  129.     return max(1,vth).
  130. }
  131. function norm {
  132.     parameter p0 is v(0,0,0).
  133.     set u to (p0-body:position):normalized.
  134.     set p1 to vxcl(u,facing:vector):normalized * (bnds:size:mag).
  135.     set g2 to body:geopositionof(angleaxis(120, u) * p1 + p0). set p2 to choose g2:position if g2:terrainheight > 0 else g2:altitudeposition(0).
  136.     set g3 to body:geopositionof(angleaxis(-120, u) * p1 + p0). set p3 to choose g3:position if g3:terrainheight > 0 else g3:altitudeposition(0).
  137.     set g1 to body:geopositionof(p1 + p0). set p1 to choose g1:position if g1:terrainheight > 0 else g1:altitudeposition(0).
  138.     return vcrs(p1-p2,p1-p3):normalized.
  139. }
  140. function getSlope {
  141.     parameter pos, vec.
  142.     local g1 is body:geopositionof(pos). local p1 is choose g1:position if g1:terrainheight > 0 else g1:altitudeposition(0).
  143.     local g2 is body:geopositionof(pos+vec). local p2 is choose g2:position if g2:terrainheight > 0 else g2:altitudeposition(0).
  144.     return 90 - vang(up:vector, p2-p1).
  145. }
  146.  
  147. set terDisplay to false.
  148.  
  149. function showVD {
  150.     toggle terDisplay.
  151.     set vdTer to vecdraw(v(0,0,0), up:vector * 1, red, "", 1, true, 0.9).
  152.     set vdSlope to vecdraw(v(0,0,0), up:vector * 1, yellow, "", 1, true, 0.4).
  153.     set vdVel to vecdraw(v(0,0,0), up:vector * 1, blue, "", 1, true, 0.4).
  154.     set vdAcc to vecdraw(v(0,0,0), up:vector * 1, green, "", 1, true, 0.3).
  155. }
  156. function terDisplayFunc {
  157.     set vdTer:start to pi.
  158.     set vdTer:vec to (angleaxis(terSlope, vcrs(hvel, up:vector)) * up:vector) * height.
  159.     set vdTer:width to 1 + (pi:mag^0.75) / 80.
  160.    
  161.     set vdSlope:vec to angleaxis(terSlope, vcrs(tvCopy, up:vector)) * tvCopy / 5.
  162.     set vdVel:vec to vel / 5.
  163.    
  164.     set velDiff to vel-velOld.
  165.     set vdAcc:vec to (velDiff:normalized * (velDiff:mag/0.02)) / 10.
  166.     set velOld to vel.
  167. }
  168.  
  169.  
  170. function tiltStar {
  171.     parameter tlt is 0.
  172.     if vsErr < -1 set tlt to tlt + tlt * max(-1, vsErr / 8).
  173.     set tlt to tlt + vang(up:vector,  face:starvector) - 90.  
  174.     set rollError to steeringmanager:rollpid:output. // rollerror
  175.     for hinge in servosSideTilt hinge["s"]:setfield("target angle", tlt * hinge["direction"] * hinge["right"] + tiltOutwards + min(20, max(-20,(rollError * 40) * hinge["front"] * hinge["right"])) ).
  176. }
  177. function tilt {
  178.     parameter tlt is 0.
  179.     //if vsErr < -1  and (vdot(hvel:normalized, relVelVec) > -2 or vdot(tvCopy, hvel) < 0) or race set tlt to tlt + tlt * max(-1, vsErr / 10).
  180.     if vsErr < -1  set tlt to tlt + tlt * max(-1, vsErr / 10).
  181.     set curPitch to choose (vang(up:vector,  face:topvector) - 90) if vdot(face:vector, up:vector) >= 0 else (90 + vang(up:vector, -facing:topvector)).
  182.     set tlt to tlt + curPitch.
  183.     if tlt > 180 set tlt to tlt - 360.
  184.     set mLast4:text to "pitch tilt: " + round(tlt,2).
  185.     for s in servos s["s"]:setfield("target angle", tlt).
  186.     //if tlt > 45 {
  187.     //  for s in servos s["s"]:setfield("target angle", tlt + s["front"] * steeringmanager:pitcherror / -2).
  188.     //} else {
  189.     //  for s in servos s["s"]:setfield("target angle", tlt).
  190.     //}
  191. }
  192. function goToTarget {
  193.     if localport:istype("part") {
  194.         lock tv to choose (vxcl(up:vector,(target:position + target:facing:vector * -followDist) - localport:position):normalized * min(sl,(vxcl(up:vector,(target:position + target:facing:vector * -followDist) - localport:position):mag/3)^0.75) + (choose target:velocity:surface if target:loaded else v(0,0,0))) if hastarget else v(0,0,0).
  195.        
  196.     } else {
  197.         lock tv to choose (vxcl(up:vector,target:position + target:facing:vector * -followDist):normalized * min(sl,(vxcl(up:vector,target:position + target:facing:vector * -followDist):mag/3)^0.75) + (choose target:velocity:surface if target:loaded else v(0,0,0))) if hastarget else v(0,0,0).
  198.     }
  199.     set mode to "Target".
  200.     if sl < 1 { set sl to 5. HUDTEXT("SL (speedlimit) is low, setting SL to 5..",16,2,20,yellow,false). }
  201. }
  202. function goToPosition {
  203.     parameter pos.
  204.     if pos:typename = "Vector" set pos to body:geopositionof(pos).
  205.     set tgt to pos.
  206.     lock tv to vxcl(up:vector,tgt:position):normalized * min(sl,(vxcl(up:vector,tgt:position):mag/3)^0.70) - (choose localport:position if localport:istype("part") else v(0,0,0)).
  207.     set mode to "GeoPos".
  208.     if sl < 1 { set sl to 5. HUDTEXT("SL (speedlimit) is low, setting SL to 5..",16,2,20,yellow,false). }
  209. }
  210. function goto {
  211.     parameter where.
  212.     if not(defined places) { print "ERROR: places json not loaded.". }
  213.     else if places:haskey(where) { gotoposition(places[where]). }
  214.     else { print char(7)+ "ERROR: no known place: " + where. }
  215. }
  216. function resetSteering { lock tv to heading(hdgLag,0):vector * sl. lock steering to st. set mode to "Heading". set keepCamSteer to false. }
  217.  
  218. function powerdown {
  219.     for s in ship:modulesnamed("ModuleRoboticServoRotor") s:setfield("torque limit(%)", 0).
  220.     on height powerup().
  221. }
  222. function powerup {
  223.     if props {
  224.         set t0 to time:seconds.
  225.         when true then {
  226.             set tPercent to min(100,(time:seconds - t0) * 33).
  227.             for s in ship:modulesnamed("ModuleRoboticServoRotor") s:setfield("torque limit(%)", tPercent).
  228.             return tPercent < 100.
  229.         }
  230.     }
  231. }
  232.  
  233. //===[engine & servos setup]===
  234. set engs to list().
  235. list engines in engs2. for e in engs2 if e:tag <> "aft" engs:add(e).
  236. set allServos to ship:modulesnamed("ModuleRoboticRotationServo").
  237. set servos to list().
  238. set yawServos to list().
  239. set servosSideTilt to list().
  240. for s in allServos {
  241.    
  242.     if s:part:tag = "yaw" {
  243.         yawServos:add(s).
  244.     } else if abs(vdot(facing:starvector, s:part:facing:vector)) > 0.5 {
  245.         local sLex is lexicon("direction", 1, "right", choose 1 if vdot(face:starvector, s:part:position) > 0 else -1, "front", choose 1 if vdot(face:topvector, s:part:position) < 0 else -1, "s", s).
  246.         servos:add(sLex).
  247.     } else if abs(vdot(facing:topvector, s:part:facing:vector)) > 0.5 {
  248.         local sLex is lexicon("direction", choose -1 if vdot(facing:topvector, s:part:facing:vector) > 0 else 1,"right", choose 1 if vdot(face:starvector, s:part:position) > 0 else -1, "front", choose 1 if vdot(face:topvector, s:part:position) < 0 else -1, "s", s).
  249.         servosSideTilt:add(sLex).
  250.     }
  251. }
  252.  
  253.  
  254. for m in ship:modulesnamed("ModuleRoboticServoHinge") {
  255.     if m:part:tag = "enginePitch" {
  256.         local pitchEngLex is lexicon("right", 0, "front", 0, "s", m).
  257.         servos:add(pitchEngLex).
  258.     }
  259.     else if m:part:tag <> "ignore" {
  260.         local pPos is m:part:position.
  261.         local l is lexicon("direction", 1, "right", choose 1 if vdot(face:starvector, pPos) > 0 else -1, "front", choose 1 if vdot(face:topvector, pPos) < 0 else -1, "s", m).
  262.         if not (props) and engs:length <= 2 set l["front"] to 0.
  263.         servosSideTilt:add(l).
  264.     }
  265. }
  266. for l in servos { l["s"]:setfield("damping", 100). l["s"]:setfield("traverse rate", 120). }
  267. for l in servosSideTilt { l["s"]:setfield("damping", 50). l["s"]:setfield("traverse rate", 120). }
  268.  
  269. set twoaxistilt to (servosSideTilt:length > 1).
  270. if twoaxistilt HUDTEXT("2-axis engine tilting enabled. Toggle 'twoaxistilt' to disable",20,2,22,yellow,false).
  271. set sideTiltMult to choose 0.50 if twoaxistilt else 1.
  272. set jets to false.
  273. for e in engs if e:sealevelisp > 3000 jets on.
  274.  
  275. //===[PID controllers]===
  276. if props {
  277.     set aoaPID to pidloop(1.5, 0, 0, -2, 5).
  278. } else if jets {
  279.     set tpid to pidloop(8,0.2, 9, -0.5, 4).
  280. } else {
  281.     set tpid to pidloop(2,0.2, 0.0, -1, 4).
  282. }
  283. set vsPID to pidloop(1,1,1,-50,100).
  284. set tltpid to pidloop(20, 2, 2, -35, 75).
  285. set tltStarpid to pidloop(20, 2, 2, -35, 35).
  286.  
  287. when sl >= 200 then if ship:availablethrust = 0 stage.
  288.  
  289.  
  290. wait 1.
  291.  
  292. //===[TRIGGER WARNING!]===
  293. //5hz trigger
  294.  
  295. if not props {
  296.     set curThrust to vertThrust().
  297.     on round(time:seconds * 5) {
  298.         set grav to body:mu/body:position:sqrmagnitude.
  299.         set curThrust to min(curThrust * 1.05,vertThrust()).
  300.         set twr to (curThrust/mass)/grav.
  301.         set acc to max(0.1, curThrust/mass - grav).
  302.         set tpid:maxoutput to twr - 1.
  303.         set tpid:minoutput to (choose -0.5 if altErr > -1 else -1).
  304.         return vtol.
  305.     }
  306. }
  307. //fast (50hz) trigger
  308. when true then {
  309.     set face to choose facing + r(0,0,180) if flipSteering else facing.
  310.     set vel to velocity:surface.
  311.     set hvel to vxcl(up:vector,vel).
  312.     //if hdgLag <> hdg {
  313.     //  set hdgLag to choose round(hdgLag-1) if sin(hdg-hdgLag)<0 else round(hdgLag+1).
  314.     //}
  315.     set hdgLag to hdg.
  316.    
  317.     set tvCopy to tv.
  318.     set tvCopyMag to tvCopy:mag.
  319.     set altErr to altitude - (choose talt if (mode <> "Target") else target:altitude).
  320.    
  321.     //[Terrain detection and minimum climb angle]
  322.     if tAltOverride = 0 and vsOverride = 0 {
  323.         set gi to body:geopositionof((hvel * (1.5 - terI/terSteps) + tvCopy * terI/terSteps):normalized * (groundspeed + (tvCopyMag + groundspeed)/2 * (terI^1.4) * terStepDist)).
  324.         set pi to choose gi:position if gi:terrainheight > 0 else gi:altitudeposition(0).
  325.         set tempSlope to max(-60,90 - vang(up:vector, pi + (angleaxis(terSlope, vcrs(hvel, up:vector)) * up:vector) * min(alt:radar + height * terI/terSteps,height))).
  326.         if tempSlope > terSlope {
  327.             set terSlope to tempSlope.
  328.             set terJ to 0.
  329.         } else {
  330.             set terJ to terJ + 1.
  331.             set terSlope2 to max(tempSlope, terSlope2 * 0.999 + 0.001 * tempSlope).
  332.             if terJ > terSteps * 3 + 30 { set terJ to 0. set terSlope to terSlope2. set terSlope2 to max(-30, terSlope2 - 25).  }
  333.         }
  334.         if terDisplay terDisplayFunc().
  335.         set terI to terI + terStepDist.
  336.         if terI > terSteps {
  337.             set terI to terStepDist.
  338.             //if terSlope > 0 set terSlope to max(terSlope, getSlope(vel:normalized * (sl * terSteps), vel:normalized * (sl * 2))).
  339.         }
  340.     }
  341.    
  342.     //[Target vertical speed & throttle]
  343.     set slopeVS to choose vsMin if (tAltOverride <> 0 or groundspeed < 3) else (tan(terSlope) * (groundspeed * 1.1 + (choose 0 if altErr < 0 else max(0,20 - groundspeed^1.5)))).
  344.     set vs to choose vsOverride if vsOverride <> 0 else max(max(vsMin,slopeVS)  ,min(vsMax,       choose (-1 * (0.7 * acc * max(altErr + min(0, verticalspeed * 1) ,0.0001))^0.4) if altErr > 0 else sqrt(2 * (grav/2) * max(-altErr - verticalspeed * 0.2,0.0001))         )).
  345.     set vsErr to verticalspeed - vs.
  346.     if props {
  347.         bladeAOA(aoaPID:update(time:seconds, vsErr)).
  348.     } else {
  349.         set mul to 1 + tpid:update(time:seconds,vsErr).
  350.         if vsErr < -10 tPid:reset().
  351.     }
  352.     set relVelVec to vxcl(up:vector, min(1,  max(0, 1 + (2 + vsErr) / 20)) * tvCopy - vel) / 4.
  353.     set relVelVec:mag to min(5,relVelVec:mag).
  354.    
  355.     for s in yawServos s:setfield("target angle", steeringmanager:yawpid:output * 20).
  356.     return vtol.
  357. }
  358.  
  359. //12hz trigger - steering and engine tilt
  360. on round(time:seconds * 12) {
  361.     set backDir to vxcl(up:vector, choose (face:topvector) if vdot(up:vector, face:vector) >= 0 else (-face:topvector)):normalized.
  362.     tilt(tltpid:update(time:seconds, vdot(backDir, relVelVec))).
  363.    
  364.     set stTopVector to choose tvCopy * (choose 1 if flipSteering else -1) if tvCopyMag > 2 else (choose -target:facing:topvector if hastarget else face:topvector).
  365.     if twoaxistilt {
  366.         tiltStar(tltStarpid:update(time:seconds, vdot(face:starvector, relVelVec))).
  367.         set st to lookdirup(angleaxis(choose 0 if alt:radar < alignTerrainHeight or race else (min(tvCopyMag/2,max(-tvCopyMag/2,terSlope - vsErr/6))), -face:starvector) * (vel / -500 + (choose norm() if alt:radar < alignTerrainHeight else up:vector) * 10 + vxcl(vxcl(up:vector,face:topvector),relVelVec * sideTiltMult )), stTopVector) * angleaxis(pitchoffset, face:starvector).
  368.     } else {
  369.         set st to lookdirup( (vel / -500 + vxcl(vcrs(face:topvector, up:vector), (choose norm() if alt:radar < alignTerrainHeight else up:vector)):normalized * 10 + vxcl(vxcl(up:vector,face:topvector),relVelVec * sideTiltMult )), stTopVector).
  370.     }
  371.    
  372.     set tltpid:minoutput to min(-10,-55 + airspeed / 3).
  373.     //set tltStarpid:minoutput to min(-10,-45 + airspeed / 3).
  374.     //set tltStarpid:maxoutput to max(10,45 - airspeed / 3).
  375.     return vtol.
  376. }
  377.  
  378. // Aft engine(s) trigger
  379. set aftEngs to ship:partstagged("aft").
  380. if aftEngs:length > 0 {
  381.     on round(time:seconds * 13) {
  382.         for eng in aftEngs {
  383.             set eng:thrustlimit to choose 0 if tvCopyMag < 200 or vsErr < -20 or vdot(eng:facing:vector,relVelVec) < -2 else vdot(eng:facing:vector, tvCopy-vel) * 30.
  384.         }
  385.         return vtol.
  386.     }
  387. }
  388. wait 1.1.
  389.  
  390. //===[Camera, GUI, and other]===
  391.  
  392. if not(lights) lights on.
  393. set trackCam to false.
  394. set pitch to 15.
  395. lock co to v(0,0,0).
  396. set cam to addons:camera:flightcamera.
  397. set camDist to bnds:size:mag * 1.0.
  398. when trackCam then {
  399.     set cam:position to cam:position * 0.8 + 0.2 * (co + angleaxis(pitch, face:starvector) * (-vel / 50 + (-relVelVec/10 + face:topvector):normalized * camDist)).
  400.     return vtol.
  401. }
  402.  
  403.  
  404. on time:second {
  405.     set m0:text to "Mode: <color=yellow>" + mode + "</color>".
  406.     set m1:text to "SL: <color=white>" + round(sl,2) + "m/s</color> (" + round(tvCopyMag,1) + ")".
  407.     set m2:text to "HDG: <color=white>" + round(hdg,2) + "</color>".
  408.    
  409.     set m3:text to (choose "<color=#222>Height: </color>" if (vsOverride <> 0 or tAltOverride <> 0) else "Height: ") + "<color=white>" + height + "</color> (priority #3)".
  410.     set m4:text to (choose "<color=#222>tAltOverride: </color>" if (vsOverride <> 0 or tAltOverride = 0) else "tAltOverride: ")+ "<color=white>" + tAltOverride + "</color> (priority #2 if <> 0)".
  411.     set m5:text to (choose "<color=#222>vsOverride: </color>" if (vsOverride = 0)  else "vsOverride: ") + "<color=white>" + vsOverride + "</color> (priority #1 if <> 0)".
  412.    
  413.     set m7:text to "TrackCam: <color=white>" + trackCam + "</color>".
  414.     set m8:text to "alignTerrainHeight: <color=white>" + alignTerrainHeight + "m</color> (match slope if height below this value)".
  415.     set m9:text to "tiltOutwards: <color=white>" + tiltOutwards + "</color>".
  416.     set m10:text to "Localport: <color=white>" + localport + "</color>".
  417.    
  418.     set mIPU:text to "IPU: " + round(core:getfield("kOS average power") / 0.0002).
  419.     return menu:visible.
  420. }
  421. when true then {
  422.     set m6:text to "Alt:radar: " + round(alt:radar,2) + "m".
  423.     set mLast3:text to "vs err: " + round(vsErr,3) + ", cur: " + round(verticalspeed,3).
  424.     //set mLast4:text to "mul: " + round(mul,2) + ", tpid:iterm: " + round(tpid:iterm,4).
  425.    
  426.     if props set mAOA:text to "neutAng: " + round(estNeutral,1) + "  AOA: " + round(tarAOA,1).
  427.     return menu:visible.
  428. }
  429. on vtol menu:dispose.
  430. //clearscreen.
  431. print "VTOL hover script running. See GUI for available variables and functions.".
  432.  
  433. lock steering to st.
  434. if not (props) lock throttle to mul/twr.
  435.  
  436. if defined(places) {
  437.     function showPlaces {
  438.         set placesGUI to gui(180,50).
  439.         for p in places:keys {
  440.             set txt to placesgui:addlabel(p + " (<color=white>" + round(places[p]:distance/1000,1) + "km</color>)").
  441.             set txt:style:fontsize to 9. set txt:style:padding:v to 0.
  442.         }
  443.         placesGUI:addlabel("<color=white>placesGUI:dispose</color> to close").
  444.         Set placesGUI:x to -250.
  445.         set placesGUI:y to 10.
  446.         set placesGUI:style:bg to "".
  447.         placesGUI:show.
  448.     }
  449. }
  450.  
  451. set keepCamSteer to false.
  452. set camDist to ship:bounds:furthestcorner(facing:topvector):mag * 2.
  453. function camSteer {
  454.     set keepCamSteer to true.
  455.     trackcam off.
  456.     set cam:distance to camDist.
  457.     set cam:pitch to 10.
  458.     when true then {
  459.         set hdg to cam:heading.
  460.         set sl to max(0,round(sl + (camDist - cam:distance ) * 10)).
  461.         set cam:distance to camDist.
  462.         return keepCamSteer.
  463.     }
  464. }
  465.  
  466. function land {
  467.     set keepCamSteer to false. resetsteering.
  468.     set sl to 0. set hdg to round(body:geopositionof(velocity:surface:normalized * 100):heading). set height to min(20, height).
  469.     set vsOverride to 0. set tAltOverride to 0.
  470.     when groundspeed < 2 then {
  471.         set sl to 0.
  472.         set height to 0.6.
  473.         on ship:status powerdown().
  474.     }
  475. }
  476.  
  477. powerup().
  478.  
  479.  
Add Comment
Please, Sign In to add comment