SpinkAkron

[1.6.X] Spink's kOS Script Pack v1.0.1 (11 Mar 2019)

Recommended Posts

IJwwQ4k.png

Thanks to Kevin and all the others I learned from!

First of all, I'd like to thank Kevin Gisi for his great YouTube series on using kOS.  I learned a lot from him and used his code as the starting point for mine. Go watch his videos. I've also picked up snippets from the kOS threads on this forum and reddit.  I never planned to release this so unfortunately I didn't make the effort to keep track of what bits I got from where.  So, here's a big thank you to all the folks sharing their code and expertise on the various forums.

What it is

This is a library of scripts I've been working on for a couple years of playing unmanned careers.  I thought making it available might help players who'd like to try kOS but don't know where to start.  I tried to keep the code simple and easy to follow.  It is composed of a boot script, a library of functions, and a mission folder.  The library functions are the building blocks used to build the missions.  They cover launches, changing orbits, intercepts, docking, landers, and science gathering.  I'm sure there are better, more exact and efficient ways to do it, but I went with a "good enough" mindset. If it got the job done reasonably well most of the time, it was good enough for me. By releasing them I'll have the opportunity to take advantage of user's experiences and suggestions to improve them. 

NOTE: there are bound to be some bugs, inconsistent performance, etc.  I can't guarantee they'll work for all situations and mods configs, but it should give people an idea of one way of approaching kOS and a place to start.  You may need to tweak things to fit your situation.  If you provide feedback and bug reports, I can fix and improve it both for my use and the community.   

What it's not

For those unfamiliar with kOS, it's not MechJeb. It's not plug and play. It's more of a tool kit. Unlike a regular mod, you're expected and encouraged to dig in and change things. I've learned more from trying to figure out why something isn't working as expected than when it does. It's very rewarding when you see a mission you've designed actually work like you intended.

File Structure

There are three main folders within the script folder itself.  The boot folder contains the boot script (boot.ks).  The library folder contains the functions that are used by missions.  The mission folder contains sub-folders with the name of the mission.  The mission folder is named for craft that will execute the mission. So spacecraft "Mun Probe I" will execute the script in folder "scripts\missions\Mun Probe I".  I find it makes it easier to keep track of things.  Within the mission folder is a script file names "mission.ks".  This is the file that the boot script will look for first and attempt to execute.  It will also look for a file named update.ks whenever it reboots.  This is how you can make changes during a mission. Any library scripts needed by the mission are loaded via the require("name") function.  It works pretty nifty I think.

Program Flow

Processing is structured around two primary concepts - Phase and Run Mode. Examples of phases are launch , orbiting, landing, etc.  The mission script work with phases.  Here's an example of a CommSat launch.  The main loop is a series "if phase =' statements  that control the program flow.  When one phase is complete, we setphase(x) to move to a different phase. Setphase also saves the phase variable to a file so that in the event of a power failure or reboot you can continue in the same phase. That's the intent anyway. I'm not sure how well it works in practice.

@lazyglobal off.

if true and
	require("ascent.ks") and
	require("systems.ks") and
	require("changeorbit.ks") and
	require("control.ks") and
	true {
	main().
}
else{
	notify("REBOOTING").
	wait 10.
	reboot.
}
function main {
	local iHdg is 90.
	local iOrbit is 1067600.
	local iPitch is 90.
	local fOrbit is 1067600.

	when ship:altitude > 60000 then {
		deployFairings().
	}
	when ship:altitude > 70000 then {
		deployPanels().
		deployAntenna().
	}

	if phase = 0 {
		setPhase(1).	
	}
		
	until phase = 0 {
		if phase = 1 {
			ascent(iHdg,iOrbit,iPitch).
			wait 5.
			setPhase(2).
		}
		if phase = 2 {
			changeorbit(fOrbit,true).
			setPhase(3).
		}
		if phase = 3 {
			adjustPeriod(7200).
			if approx(apoapsis,1067.7,2) {
				setphase(0).
			}
			else {
				setPhase(2).
			}
		}
	}
	setPhase(9).
	notify("Orders complete").
}

