Skip to content

Instantly share code, notes, and snippets.

@danielboro
Forked from KK4TEE/rover.ks
Last active March 17, 2019 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielboro/38ae24f97d209d8d853f78bf1fbad641 to your computer and use it in GitHub Desktop.
Save danielboro/38ae24f97d209d8d853f78bf1fbad641 to your computer and use it in GitHub Desktop.
Cruise control and autopilot for rovers in Kerbal Space Program using kOS
// rover.ks
// Written by KK4TEE modifaid by danielboro
//https://gist.github.com/KK4TEE/5966971602973c24107f
// License: GPLv3
print ship:body:name.
print status.
set speedlimit to 24. //All speeds are in m/s
lock turnlimit to min(1, 1.5 / max(0.1,GROUNDSPEED)).
set looptime to 0.01.
set loopEndTime to TIME:SECONDS.
set eWheelThrottle to 0.
set iWheelThrottle to 0.
set wtVAL to 0.
set kTurn to 0.
set targetspeed to 0. //Cruise control starting speed
set targetHeading to 90.
set NORTHPOLE to latlng( 90, 0).
set mindn to "".
//when ship:ELECTRICCHARGE<1 then {brakes on. reboot.}.
if EXISTS("scilib.ks") run scilib.
else if HOMECONNECTION:isconnected and EXISTS("0:/scilib.ks") if copypath("0:/scilib.ks",scilib.ks) run scilib.
else run "0:/scilib".
if EXISTS("ondimandfclib.ks") run ondimandfclib(20,20).
else if HOMECONNECTION:isconnected and EXISTS("0:/ondimandfclib.ks") if copypath("0:/ondimandfclib.ks",ondimandfclib.ks) run ondimandfclib(20,20).
else run "0:/ondimandfclib.ks"(20,20).
if status<>"LANDED" wait until ship:body:name<>"kerbin" and status="LANDED".
if NOT (defined BIOME) set get_biome to {return false.}.
clearscreen.
sas off. rcs off. AG1 off. lights on.
lock throttle to 0.
set runmode to false.
on ag10 {set runmode to true.}
on ag9 if not ag9{set ag1 to false. brakes on. set mindn to "".}
SET spot TO ALLWAYPOINTS().
for t in spot { if t:POSITION:mag<10000 AG9 ON.}
function groundSlope {
parameter center is ship:position.
local east is vectorCrossProduct(north:vector, up:vector).
local a is body:geopositionOf(center + 5 * north:vector).
local b is body:geopositionOf(center - 3 * north:vector + 4 * east).
local c is body:geopositionOf(center - 3 * north:vector - 4 * east).
local a_vec is a:altitudePosition(a:terrainHeight).
local b_vec is b:altitudePosition(b:terrainHeight).
local c_vec is c:altitudePosition(c:terrainHeight).
return vectorCrossProduct(c_vec - a_vec, b_vec - a_vec):normalized.
}
function ede{
set result to -1.
if defined oldECL {set result to (oldECL[0]-SHIP:ELECTRICCHARGE)/(oldECL[1]-TIME:SECONDS).}.
set oldECL to list(SHIP:ELECTRICCHARGE,TIME:SECONDS).
return result.
}. lock tede to ede().
until runmode {
if ship:ELECTRICCHARGE<20 {brakes on. set SHIP:CONTROL:WHEELTHROTTLE to 0. PANELS ON. print "waiting until has power" at(10,0). wait until KUNIVERSE:CANQUICKSAVE. set warp to 2. wait until ship:ELECTRICCHARGE>600 or tede=0 or warp=0. set warp to 0. KUNIVERSE:QUICKSAVE(). brakes off. PANELS OFF. clearscreen.}.
if defined fc and fc:length>0 FCround().
if NOT SAS lock steering to LOOKDIRUP(VECTOREXCLUDE(groundSlope,facing:vector),groundSlope). else unlock steering.
if northPole:bearing <= 0 {
set cHeading to ABS(northPole:bearing).
}
else {
set cHeading to (180 - northPole:bearing) + 180.
}
set targetspeed to targetspeed + 0.05 * SHIP:CONTROL:PILOTWHEELTHROTTLE.
set targetspeed to max(-1, min( speedlimit, targetspeed)).
if targetspeed > 0 { //If we should be going forward
// brakes off.
PANELS OFF.
set eWheelThrottle to targetspeed - GROUNDSPEED.
set iWheelThrottle to min( 1, max( -1, iWheelThrottle+(looptime * eWheelThrottle))).
set wtVAL to eWheelThrottle + iWheelThrottle.//PI controler
if GROUNDSPEED < 5 {set wtVAL to min( 1, max( -0.2, wtVAL)).}
}
else if targetspeed < 0 { //Else if we're going backwards
set wtVAL to SHIP:CONTROL:PILOTWHEELTHROTTLE.
set targetspeed to 0. //Manual reverse throttle
set iWheelThrottle to 0.
}
else { // If value is out of range or zero, stop.
set wtVAL to 0.
brakes on. PANELS ON.
}
if brakes = 1 { //Disable cruise control if the brakes are turned on.
set targetspeed to 0.
set AG8 to false.
PANELS ON.
}
if AG1 { //Activate autopilot if Actiong group 1 is on
set errorSteering to (targetheading - cHeading).
if errorSteering > 180 { //Make sure the headings make sense
set errorSteering to errorSteering - 360.
}
else if errorSteering < -180 {
set errorSteering to errorSteering + 360.
}
set desiredSteering to -errorSteering / 10.
set kturn to min( 1, max( -1, desiredSteering)) * turnlimit.
}
else {
set kturn to turnlimit * SHIP:CONTROL:PILOTWHEELSTEER.
}
if AG2 { // Set heading to the current heading
set targetHeading to cHeading.
set AG2 to FALSE. //Reset the AG after we read it
set AG9 to FALSE.
}
else if AG3 { // Decrease the heading
set targetHeading to targetHeading - 0.5.
set AG3 to FALSE.
set AG9 to FALSE.
}
else if AG4 { // Increase the heading
set targetHeading to targetHeading + 0.5.
set AG4 to FALSE.
set AG9 to FALSE.
}
else if AG5 {
set targetHeading to targetHeading - 0.5.
set AG9 to FALSE.
set AG6 to FALSE.
//Prevent increase if we are decreasing
}
else if AG6 {
set targetHeading to targetHeading + 0.5.
set AG9 to FALSE.
set AG5 to FALSE.
//Prevent decrease if we are increasing
}
if AG7 {
if defined BIOME and is_biome_new() {
get_all_science().
set waituntiltime to TIME:SECONDS+5.
when TIME:SECONDS>waituntiltime then transmit_all_science().
when TIME:SECONDS>waituntiltime+20 then collect_all_science().
when TIME:SECONDS>waituntiltime+25 then clear_all_science().
}
}
if AG8 {
set targetspeed to abs(max(5,speedlimit*5/max(5,vang(groundSlope(srfprograde:vector*10), up:vector)))).
if abs(errorSteering)>5 set targetspeed to 0.5*targetspeed.
}
if AG9 {
if mindn="" {
SET spot TO ALLWAYPOINTS().
set mind to 1000000.
for t in spot {
if t:POSITION:mag<mind and t:POSITION:mag>150 and (t:GROUNDED or t:NEARSURFACE){
set mind to t:POSITION:mag.
set mindn to t:name.
}
}
if mindn<>"" {
SET wp TO WAYPOINT(mindn).
set AG1 to true. set AG6 to FALSE. set AG5 to FALSE. set AG8 to true.
brakes off. sas off. PANELS OFF.
set targetspeed to 5.
}
}
if mindn<>"" {
lock targetHeading to wp:GEOPOSITION:Heading.
if wp:POSITION:MAG<100*targetspeed/5 {
brakes on. PANELS ON.set SHIP:CONTROL:WHEELTHROTTLE to 0.
if defined BIOME {
get_all_science().
wait until KUNIVERSE:CANQUICKSAVE.
KUNIVERSE:QUICKSAVE().
collect_all_science().
clear_all_science().
} else set AG9 to false.
set mindn to "".
}
}
}
if targetHeading > 360 {
set targetHeading to targetHeading - 360.
}
else if targetHeading < 0 {
set targetHeading to targetHeading + 360.
}
set SHIP:CONTROL:WHEELTHROTTLE to WTVAL.
set SHIP:CONTROL:WHEELSTEER to kTurn.
print "version: 1.18 " + " " at (2, 2).
print "Target Speed: " + round( targetspeed, 1) + " " at (2, 3).
print "Speed Limit: " + round( speedlimit, 1) + " " at (2, 4).
print "Surface Speed: " + round( GROUNDSPEED, 1) + " " at (2, 5).
print "Pilot Throttle: " + round( SHIP:CONTROL:PILOTWHEELTHROTTLE, 2)+ " " at (2, 7).
print "Kommanded tVAL: " + round( wtVAL, 2) + " " at (2, 8).
print "Pilot Turn: " + round( SHIP:CONTROL:PILOTWHEELSTEER, 2)+ " " at (2, 9).
print "Kommanded Turn: " + round( kTurn, 2) + " " at (2, 10).
print "Target Heading: " + round( targetheading, 2) + " " at (2, 12).
print "CurrentHeading: " + round( cheading, 2) + " " at (2, 13).
print "Cruise Control: " + AG1 + " " at (2, 14).
print "auto speed: " + AG8 + " " at (25, 14).
print "auto sciance: " + AG7 + " " at (43, 14).
print "E: " + round(eWheelThrottle,2)+ " " at ( 2, 16).
print "I: " + round(iWheelThrottle,2) + " " at (10,16).
print "going to WP: " + mindn + " " at (2,17).
set looptime to TIME:SECONDS - loopEndTime.
set loopEndTime to TIME:SECONDS.
}
set SHIP:CONTROL:WHEELTHROTTLE to 0.
set SHIP:CONTROL:WHEELSTEER to 0.
unlock steering.
if KUNIVERSE:CANQUICKSAVE KUNIVERSE:QUICKSAVE().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment