Add aircraft automation code, including flap control and stable autopilot flight.
This commit is contained in:
parent
a99912e3ae
commit
376629354b
10
boot/aircraft.ks
Normal file
10
boot/aircraft.ks
Normal file
|
@ -0,0 +1,10 @@
|
|||
RunOncePath("0:/lib/boot").
|
||||
|
||||
parameter debug is false.
|
||||
|
||||
Bootstrap(
|
||||
"/boot/aircraft",
|
||||
"/prog/aircraft",
|
||||
List(), // no additional program files
|
||||
debug
|
||||
).
|
|
@ -78,7 +78,9 @@ function addLibs {
|
|||
if line:Contains("RunOncePath") {
|
||||
local start is line:Find(char(34)).
|
||||
local end is line:FindLast(char(34)).
|
||||
libs:Add(line:Substring(start + 1, end - start - 1)).
|
||||
local libFile is line:Substring(start + 1, end - start - 1).
|
||||
libs:Add(libFile).
|
||||
addLibs(libs, libFile).
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
32
lib/flap_control.ks
Normal file
32
lib/flap_control.ks
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
function SetFlapAngle {
|
||||
parameter angle.
|
||||
|
||||
local flaps is getFlaps().
|
||||
if flaps:LENGTH = 0 { return. }
|
||||
for flap in flaps {
|
||||
flap:GetModule("ModuleControlSurface"):SetField("deploy angle", angle).
|
||||
print("DEBUG: Set flap angle to " + angle).
|
||||
}
|
||||
}
|
||||
|
||||
function SetFlaps {
|
||||
parameter extend is true.
|
||||
local flaps is getFlaps().
|
||||
if flaps:LENGTH = 0 { return. }
|
||||
for flap in flaps {
|
||||
flap:GetModule("ModuleControlSurface"):SetField("deploy", extend).
|
||||
print("DEBUG: Set flap deployment to " + extend).
|
||||
}
|
||||
}
|
||||
|
||||
function getFlaps {
|
||||
local flaps is SHIP:PartsTagged("flap").
|
||||
for flap in flaps {
|
||||
if flap:MODULES:Find("ModuleControlSurface") = -1 {
|
||||
print "WARNING: Flap is not a control surface. Aborting operation.".
|
||||
return List().
|
||||
}
|
||||
}
|
||||
return flaps.
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
RunOncePath("lib/throttle").
|
||||
RunOncePath("lib/navigation").
|
||||
RunOncePath("lib/navball").
|
||||
|
||||
// Calculate the direction to lock during ascent.
|
||||
function getClampedDir {
|
||||
|
@ -8,18 +9,12 @@ function getClampedDir {
|
|||
// face just beneath prograde, but hold a solid eastern heading and don't
|
||||
// rotate the ship
|
||||
local newHeading is lookdirup(SHIP:SRFPROGRADE:FOREVECTOR, heading(90, 0, 270):TOPVECTOR).
|
||||
if getPitch(newHeading:FOREVECTOR) < minPitch {
|
||||
if GetPitch(newHeading:FOREVECTOR) < minPitch {
|
||||
set newHeading to heading(90, minPitch, 270).
|
||||
}
|
||||
return newHeading.
|
||||
}
|
||||
|
||||
// Returns the navball pitch of a given vector.
|
||||
function getPitch {
|
||||
parameter v is SHIP:FACING:FOREVECTOR.
|
||||
return 90 - vectorangle(SHIP:UP:FOREVECTOR, v).
|
||||
}
|
||||
|
||||
// Given a target (end) pitch, a target duration, and a start time,
|
||||
// returns the correct current heading.
|
||||
function pitchProgram {
|
||||
|
|
9
lib/navball.ks
Normal file
9
lib/navball.ks
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Returns the navball pitch of a given vector.
|
||||
function GetPitch {
|
||||
parameter v is SHIP:FACING:FOREVECTOR.
|
||||
return 90 - vectorangle(SHIP:UP:FOREVECTOR, v).
|
||||
}
|
||||
|
||||
function GetHeading {
|
||||
return mod(360 - LatLng(90,0):BEARING, 360).
|
||||
}
|
34
lib/stabilize_aircraft.ks
Normal file
34
lib/stabilize_aircraft.ks
Normal file
|
@ -0,0 +1,34 @@
|
|||
RunOncePath("lib/navball").
|
||||
|
||||
// Fly level toward the current compass heading.
|
||||
function HoldHorizon {
|
||||
parameter Kp is 0.02.
|
||||
parameter Ki is 0.04.
|
||||
parameter Kd is 0.0066.
|
||||
|
||||
SAS off.
|
||||
|
||||
local pitchPID is PidLoop(Kp, Ki, Kd).
|
||||
|
||||
// local rollPID is PidLoop(Kp, Ki, Kd).
|
||||
// lock rollVec to VXCL(SHIP:FACING:FOREVECTOR, SHIP:FACING:TOPVECTOR).
|
||||
// lock upVec to VXCL(SHIP:FACING:FOREVECTOR, SHIP:UP:FOREVECTOR).
|
||||
|
||||
local h is GetHeading().
|
||||
|
||||
local p is 0.
|
||||
lock p to pitchPID:Update(TIME:SECONDS, SHIP:VERTICALSPEED).
|
||||
lock STEERING to Heading(h, p, 0).
|
||||
|
||||
// until done {
|
||||
// set SHIP:CONTROL:PITCH to pitchPID:Update(TIME:SECONDS, GetPitch(SHIP:SRFPROGRADE:FOREVECTOR)).
|
||||
// set SHIP:CONTROL:ROLL to rollPID:Update(TIME:SECONDS, VAng(rollVec, upVec)).
|
||||
// }
|
||||
|
||||
wait until done.
|
||||
set done to false.
|
||||
unlock STEERING.
|
||||
SAS on.
|
||||
// set SHIP:CONTROL:PITCH to 0.
|
||||
// set SHIP:CONTROL:ROLL to 0.
|
||||
}
|
22
lib/ui.ks
22
lib/ui.ks
|
@ -53,3 +53,25 @@ function MakeMenu {
|
|||
set top:AddButton(execLabel):onClick to callback:Bind(optionList).
|
||||
}
|
||||
}
|
||||
|
||||
function AddStockButtons {
|
||||
parameter row.
|
||||
parameter bootname.
|
||||
|
||||
local btn is row:AddButton("Term").
|
||||
set btn:TOGGLE to true.
|
||||
set btn:ONTOGGLE to {
|
||||
parameter d.
|
||||
|
||||
if d {
|
||||
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
|
||||
} else {
|
||||
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
|
||||
}
|
||||
}.
|
||||
|
||||
MakeButton(row, "Update", {
|
||||
switch to 0.
|
||||
run reinstall(bootname).
|
||||
}).
|
||||
}
|
||||
|
|
91
prog/aircraft.ks
Normal file
91
prog/aircraft.ks
Normal file
|
@ -0,0 +1,91 @@
|
|||
|
||||
RunOncePath("lib/flap_control").
|
||||
RunOncePath("lib/stabilize_aircraft").
|
||||
RunOncePath("lib/ui").
|
||||
|
||||
clearguis().
|
||||
|
||||
global done is false.
|
||||
on AG9 {
|
||||
set done to true.
|
||||
return true.
|
||||
}
|
||||
|
||||
function landingMode {
|
||||
print "Setting flaps to landing mode.".
|
||||
SetFlapAngle(20).
|
||||
when SHIP:VELOCITY:SURFACE:MAG < 0.1 then {
|
||||
takeoffMode().
|
||||
}
|
||||
}
|
||||
|
||||
function takeoffMode {
|
||||
print "Setting flaps to takeoff mode.".
|
||||
SetFlapAngle(10).
|
||||
on GEAR {
|
||||
if GEAR = true {
|
||||
return true.
|
||||
}
|
||||
landingMode().
|
||||
}
|
||||
}
|
||||
|
||||
if SHIP:STATUS = "LANDED" or SHIP:STATUS = "PRELAUNCH" {
|
||||
takeoffMode().
|
||||
} else {
|
||||
landingMode().
|
||||
}
|
||||
|
||||
// Top-level elements.
|
||||
local iface is gui(250, 300).
|
||||
set iface:X to 200.
|
||||
set iface:Y to 700.
|
||||
local top is iface:AddVLayout().
|
||||
local rows is List(MakeRow(top), MakeRow(top)).
|
||||
local stk is iface:AddStack().
|
||||
|
||||
AddStockButtons(rows[0], "aircraft").
|
||||
|
||||
// rows[0]:AddLabel("FLAPS").
|
||||
// // Todo: make angles configurable...
|
||||
// set rows[1]:AddButton("Takeoff"):onClick to {
|
||||
// SetFlapAngle(10).
|
||||
// }.
|
||||
|
||||
// set rows[1]:AddButton("Land"):onClick to {
|
||||
// SetFlapAngle(20).
|
||||
// }.
|
||||
|
||||
// set rows[2]:AddButton("Extend"):onClick to {
|
||||
// SetFlaps(true).
|
||||
// }.
|
||||
|
||||
// set rows[2]:AddButton("Retract"):onClick to {
|
||||
// SetFlaps(true).
|
||||
// }.
|
||||
|
||||
// rows[3]:AddLabel("AUTO").
|
||||
|
||||
MakeMenu(
|
||||
stk,
|
||||
MakeButton(rows[1], "Level"),
|
||||
List(
|
||||
List("Kp", "SCALAR", "0.02"),
|
||||
List("Ki", "SCALAR", "0.01"),
|
||||
List("Kd", "SCALAR", "1")
|
||||
),
|
||||
"Execute",
|
||||
{
|
||||
parameter options.
|
||||
HoldHorizon(
|
||||
options["Kp"]:TEXT:ToNumber(),
|
||||
options["Ki"]:TEXT:ToNumber(),
|
||||
options["Kd"]:TEXT:ToNumber()
|
||||
).
|
||||
}
|
||||
).
|
||||
|
||||
|
||||
iface:show().
|
||||
|
||||
wait until false.
|
|
@ -25,17 +25,7 @@ local rows is list(MakeRow(top), MakeRow(top), MakeRow(top)).
|
|||
local stk is iface:AddStack().
|
||||
|
||||
// Buttons and menus.
|
||||
local btn is rows[0]:AddButton("TERM").
|
||||
set btn:TOGGLE to true.
|
||||
set btn:ONTOGGLE to {
|
||||
parameter d.
|
||||
|
||||
if d {
|
||||
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Open Terminal").
|
||||
} else {
|
||||
CORE:PART:GETMODULE("kOSProcessor"):DOEVENT("Close Terminal").
|
||||
}
|
||||
}.
|
||||
AddStockButtons(rows[0], "rocket").
|
||||
|
||||
MakeMenu(
|
||||
stk,
|
||||
|
|
Loading…
Reference in New Issue
Block a user