The functions being performed within the phases are the library functions. They are uploaded to the craft by the requires() function at the beginning of the script.  

In the same manner the mission script is controlled by Phase, library functions are controlled by Runmode. in the scripts, runmode is shortened to 'rm' .  Memory space in kOS is determined by character count, so I tried to keep that low without adversely impacting readability.  Even so, advanced missions requires files to be deleted and new ones uploaded as there isn't space to load the full set at once. Look in the missions/archives folder for examples of missions I've put together. I move mission folders in and out of the archive folder as I need them. This keeps the mission folder from getting cluttered while still keeping them handy.

There are displays in the console showing the phase and runmode and whatever other info I thought I needed to see at the time.

Here's the ascent script. It's not mechjeb but it works well enough most of the time.

//ascent.ks
@lazyglobal off.
require("control.ks").

function ascent{
	parameter tHeading.
	parameter tApo is 100000.
	parameter iPitch is 80.
	parameter ApoETA is 60.
	parameter sBurn is 5.
	local rm is 1.
	local mPitch is 0.
	local mPitchAlt is 60000. 
	local pidAlt is 60000. 
	local kP1 is 0.05.	// 0.05
	local kI1 is 0.6.	// 0.5
	local kD1 is 0.001.	// 0.01
	local aPID is pidloop(kP1,kI1,kD1,0,1).
	set aPID:setpoint to 200.
	local tPitch is 0.
	local tLaunch is 0.
	local tPrd is getPeriod(tApo).
	local fIg is true. 

	local tWork is 0.
 	local hWork is ship:facing.
	set tLock to tWork.
	set hLock to hWork. 
	lock throttle to tLock.
	lock steering to hLock.
		
	rcs off.
	sas off.

	clearscreen.
	local tCD is 10.
	eTime().eTime().
	if rm = 0{
		set rm to 1.
	}
	
	until rm = 0{
		if rm > 1 and verticalspeed < -50 and
			ship:altitude < 65000 and 
			ship:periapsis < 0{
			set rm to 0.
		}
		else if rm = 1{ 
			if tCD > 0{
				notify("COUNTDOWN INITIATED: T - " + round(tCD)).
				if fIg and tCD < 1{
					local lEng is list().
					list engines in lEng.
					for eng in lEng{
						if eng:stage = (stage:number - 1) and eng:allowshutdown{
							eng:activate().
							set tWork to 1.
							notify("IGNITION").
						}
					}
					set fIg to false.
				}
				set tCD to tCD - tElapsed.
			}
			else{
				stage.
				set hWork to ship:facing.
				set tWork to aPID:update(time:seconds,verticalspeed).
				set stageMax to ship:maxthrust.
				set rm to 2.
				notify("LAUNCH").
			}
		}
		else if rm = 2{
			if ship:altitude > 8000{
				set kP1 to 0.156.
				set kI1 to 0.101.	
				set kD1 to 0.060.	
				set aPID to pidloop(kP1,kI1,kD1,0,1).
				set aPID:setpoint to ApoETA.
				set rm to 3.
			}
			else if verticalspeed > 50{      
				set tPitch to min(iPitch,max(mPitch,90*(1 - alt:radar/mPitchAlt))).                    
				set hWork to heading(tHeading,tPitch).
			}
			else if verticalspeed > 20{
				set hWork to heading(tHeading,90).
			}
			set tWork to aPID:update(time:seconds,verticalspeed).
			if twork < .1{
				set tWork to .1.
			}
		}
		else if rm = 3{

			set tPitch to min(iPitch,max(mPitch,90 * (1 - alt:radar/mPitchAlt))).
			set hWork to heading(tHeading,tPitch). 
			if eta:periapsis < eta:apoapsis{
				set tWork to 1.
			}			
			else if ship:altitude < pidAlt{
				set tWork to aPID:update(time:seconds,eta:apoapsis).
				if twork < .1{
					set tWork to .1.
				}
			}
			else{
				set tWork to setThrottle(ship:apoapsis,tApo,0.1).
			}
			if (ship:apoapsis > tApo){
				set tWork to 0.
				set hWork to ship:prograde.
				notify("COAST TO APOAPSIS").
				setAlarm(time:seconds + eta:apoapsis - 90).
				set rm to 4.
			}
		}
		else if rm = 4{
			set tWork to 0.
			set hWork to ship:prograde.

			if eta:apoapsis < sBurn + 10{
				rcs on.
			}
			if eta:apoapsis < sBurn{
				notify("CIRCULARIZE").
				rcs off.
				set rm to 5.
			}
			else if eta:periapsis < eta:apoapsis{
				notify("CIRCULARIZE").
				rcs off.
				set rm to 5.
			}		
		}
		else if rm = 5{
			if ship:periapsis > 70000 and ship:orbit:period > tPrd{
				notify("ORBIT ESTABLISHED").
				set tWork to 0.
				set rm to 0.
			}
			set hWork to ship:prograde.
			set tWork to setThrottle(ship:orbit:period,tPrd,0.1).
		}
		checkStage().
		set tLock to tWork.
		set hLock to hWork.
		eTime().
		telemetry(rm).
		print "Ascent   " at (1,1).
		print "Pitch  : " + round(tPitch) + " " at (1,7).
	}
	lock throttle to 0.
	lock steering to ship:prograde.
	clearscreen.
}

 

