Advertisement
sumguytwitches

VTOL Experimental Clone for Props

Oct 27th, 2020 (edited)
553
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //VTOL hover script with side translation - Ozin
  2. //hacked and likely broken - sumguy
  3. // !runscript N8eMd50c
  4. switch to 0.
  5. clearvecdraws().
  6. HUDTEXT("Running script: VTOL hover for props",20,2,22,white,false).
  7.  
  8. //===[Setup shitload of vars]=== A lot of these get updated in triggers and functions but need to be delcared here first with initial values.
  9.  
  10.  
  11. set vtol to true.
  12. set steeringmanager:rollcontrolanglerange to 180.
  13. set steeringmanager:rollpid:kp to 0.4.
  14. set steeringmanager:rollpid:ki to 0.04.
  15. set steeringmanager:rollpid:kd to 0.25.
  16. set steeringmanager:yawpid:kd to 0.15.
  17. set bnds to ship:bounds.
  18. set st to  lookdirup(up:vector, facing:topvector).
  19. lock steering to st.
  20. lock hdg to 90.
  21. lock sl to 0.
  22. set relVelVec to v(0,0,0).
  23. lock tAltOverride to 0.
  24. set terSlope to 0.
  25.  
  26. set grav to 9.
  27. set acc to 10.
  28. lock height to 20.
  29. set hvel to v(0,0,0).
  30. set vel to velocity:surface.
  31. lock terAlt to max(0,ship:geoposition:terrainheight).
  32. lock talt to choose tAltOverride if tAltOverride <> 0 else height + terAlt.
  33. set altErr to altitude - talt.
  34. set tiltOutwards to 0.
  35. lock vsOverride to 0.
  36. set vsMin to -100.
  37. set vsMax to 200.
  38. set vs to 0.
  39. set vsErr to 0.
  40. set stTopVector to facing:topvector.
  41. set terI to 1.
  42. set terSteps to 15.
  43. set terStepDist to 0.25.
  44. set terSlope2 to 0.
  45. set terJ to 0.
  46. set mul to 1.
  47. lock tv to heading(hdg,0):vector * sl.
  48. set tvCopy to tv.
  49.  
  50. lock deploy to max(3,airspeed^0.7).
  51. lock rpmlimit to max(0,(-2*verticalspeed - altitude + talt -altErr*0.6)*4.6*2).
  52. set blades to ship:partsdubbedpattern("blade").
  53.  
  54. set rotors to ship:partsdubbedpattern("rotor").
  55.  
  56. for rotor in rotors rotor:getmodulebyindex(1):setfield("torque limit(%)",100).
  57.  
  58. if ship:partsnamedpattern("grap"):length > 0 {
  59.     set localport to ship:partsnamedpattern("grap")[0].
  60. } else if ship:dockingports:length > 0 {
  61.     set localport to ship:dockingports[0].
  62. } else {
  63.     set localport to false.
  64. }
  65. set mode to "Heading".
  66. set tgt to false.
  67. set alignTerrainHeight to 10.
  68.  
  69.  
  70. //===[Functions]===
  71.  
  72. function norm {
  73.     parameter p0 is v(0,0,0).
  74.     set u to (p0-body:position):normalized.
  75.     set p1 to vxcl(u,facing:vector):normalized * (bnds:size:mag + 5).
  76.     set g2 to body:geopositionof(angleaxis(120, u) * p1 + p0). set p2 to choose g2:position if g2:terrainheight > 0 else g2:altitudeposition(0).
  77.     set g3 to body:geopositionof(angleaxis(-120, u) * p1 + p0). set p3 to choose g3:position if g3:terrainheight > 0 else g3:altitudeposition(0).
  78.     set g1 to body:geopositionof(p1 + p0). set p1 to choose g1:position if g1:terrainheight > 0 else g1:altitudeposition(0).
  79.     return vcrs(p1-p2,p1-p3):normalized.
  80. }
  81. function getSlope {
  82.     parameter pos, vec.
  83.     local g1 is body:geopositionof(pos). local p1 is choose g1:position if g1:terrainheight > 0 else g1:altitudeposition(0).
  84.     local g2 is body:geopositionof(pos+vec). local p2 is choose g2:position if g2:terrainheight > 0 else g2:altitudeposition(0).
  85.     return 90 - vang(up:vector, p2-p1).
  86. }
  87. function showVD { toggle terDisplay. set vdTer to vecdraw(v(0,0,0), up:vector * 1, red, "", 1, true, 0.9, false). set vdSlope to vecdraw(v(0,0,0), up:vector * 1, yellow, "", 1, true, 0.4, true). set vdVel to vecdraw(v(0,0,0), up:vector * 1, blue, "", 1, true, 0.4, true). }
  88. set terDisplay to false.
  89. function terDisplayFunc {
  90.     set vdTer:start to pi.
  91.     set vdTer:vec to (angleaxis(terSlope, vcrs(hvel, up:vector)) * up:vector) * height.
  92.     set vdTer:width to 1 + (pi:mag^0.9) / 80.
  93.    
  94.     set vdSlope:vec to angleaxis(terSlope, vcrs(tvCopy, up:vector)) * tvCopy / 5.
  95.     set vdVel:vec to vel / 5.
  96. }
  97. function tiltStar {
  98.     parameter tlt is 0.
  99.     if vsErr < -1 set tlt to tlt + tlt * max(-1, vsErr / 15).
  100.     set tlt to tlt + vang(up:vector,  facing:starvector) - 90.  
  101.     set rollError to steeringmanager:rollpid:output.
  102.     for hinge in allHinges hinge["s"]:setfield("target angle", tlt * hinge["right"] + tiltOutwards + min(15, max(-15,rollError * 40 * hinge["front"] * hinge["right"])) ).
  103. }
  104. function tilt {
  105.     parameter tlt is 0. if vsErr < -1  and (vdot(hvel:normalized, relVelVec) > -2 or vdot(tvCopy, hvel) < 0) set tlt to tlt + tlt * max(-1, vsErr / 20).
  106.     set tlt to tlt + vang(up:vector,  facing:topvector) - 90.
  107.     for s in servos s:setfield("target angle", tlt).
  108. }
  109. function goToTarget {
  110.     if localport:istype("part") {
  111.         lock tv to choose (vxcl(up:vector,target:position - localport:position):normalized * min(sl,(vxcl(up:vector,target:position - localport:position):mag/3)^0.70) + (choose target:velocity:surface if target:loaded else v(0,0,0))) if hastarget else v(0,0,0).
  112.        
  113.     } else {
  114.         lock tv to choose (vxcl(up:vector,target:position):normalized * min(sl,(vxcl(up:vector,target:position):mag/3)^0.70) + (choose target:velocity:surface if target:loaded else v(0,0,0))) if hastarget else v(0,0,0).
  115.     }
  116.     set mode to "Target".
  117.     if sl < 1 { set sl to 5. HUDTEXT("SL (speedlimit) is low, setting SL to 5..",16,2,20,yellow,false). }
  118. }
  119. function goToPosition {
  120.     parameter pos.
  121.     if pos:typename = "Vector" set pos to body:geopositionof(pos).
  122.     set tgt to pos.
  123.     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)).
  124.     set mode to "GeoPos".
  125.     if sl < 1 { set sl to 5. HUDTEXT("SL (speedlimit) is low, setting SL to 5..",16,2,20,yellow,false). }
  126. }
  127. function resetSteering { lock tv to heading(hdg,0):vector * sl. lock steering to st. set mode to "Heading". }
  128.  
  129.  
  130. //===[engine & servos setup]===
  131.  
  132. set allServos to ship:modulesnamed("ModuleRoboticRotationServo").
  133. set servos to list().
  134. set yawServos to list().
  135. for s in allServos {
  136.     if s:part:tag <> "yaw" {
  137.         s:setfield("damping", 80). s:setfield("traverse rate", 80). servos:add(s).
  138.     } else {
  139.         yawServos:add(s).
  140.     }
  141. }
  142. set allHinges to list().
  143. for m in ship:modulesnamed("ModuleRoboticServoHinge") {
  144.     m:setfield("damping", 80). m:setfield("traverse rate", 80).
  145.     local pPos is m:part:position.
  146.     local l is lexicon("right", choose 1 if vdot(facing:starvector, pPos) > 0 else -1, "front", choose 1 if vdot(facing:topvector, pPos) < 0 else -1, "s", m).
  147.  
  148.     allHinges:add(l).
  149. }
  150. set twoaxistilt to (allHinges:length > 1).
  151. if twoaxistilt HUDTEXT("2-axis engine tilting enabled. Toggle 'twoaxistilt' to disable",20,2,22,yellow,false).
  152. set sideTiltMult to choose 0.50 if twoaxistilt else 1.
  153. set jets to false.
  154.  
  155. //===[PID controllers]===
  156. if jets {
  157.     set tpid to pidloop(8,0.2, 9, -0.5, 4).
  158. } else {
  159.     set tpid to pidloop(5,0.2, 0.5, -1, 4).
  160. }
  161. set vsPID to pidloop(1,1,1,-50,100).
  162. set tltpid to pidloop(20, 2, 2, -55, 60).
  163. set tltStarpid to pidloop(20, 2, 2, -35, 35).
  164.  
  165.  
  166. //===[TRIGGER WARNING!]===
  167. //5hz trigger
  168. on round(time:seconds * 5) {
  169.    
  170.    
  171.     return vtol.
  172. }
  173. //fast (50hz) trigger
  174. when true then {
  175.     set vel to velocity:surface.
  176.     set hvel to vxcl(up:vector,vel).
  177.     set tvCopy to tv.
  178.     set tvCopyMag to tvCopy:mag.
  179.     set altErr to altitude - talt.
  180.    
  181.     //[Terrain detection and minimum climb angle]
  182.     set gi to body:geopositionof((hvel * (1.5 - terI/terSteps) + tvCopy * terI/terSteps):normalized * (groundspeed + (tvCopyMag + groundspeed)/2 * (terI^1.4) * terStepDist)). set pi to choose gi:position if gi:terrainheight > 0 else gi:altitudeposition(0).
  183.     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))).
  184.     if tempSlope > terSlope {
  185.         set terSlope to tempSlope.
  186.         set terJ to 0.
  187.     } else {
  188.         set terJ to terJ + 1.
  189.         set terSlope2 to max(tempSlope, terSlope2 * 0.999 + 0.001 * tempSlope).
  190.         if terJ > terSteps * 3 + 30 { set terJ to 0. set terSlope to terSlope2. set terSlope2 to max(-30, terSlope2 - 25).  }
  191.     }
  192.     if terDisplay terDisplayFunc().
  193.     set terI to terI + terStepDist.
  194.     if terI > terSteps {
  195.         set terI to terStepDist.
  196.         //if terSlope > 0 set terSlope to max(terSlope, getSlope(vel:normalized * (sl * terSteps), vel:normalized * (sl * 2))).
  197.     }
  198.    
  199.     //[Target vertical speed & throttle]
  200.     set slopeVS to choose 0 if tAltOverride else (tan(terSlope) * (groundspeed + (choose 0 if altErr < 0 else max(0,20 - groundspeed^1.5)))).
  201.     set vs to choose vsOverride if vsOverride <> 0 else max(max(vsMin,slopeVS)  ,min(vsMax,       choose (-1 * (1 * 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))         )).
  202.     set vsErr to verticalspeed - vs.
  203.    
  204.     set relVelVec to vxcl(up:vector, min(1,  max(0, 1 + (2 + vsErr) / 20)) * tvCopy - vel) / 4.
  205.     set relVelVec:mag to min(5,relVelVec:mag).
  206.    
  207.     for s in yawServos s:setfield("target angle", steeringmanager:yawpid:output * 20).
  208.  
  209.  
  210.     For b in blades b:getmodule("ModuleControlSurface"):setfield("deploy angle", deploy).
  211.     for rotor in rotors rotor:getmodulebyindex(1):setfield("rpm limit", rpmlimit).
  212.  
  213.     return vtol.
  214. }
  215.  
  216. //12hz trigger - steering and engine tilt
  217. on round(time:seconds * 12) {
  218.     tilt(tltpid:update(time:seconds, vdot(facing:topvector, relVelVec))).
  219.    
  220.     set stTopVector to choose tvCopy * -1 if tvCopyMag > 2 else (choose -target:facing:topvector if hastarget else facing:topvector).
  221.     if twoaxistilt {
  222.         tiltStar(tltStarpid:update(time:seconds, vdot(facing:starvector, relVelVec))).
  223.         set st to lookdirup(angleaxis(choose 0 if alt:radar < alignTerrainHeight else (min(tvCopyMag/2,max(-tvCopyMag/2,terSlope - vsErr/6))), -facing:starvector) * (vel / -500 + (choose norm() if alt:radar < alignTerrainHeight else up:vector) * 10 + vxcl(vxcl(up:vector,facing:topvector),relVelVec * sideTiltMult )), stTopVector).
  224.     } else {
  225.         set st to lookdirup(angleaxis(min(tvCopyMag/2,max(-tvCopyMag/2,terSlope - vsErr/6)), -facing:starvector) * (vel / -500 + up:vector * 10 + vxcl(vxcl(up:vector,facing:topvector),relVelVec * sideTiltMult )), stTopVector).
  226.     }
  227.     return vtol.
  228. }
  229.  
  230.  
  231. //===[Camera, GUI, and other]===
  232. if vang(up:vector,facing:vector) > 60 toggle ag2.
  233.  
  234. if not(lights) lights on.
  235. set trackCam to true.
  236. set pitch to 12.
  237. lock co to v(0,0,0).
  238. set cam to addons:camera:flightcamera.
  239. when trackCam then {
  240.     set cam:position to cam:position * 0.9 + 0.1 * (co + angleaxis(pitch, facing:starvector) * (-vel / 50 + (-relVelVec/10 + facing:topvector):normalized * bnds:size:mag * 1.2)).
  241.     return vtol.
  242. }
  243.  
  244. clearguis().
  245. set menu to gui(200, 30). Set menu:x to -30. set menu:y to 300. menu:show.
  246. menu:addlabel("<b><color=yellow>VTOL 2-axis script</color></b>").
  247. set m0 to menu:addlabel("Mode:").
  248. set m1 to menu:addlabel("SL:").
  249. set m2 to menu:addlabel("HDG:").
  250. set m3 to menu:addlabel("Height:").
  251. set m4 to menu:addlabel("tAltOverride:").
  252. set m5 to menu:addlabel("vsOverride:").
  253. set m6 to menu:addlabel("alt:radar:").
  254. set m7 to menu:addlabel("trackCam:").
  255. set m8 to menu:addlabel("alignTerrainHeight:").
  256. set m9 to menu:addlabel("tiltOutwards:").
  257. set m10 to menu:addlabel("Localport:").
  258. set mLast to menu:addlabel("Functions: <color=white>goToTarget(), goToPosition(<geopos or position>), resetSteering()</color>").
  259. set mLast2 to menu:addlabel("Additional vars: <color=white>vsMin, vsMax, sideTiltMult</color>").
  260. set mLast3 to menu:addlabel("").
  261. set mLast4 to menu:addlabel("").
  262.  
  263. for txt in menu:widgets { set txt:style:fontsize to 10. set txt:style:padding:v to 1. }
  264. set m3:style:margin:top to 15.
  265. set m5:style:margin:bottom to 15.
  266. on time:second {
  267.     set m0:text to "Mode: <color=yellow>" + mode + "</color>".
  268.     set m1:text to "SL: <color=white>" + round(sl,2) + "m/s</color> (" + round(tvCopyMag,1) + ")".
  269.     set m2:text to "HDG: <color=white>" + round(hdg,2) + "</color>".
  270.    
  271.     set m3:text to (choose "<color=#222>Height: </color>" if vsOverride <> 0 or tAltOverride <> 0 else "Height: ") + "<color=white>" + height + "</color> (priority #3)".
  272.     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)".
  273.     set m5:text to (choose "<color=#222>vsOverride: </color>" if vsOverride = 0  else "vsOverride: ") + "<color=white>" + vsOverride + "</color> (priority #1 if <> 0)".
  274.    
  275.     set m7:text to "TrackCam: <color=white>" + trackCam + "</color>".
  276.     set m8:text to "alignTerrainHeight: <color=white>" + alignTerrainHeight + "m</color> (match slope if height below this value)".
  277.     set m9:text to "tiltOutwards: <color=white>" + tiltOutwards + "</color>".
  278.     set m10:text to "Localport: <color=white>" + localport + "</color>".
  279.     return menu:visible.
  280. }
  281. when true then {
  282.     set m6:text to "Alt:radar: " + round(alt:radar,2) + "m".
  283.     set mLast3:text to "vs err: " + round(vsErr,3) + ", cur: " + round(verticalspeed,3).
  284.     set mLast4:text to "mul: " + round(mul,2) + ", tpid:iterm: " + round(tpid:iterm,4).
  285.     return menu:visible.
  286. }
  287. on vtol menu:dispose.
  288. clearscreen.
  289. print "VTOL hover script running. See GUI for available variables and functions.".
  290.  
  291. set places to readjson("kerbin.json").
  292. function gotoplace { parameter placename is "helipad". set dest to places[placename]. lock taltoverride to max(dest:terrainheight + 15, ship:geoposition:terrainheight + 15). gotoposition(dest). }.
  293.  
  294.  
  295.  
  296.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement