Jump to content

[1.3] kOS Scriptable Autopilot System v1.1.3.0


erendrake

Recommended Posts

3 hours ago, hvacengi said:

That would potentially explain why you had issues with just the fins. Look for the next update to FAR to possibly help with kOS performance.

I was able to launch your ship in stock KSP without kOS failing to attempt to steer.  Because of the angles of your fins it wasn't very stable (attempts to pitch cause the ship to yaw as well).  Because there is no limit to the angle of attack, that may also be contributing to the instability that I was observing.  As you climb through the atmosphere the ship becomes more stable.

Ah I see, so kOS doesn't like FAR fins then.. Well that's unfortunate. As far as the stability issues you were seeing in stock, I've played with FAR for a long time and it doesn't seem to have that issue.

Link to comment
Share on other sites

On 07/06/2016 at 0:32 AM, Aelfhe1m said:

Point 2 and 4 code sample:

  Hide contents


function SCANsatEvent {
	parameter partname.
	parameter eventname.
	
	set plist to ship:partsnamed(partname).
	for p in plist {
		set m to p:getmodule("SCANsat").
		if m:hasevent(eventname)
			m:doevent(eventname).
	}
}
	
function StartSCANsatScanners {
	SCANsatEvent("SCANsat.Scanner", "start radar scan").
	SCANsatEvent("SCANsat.Scanner2", "start SAR scan").
	SCANsatEvent("SCANsat.Scanner24", "start multispectral scan").
	SCANsatEvent("SCANsat.Scanner32", "start BTDT scan").
}

function StopSCANsatScanners {
	SCANsatEvent("SCANsat.Scanner", "stop radar scan").
	SCANsatEvent("SCANsat.Scanner2", "stop SAR scan").
	SCANsatEvent("SCANsat.Scanner24", "stop multispectral scan").
	SCANsatEvent("SCANsat.Scanner32", "stop BTDT scan").
}

function SCANsatAnalyzeData {
	SCANsatEvent("SCANsat.Scanner", "analyze data").
	SCANsatEvent("SCANsat.Scanner2", "analyze data").
	SCANsatEvent("SCANsat.Scanner24", "analyze data").
	SCANsatEvent("SCANsat.Scanner32", "analyze data").
}

Clearscreen.
StartSCANsatScanners().
WAIT 10.
SCANsatAnalyzeData().

 

Note there is a distinction in SCANsat between the scan data which is continually accumulated while the scanner is running and the science data result that can be transmitted for R&D science points.

I see. Well I'm already happy that it's already possible to start the scanning. I'll head over to the SCANsat thread to inquire about compatibility with kOS.

Link to comment
Share on other sites

The next release of SCANsat will have a science gather method similar to what I added for Orbital Science, it will allow for science collection without opening the results window. It will require explicit support from KOS, but at least the option will be there.

https://github.com/DMagic1/SCANsat/commit/ce2be8fc375ba12d59c06efa6bd12b39d3328f16

Link to comment
Share on other sites

8 minutes ago, DMagic said:

The next release of SCANsat will have a science gather method similar to what I added for Orbital Science, it will allow for science collection without opening the results window. It will require explicit support from KOS, but at least the option will be there.

https://github.com/DMagic1/SCANsat/commit/ce2be8fc375ba12d59c06efa6bd12b39d3328f16

Awesome!  Explicit support won't be a problem.  We already have specific support for Orbital Science anyways.  Thanks for keeping us posted!

In the future, I will probably want to pick your brain about how to let kOS get the map data out of SCANsat, as that's been an "issue" on our road map for a while too.

Link to comment
Share on other sites

I started a new career game, this time with the objective "automate everything". Including science gathering.

So I start with contracts to launch a sounding rocket to an altitude of over 2000m and gather some science.

I have this in boot_sounding.ks

FUNCTION do_science {
  SET P TO SHIP:PARTSNAMED("SR.ProbeCore")[0].
  SET M TO P:GETMODULE("ModuleScienceExperiment").
  M:DEPLOY.
  WAIT UNTIL M:HASDATA.
  M:TRANSMIT.
}

PRINT "Launch program initiated".
do_science.

PRINT "Counting down:".
FROM {local countdown is 3.} UNTIL countdown = 0 STEP {SET countdown to countdown - 1.} DO {
  PRINT "..." + countdown.
  WAIT 1.
}
PRINT "LAUNCH!". STAGE.

WAIT 10. do_science.

WAIT 30. STAGE. STAGE. STAGE. SET CHUTES TO TRUE. CHUTES ON.
SHUTDOWN.

The rocket gets launched after a 3 second countdown, but

  1. No science (Analyze Telemetry) is collected or transmitted.
  2. The chutes don't deploy. That 3 times staging etc is my "panic mode". None of it worked. I verified that manual deployment (pressing space) works.

The script doesn't output errors.

How do I start to debug?

EDIT: I am not near my gaming pc now so I cannot verify, but I wonder: I labeled the probe core "SR.ProbeCore", but maybe kOS looks at some other, internal name? What if it cannot find that part? Should it give an error, or just do nothing at all?
I'm still clueless about the chutes (sounding rocket nose cone).

Edited by Amedee
Link to comment
Share on other sites

19 hours ago, Amedee said:

I am not near my gaming pc now so I cannot verify, but I wonder: I labeled the probe core "SR.ProbeCore", but maybe kOS looks at some other, internal name? What if it cannot find that part? Should it give an error, or just do nothing at all?
I'm still clueless about the chutes (sounding rocket nose cone).

When you say you labeled the probe core, do you mean you modified it's kOS name tag?  If so, you do want to use partstagged suffix instead.  The partsnamed suffix relies on the internal name that KSP uses in the cfg file.  But I suspect this is not the root of your issue, because kOS would have thrown an exception if you tried to access an item in an empty list.  If I were to guess, the issue is with the deploy command or the hasdata suffix.  Try adding some debug prints through your code to check the progress.  For example, you could add the line "print "deploying science!". " before calling deploy, that way you know that you reached that part of the code.  I don't know what science experiment Sounding Rockets supports on the probe core, but I can probably look at some point.

But if you're blocking at that point, you never reach the code that is supposed to deploy the parachutes.

Edited by hvacengi
Link to comment
Share on other sites

4 hours ago, hvacengi said:

When you say you labeled the probe core, do you mean you modified it's kOS name tag?  If so, you do want to use partstagged suffix instead.  The partsnamed suffix relies on the internal name that KSP uses in the cfg file.  But I suspect this is not the root of your issue, because kOS would have thrown an exception if you tried to access an item in an empty list.  If I were to guess, the issue is with the deploy command or the hasdata suffix.  Try adding some debug prints through your code to check the progress.  For example, you could add the line "print "deploying science!". " before calling deploy, that way you know that you reached that part of the code.  I don't know what science experiment Sounding Rockets supports on the probe core, but I can probably look at some point.

But if you're blocking at that point, you never reach the code that is supposed to deploy the parachutes.

It wouldn't matter if I used PARTSNAMED or PARTSTAGGED because I made the kOS name tag identical to the internal name in the cfg file. But thanks for the distinction.

The science experiment on the probe core of a sounding rocket is just the generic "Analyze Telemetry".

When I add that print statement, the experiment runs... but maybe I made a mistake. Remember I wrote I want to automate everything with kOS? Well, then I should also remove the ForScience mod, which also automatically runs experiments. Doh! So I did that.

Another possible mistake: when I edit a script and save it, I shouldn't revert to launch but revert to assembly, or the updated script won't be loaded. At least it appears that way.

But I wouldn't have known without the debug statement, which tells me that I did not reach that code, why? Because kOS wasn't even aware that there was new code! Doh!

I decided to put my scripts on GitHub, if anyone is interested: https://github.com/amedee/kOS/blob/master/boot_sounding.ks

Thanks for being my rubber duck! The script runs as expected now.

Edited by Amedee
Link to comment
Share on other sites

Hello,

So I've been having a strange issue with trying to get any information at all about the engines on my ship... I've tried the following code which I got from the documentation, but for some reason it always returns 0. It will properly create the list with the proper number of engines in it and it will print the values in the FOR loop, however it just says that all of the engines ISP are 0, which obviously wouldn't be the case.

LIST ENGINES IN myVariable.
FOR eng IN myVariable {
    print "An engine exists with ISP = " + eng:ISP.
}.

 