I think that's a big enough wall of text. I guess I'll just throw this out there and answer questions as they come up.  Feedback, suggestions, bug reports are always welcome.

REQUIRES:  kOS

DOWNLOAD from SPACEDOCK 

Copy the Script folder in the download to your Kerbal Space Program\Ships folder.  DO NOT put in the GameData folder.

Included in the download is my KerboScript definition file for Notepad++.

 

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Edited by SpinkAkron
added picture
  • Like 11

Share this post


Link to post
Share on other sites

Just Curious, do these scripts work only in stock or will they work for RSS/RO players as well?

 

Share this post


Link to post
Share on other sites
37 minutes ago, Uace24 said:

Just Curious, do these scripts work only in stock or will they work for RSS/RO players as well?

I play a heavily modded setup.  I've never tried RSS/RO but I think the basics of it should work.  You'd need to make changes to some of the variable values. They're set to what I found worked for Kerbin launches, for instance.  You could give it a try and see what happens. My reason for releasing this is to give players a starting point to adapt for their needs.

Share this post


Link to post
Share on other sites
49 minutes ago, SpinkAkron said:

I play a heavily modded setup.  I've never tried RSS/RO but I think the basics of it should work.  You'd need to make changes to some of the variable values. They're set to what I found worked for Kerbin launches, for instance.  You could give it a try and see what happens. My reason for releasing this is to give players a starting point to adapt for their needs.

Alright. Thanks a bunch.

:)

Share this post


Link to post
Share on other sites

Greetings.

Great to see this new 'mod' / info / examples.

Very nicely done and i am looking forward to testing and see if i can crash learn from them.

thanks

Cheers.

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, drtedastro said:

Greetings.

Great to see this new 'mod' / info / examples.

Very nicely done and i am looking forward to testing and see if i can crash learn from them.

thanks

Cheers.

Thanks!

Share this post


Link to post
Share on other sites
On 2/13/2019 at 3:45 PM, SpinkAkron said:

I play a heavily modded setup.  I've never tried RSS/RO but I think the basics of it should work.  You'd need to make changes to some of the variable values. They're set to what I found worked for Kerbin launches, for instance.  You could give it a try and see what happens. My reason for releasing this is to give players a starting point to adapt for their needs.

The ascent script is likely not suitable for RSS/RO. In RSS/RO, you don't really coast to apoapsis. Instead, you often circularize at or after apoapsis (when you are falling back to earth). I also have an ascent script for RO/RSS, which basically does this:
- Go straight up
- At some predefined speed, make a gravity turn (speed differs per rocket, determined by trial and error)
- Let the rocket go prograde until altitude is over 100km and apogee is over 200km.
- Then if we didn't fall over our apogee, pitch slightly down. Once we fall over our apogee, pitch slightly up.

Most of my rockets typically circularize at apogee. Another advantage of my ascent script is that I simply let the rocket follow prograde throughout the dense parts of the atmosphere, so I can set 4x timewarp. (It takes 8-9 minutes usually to get into LEO. With 4x timewarp, this is 2-3 minutes).

 

Edited by Willem_D
  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)

Updated to 1.0.1

1.0.1    boot.ks - added connection check to boot(), moved lng2deg to control.ks
            ascent.ks            - made mPitchAlt a parameter, added default to tHeading, added rcs/sas
            control.ks        - added lng2deg moved from boot.ks    
            insertion.ks    - fixed syntax error on iOrbit
            MunDescent.ks    - added > 5000 check to rm 6
            navigation.ks    - added require of control.ks for lng2deg
            recovery.ks        - added rcs on to rm2, rcs off to rm5 
            science.ks        - added inoperable check to getSample()
            Mission Folder - several mission scripts fixed/updated    

 

Edited by SpinkAkron
Spellun

Share this post


Link to post
Share on other sites
Posted (edited)

A few months ago, I decided to do a YouTube series on KSP career mode using kOS.  I couldn't find an unmanned start tech tree I was really happy with so ended up making my own.  Now that the major work for Unkerballed Start is complete, I'm ready to start my series.  I play what I call hardercore mode so it's pretty slow moving with lots of fail.  Probably not the best way to demonstrate kOS, but it's how I enjoy playing.   I'm not the most exciting presenter, but I think I'm good at explaining things.  Each episode will feature a walk through of one of the scripts in this pack.  I'm not going to be explaining in great depth how kOS works. Kevin Gisi's excellent Kerbal Space Programming series does that. Instead, I'll be focusing on how I use kOS for my career mode play through. 

The first episode is the introduction, setup , and covers the mission script format. Episode two will cover the boot script. 

 

Mod List 

Spoiler


--- Mod List ---
AdjustableModPanel
AlternateResourcePanel
BAMCont
BackgroundResources
CapCom
Chatterer
ClickThroughBlocker
CollisionFXUpdated
CommunityCategoryKit
CommunityResourcePack
CommunityTechTree
ContractConfigurator
ContractConfigurator-CleverSats
ContractConfigurator-FieldResearch
ContractConfigurator-KerbalAcademy
ContractConfigurator-KerbinSpaceStation
ContractConfigurator-RemoteTech
ContractConfigurator-Tourism
ContractParser
Contract_Pack_Rover_Missions
CustomBarnKit
DMagicOrbitalScience
DeadlyReentry
DistantObject
DistantObject-default
EarnYourStripes
EditorExtensionsRedux
EngineLighting
EnvironmentalVisualEnhancements
FerramAerospaceResearchContinued
FilterExtensions
FilterExtensionsDefaultConfig
FinalFrontier
FlightTracker
IndicatorLights
IndicatorLightsCommunityExtensions
JanitorsCloset
KSP-AVC
KerbalAlarmClock
KerbalChangelog
KerbalConstructionTime
KerbalEngineerRedux
MK1StkOpenCockpit
MagiCore
MakingLessHistory
MandatoryRCS
MemGraph
MemorialWall
MissingHistory
MoarFEConfigs
ModularFlightIntegrator
ModuleManager
MonthlyBudgets
MyTweaks*
OhScrap
PartInfo
PoodsCalmNebulaSkybox
ProgressParser
ReStock
ReStockPlus
RealPlume
RealPlume-StockConfigs
ReentryParticleEffect
RemoteTech
SCANsat
SETI-Contracts
Scatterer
Scatterer-config
Scatterer-sunflare
SciFiVisualEnhancements
ScienceSituationInfo
ScrapYard
SigmaReplacements-SkyBox
SmokeScreen
SpaceAge
StageRecovery
StockNoContracts
Strategia
TACLS
TextureReplacer
ToolbarController
TriggerAu-Flags
UnKerballedStart
kOS
x.Science

 

Edited by SpinkAkron
mod list added
  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now