Link to comment
Share on other sites

14 hours ago, CoriW said:

Hello,

So I've been having a strange issue with trying to get any information at all about the engines on my ship... I've tried the following code which I got from the documentation, but for some reason it always returns 0. It will properly create the list with the proper number of engines in it and it will print the values in the FOR loop, however it just says that all of the engines ISP are 0, which obviously wouldn't be the case.


LIST ENGINES IN myVariable.
FOR eng IN myVariable {
    print "An engine exists with ISP = " + eng:ISP.
}.

 

Currently engines always report an ISP and thrust of zero if they are not currently active.  I'm guessing you have not yet staged them on.

Link to comment
Share on other sites

37 minutes ago, hvacengi said:

Currently engines always report an ISP and thrust of zero if they are not currently active.  I'm guessing you have not yet staged them on.

Oh, that makes a lot of sense actually! Thanks for the info. :)

Link to comment
Share on other sites

Just now, CoriW said:

Oh, that makes a lot of sense actually! Thanks for the info. :)

There have been discussions recently about providing a way to get this information from an inactive engine.  There are potential benefits for delta-v calculations, but it presents some additional issues both in backwards compatibility and fuel flow handling.  It simply hasn't been our highest of priorities.

Link to comment
Share on other sites

Is there any way of setting up a trigger on something like a keystroke or a joystick button? KSP v1.1 seems to have made the longstanding Linux throttle range bug worse (it used to not happen if the throttle axis was centered when KSP started, now it almost always happens no matter what I do), so I'm creating a throttle calibration script to unbuginate the throttle behavior (and add some 90's analog joystick nostalgia at the same time). Currently, it just use a timed wait:

 

Print "Please move throttle to minimum within 5 seconds.".
wait 5.
set min to ship:control:pilotmainthrottle.
print min.
Print "Please move throttle to maximum within 5 seconds.".
wait 5.
set max to ship:control:pilotmainthrottle.
print max.
on ship:control:pilotmainthrottle
{
	set ship:control:mainthrottle to (ship:control:pilotmainthrottle - min + 0.001) / (max - min).
	return true.
}.
Print "Ready.".
wait until false.

The offset of 0.001 is to avoid some weirdness that happens at zero throttle without it (the throttle goes to somewhere around 0.5, assuming that the KSP Linux Joystick Bug has stuck PILOTMAINTHROTTLE between 0.5 and 1 on this run of KSP). Even a small offset prevents this.

 

What I'd like to have is something like this:

Print "Please move throttle to minimum and press any joystick button.".
//Code here to wait for joystick button event.
set min to ship:control:pilotmainthrottle.
print min.
Print "Please move throttle to maximum and press any joystick button.".
//Code here to wait for joystick button event.
set max to ship:control:pilotmainthrottle.
print max.
on ship:control:pilotmainthrottle
{
	set ship:control:mainthrottle to (ship:control:pilotmainthrottle - min + 0.001) / (max - min).
	return true.
}.
Print "Ready.".
wait until false.


 


 

Link to comment
Share on other sites

On 6/17/2016 at 9:04 PM, luizopiloto said:

Why is there no BEEP. command? :(

PRINT "ASCII CODE 7 IS THE BEEP CHARACTER".

PRINT CHAR(7) + "BEEPING ONCE.".

WAIT 1.

PRINT CHAR(7) + "BEEPING AGAIN 1 SECOND LATER.".

 

Link to comment
Share on other sites

This took 3 days to achieve... 3 whole days...

95e6ade9ca75fdddf04b51ce0a211ff6.png

It's also only 2 burns.. The initial launch burn followed by a single insertion burn, I'd say accurate within 11 meters is close enough. Though with me being a perfectionist, I'm probably going to tweak it even more in a futile attempt at perfection. On a side note, I've literally tested this with at least 50 launches to get it to this point. (The initial script was accurate within about 100km, it's definitely improved since then.) xD

Link to comment
Share on other sites

3 hours ago, CoriW said:

This took 3 days to achieve... 3 whole days...

95e6ade9ca75fdddf04b51ce0a211ff6.png

It's also only 2 burns.. The initial launch burn followed by a single insertion burn, I'd say accurate within 11 meters is close enough. Though with me being a perfectionist, I'm probably going to tweak it even more in a futile attempt at perfection. On a side note, I've literally tested this with at least 50 launches to get it to this point. (The initial script was accurate within about 100km, it's definitely improved since then.) xD

Just as a helpful hint - remember the game can't change the ship control settings more often than the physics rate of 25 ticks per second.  Trying to get it more accurate than you already are may be a futile gesture because of that.  Also, some of the calculations the stock game itself uses to define your orbit based on your current position and velocity are numerical approximation algorithms that get stopped when they get within a "good enough" epsilon error.   So... trying to achieve more precision than those limitations allow for may be literally impossible within the simulation environment of the game.

Also, I suspect real-world launches can't be that accurate either, and have to depend on RCS to fine tune it post-launch, purely because the rocket engine is a physical process the software is controlling, involving moving parts: valves, pumps, etc.  Even under two identical runs of the software, there will still be small variation in how fast the physical engine shuts off in reaction to the commands the software gave it.

 

Link to comment
Share on other sites

Hi folks!

“Open Terminal” is missing in the CX-4181 Scriptable Control System part (acronym SCS).

I've just installed kOS.

 

This is how it should look:

terminal_open_1.png

 

The entry is missing in my setup: http://imgur.com/n59EiXB

 

n59EiXB

What is wrong?

 

Update: Kerbal Game has Version 1.1.2.
If I use CKAN.exe the kOS is listed as Incompatibel. Any clue?

 

Update 2: Its working now. Dont know why. Sunflares?  Restarted my computer. My post can be deletet my the moderator.

Edited by AnnaVonOesterreich
Delete please. Problem solved by magic.
Link to comment
Share on other sites

11 hours ago, Steven Mading said:

Just as a helpful hint - remember the game can't change the ship control settings more often than the physics rate of 25 ticks per second.  Trying to get it more accurate than you already are may be a futile gesture because of that.  Also, some of the calculations the stock game itself uses to define your orbit based on your current position and velocity are numerical approximation algorithms that get stopped when they get within a "good enough" epsilon error.   So... trying to achieve more precision than those limitations allow for may be literally impossible within the simulation environment of the game.

Also, I suspect real-world launches can't be that accurate either, and have to depend on RCS to fine tune it post-launch, purely because the rocket engine is a physical process the software is controlling, involving moving parts: valves, pumps, etc.  Even under two identical runs of the software, there will still be small variation in how fast the physical engine shuts off in reaction to the commands the software gave it.

 

Ah, that's good to know. Currently the parts of my script that run in loops run with a "WAIT 0.01." at the end of them, which I suppose would turn out to be 100 ticks per second. Would that mean I should be using "WAIT 0.04." instead? As 0.04 x 25 = 1.00. Anyways on a side note, after I did that test I tried the same test for a lower orbit with a higher thrust.. It didn't turn out nearly as good, with an accuracy of about 400m. That being said, my current steering method is sub-optimal because I haven't figured out PID controllers yet.. Here's my current steering method, any tips would be appreciated.

WAIT UNTIL ETA:APOAPSIS <= halfBurn.

SET currPitch TO 0.
LOCK STEERING TO HEADING(90,currPitch) + R(0,0,-90).

UNTIL SHIP:PERIAPSIS >= orbitAlt {
	
	IF halfBurn <= 5 {
		IF ETA:APOAPSIS <= 3 {
			SET currPitch TO 3 - (3 - ETA:APOAPSIS).
		}
		ELSE IF ETA:APOAPSIS > 3 AND ETA:APOAPSIS < ETA:PERIAPSIS {
			IF currPitch > 0 {
				SET currPitch TO 0.
			}
			ELSE {
				SET currPitch TO currPitch - 0.04.
			}
		}
		ELSE IF ETA:APOAPSIS > ETA:PERIAPSIS {
			IF currPitch < 0 {
				SET currPitch TO 0.
			}
			ELSE {
				SET currPitch TO currPitch + 0.04.
			}
		}
	}
	
	IF halfBurn > 0 {
		SET halfBurn TO halfBurn - 0.01.
	}
	
	WAIT 0.01.
}

(Note: I've removed some bits involving throttle control from the code snippet as the throttle control isn't what I'm worried about.)

Link to comment
Share on other sites

13 minutes ago, CoriW said:

Ah, that's good to know. Currently the parts of my script that run in loops run with a "WAIT 0.01." at the end of them, which I suppose would turn out to be 100 ticks per second. Would that mean I should be using "WAIT 0.04." instead?



 

A kOS WAIT command is incapable of waiting less than the duration of a single physics tick.  If the wait conditions are such that the wait should take less time than it takes to get to the next physics tick, the duration of the wait ends up being effectively "rounded up" to the start of the next physics tick.

In fact, this means you can even say WAIT 0. in place of WAIT 0.01 and it will end up doing the same thing.

The moment you WAIT, you are "yielding" the remainder of the current update's slice of time and telling the system to check during each subsequent update to see if it's time to continue or not.  At minimum, regardless of how small the WAIT duration is, or what the boolean condition of a WAIT UNTIL is, it can't notice its time to continue until the next update checks again.

Or to put it another way, "WAIT cannot resume halfway through a physics update.  All WAIT durations end up rounding up to the next nearest start of a physics update."

 

Link to comment
Share on other sites

Not sure whether this is the right forum, but I'm stumped on an autonavigation script I'm trying to develop for kOS. The waypoint selection code works fine, but I can't seem to actually get the rover to drive to the waypoint...help? Code is below.

 

CLEARSCREEN. SET SHIP:CONTROL:PILOTMAINTHROTTLE TO 0. LOCK THROTTLE TO 0. SWITCH TO 0. RUN autolights. RCS OFF. SAS OFF. GEAR OFF.

// My plan for autonomous navigation is an iterative algorithm.

// The goal is a LATLNG() that is calculated
// from the input parameter hdg in degrees clockwise from north.

PARAMETER hdg, horizonMultiplier.

AUTOLIGHTS().

SET dist TO SQRT((BODY:RADIUS + ALTITUDE)^2 - (BODY:RADIUS ^ 2)). // Radio horizon calculation
SET distLat TO (horizonMultiplier * dist) * COS(hdg). // X offset = a multiple of the x unit vector
SET distLng TO (horizonMultiplier * dist) * SIN(hdg). // Y offset = a multiple of the y unit vector

SET offSetLat TO (360 * (distLat * 0.9)) / (2 * BODY:RADIUS * CONSTANT:PI). // The difference in latitude caused by moving x meters north or south
SET offSetLng TO (360 * (distLng * 0.9)) / (2 * BODY:RADIUS * CONSTANT:PI). // The difference in longitude caused by moving y meters east or west

SET startPos TO SHIP:GEOPOSITION.
SET goal TO LATLNG(SHIP:GEOPOSITION:LAT + offSetLat, SHIP:GEOPOSITION:LNG + offSetLng). // The current position plus the offset

// First the script checks to see whether it has reached the goal.
FUNCTION THERE_YET
{
	PARAMETER goal.
	IF goal:DISTANCE < 1
	{
		RETURN TRUE.
	}
	ELSE
	{
		RETURN FALSE.
	}
}

// Next, it creates a list of waypoints set 5m away
FUNCTION POPULATE
{
	SET offSetA TO (360 * 100) / (BODY:RADIUS * 2 * CONSTANT:PI).
	SET offSetB TO offSetA * SIN(45).
	
	SET optionA TO LATLNG(startPos:LAT + offSetA, startPos:LNG).			// N
	SET optionB TO LATLNG(startPos:LAT + offSetB, startPos:LNG + offSetB).	// NE
	SET optionC TO LATLNG(startPos:LAT, startPos:LNG + offSetA).			// E
	SET optionD TO LATLNG(startPos:LAT - offSetB, startPos:LNG - offSetB). 	// NW
	SET optionE TO LATLNG(startPos:LAT - offSetA, startPos:LNG). 			// S
	SET optionF TO LATLNG(startPos:LAT - offSetB, startPos:LNG + offSetB). 	// SW
	SET optionG TO LATLNG(startPos:LAT, startPos:LNG - offSetA).			// W
	SET optionH TO LATLNG(startPos:LAT + offSetB, startPos:LNG - offSetB). 	// NW
	
	SET options TO LIST(optionA, optionB, optionC, optionD, optionF, optionG, optionH).
	PRINT("Deciding options...done.") AT (1,1).
	RETURN options.
}

// Then, it defines two helper functions - one for slope...
FUNCTION SLOPE_IS_SAFE
{
	PARAMETER option.
	SET location TO SHIP:GEOPOSITION.
	SET newHeight TO option:TERRAINHEIGHT.
	SET slope TO ABS(ARCTAN2((newHeight - location:TERRAINHEIGHT), 1000)).
	IF slope < 20 {RETURN TRUE.}
	ELSE {RETURN FALSE.}
}

// ...and one for bearing difference.
FUNCTION ANGLE_IS_OK
{
	PARAMETER goal, option.
	SET angle TO ABS(goal:BEARING - option:BEARING).
	IF angle < 60 {RETURN TRUE.}
	ELSE {RETURN FALSE.}
}

// Next, the function iterates through the list of points and evaluates the conditions.
// It picks the first point that matches both
FUNCTION DECIDE_NEXT
{
	PARAMETER goal, options.
	PRINT("Iterating through options.") AT (1,2).
	FOR o IN options
	{
		IF SLOPE_IS_SAFE(o) AND ANGLE_IS_OK(goal, o)
		{
			SET nextPoint TO LATLNG(o:LAT, o:LNG).
			RETURN nextPoint.
		}
	}
}

// Finally, it drives there using PID steering and throttle.
// How do I do this?!?
FUNCTION DRIVE
{
	PARAMETER p.
	SET desiredSpd TO 5.
	
	SET pWT TO 0. SET iWT TO 0. SET wtVAL TO 0.
	SET pSteer TO 0. SET iSteer TO 0. SET dSteer TO 0. SET lastPSteer TO 0.
	
	SET loopT TO 0.01. SET loopEndT TO TIME:SECONDS. SET NORTHPOLE TO LATLNG(90,0).
	
	UNTIL p:DISTANCE < 10
	{
		SET pWT TO desiredSpd - GROUNDSPEED.
		SET iWT TO MIN(1, MAX(-1, iWT + (pWT * loopT))).
		SET wtVAL TO pWT + iWT.
		
		SET pSteer TO (p:BEARING / 180).
		SET dSteer TO (pSteer - lastPSteer) / (loopEndT - loopT).
		
		SET steerVAL TO -0.5 * pSteer + 0.75 * dSteer.
		
		SET lastPSteer TO pSteer.
		
		LOCK WHEELTHROTTLE TO wtVAL. LOCK WHEELSTEER TO steerVAL.
		
		PRINT("Target heading: " + p:HEADING) AT (1,1).
		PRINT("Bearing to target: " + p:BEARING) AT (1,2).
		
		SET lastPSteer TO pSteer.
		SET loopT TO TIME:SECONDS - loopEndT.
		SET loopEndT TO TIME:SECONDS.
	}
}

UNTIL THERE_YET(goal)
{
	BRAKES ON.
	WAIT 1. POPULATE().
	WAIT 1. DECIDE_NEXT(goal, options).
	WAIT 1. CLEARSCREEN. BRAKES OFF.
	DRIVE(nextPoint).
	UNLOCK ALL. LOCK THROTTLE TO -1.
	WAIT UNTIL GROUNDSPEED < 0.25. BRAKES ON. WAIT 1. UNLOCK ALL.
}
UNLOCK ALL. LOCK THROTTLE TO -1.
WAIT UNTIL GROUNDSPEED < 0.25. BRAKES ON.
SET SHIP:CONTROL:PILOTMAINTHROTTLE TO 0. UNLOCK ALL.

 

Link to comment
Share on other sites

When I try to use IRServo:MoveTo(), I got a Error saying:
"Object reference not set to an instance of an object"
Could anyone tell me how shall I correct it?

The following is my codes:

print ADDONS:IR:GROUPS[0]:servos[0]:name. //This order works well.
ADDONS:IR:GROUPS[0]:servos[0]:moveto(47,2). 
//The Error happened. And the position is the second parameter "2".
wait 10.

Thanks.

 

PS: KSP 1.1.2 64x + kOS 0.20.1 + IR-2.0.2-Final-Full

Edited by Lookerksy
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...