-
Posts
334 -
Joined
-
Last visited
Content Type
Profiles
Forums
Developer Articles
KSP2 Release Notes
Everything posted by MAFman
-
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
// Until the goal has been reached, go through this process. PARAMETER goal. // The loop... Functions are defined below UNTIL THERE_YET(goal) { POPULATE(). DECIDE_NEXT(goal, options, 0). DRIVE_TO(nextPoint). } LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 0.5. UNLOCK ALL. BRAKES ON. FUNCTION THERE_YET { PARAMETER point. SET here TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG). SET there TO point. // Crazy formula ahead!!! SET delta TO ARCTAN2(SQRT((COS(there:LAT * SIN(there:LNG - here:LNG))^2) + (COS(here:LAT) * SIN(there:LAT) - SIN(here:LAT) * COS(there:LAT) * COS(there:LNG - here:LNG) ^ 2)), (SIN(here:LAT) * SIN(there:LAT) + COS(here:LNG) * COS(there:LNG) * COS(there:LNG - here:LNG))). // Whew! SET dist TO BODY:RADIUS * delta. IF dist < 10 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION POPULATE { SET offset_90 TO (360 * lookAhead) / (2 * BODY:RADIUS * CONSTANT:PI). //100m north, east, south, or west. SET offset_45 TO offset_90 * SIN(45). SET options TO LIST ( LATLNG(SHIP:GEOPOSITION:LAT + offset_90, SHIP:GEOPOSITION:LNG), // N LATLNG(SHIP:GEOPOSITION:LAT + offset_45, SHIP:GEOPOSITION:LNG + offset_45), // NE LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG + offset_90), // E LATLNG(SHIP:GEOPOSITION:LAT - offset_45, SHIP:GEOPOSITION:LNG + offset_45), // SE LATLNG(SHIP:GEOPOSITION:LAT - offset_90, SHIP:GEOPOSITION:LNG), // S LATLNG(SHIP:GEOPOSITION:LAT - offset_45, SHIP:GEOPOSITION:LNG - offset_45), // SW LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG - offset_90), // W LATLNG(SHIP:GEOPOSITION:LAT + offset_45, SHIP:GEOPOSITION:LNG - offset_45) // W ). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER option. SET here TO SHIP:GEOPOSITION. SET there TO option. SET slope TO ABS(ARCTAN2(there:TERRAINHEIGHT - here:TERRAINHEIGHT, lookAhead)). IF slope < acceptableSlope { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION BEARING_IS_OK { PARAMETER option, goal. SET brg TO ABS(goal:BEARING - option:BEARING). // Make sure the result makes sense... IF brg > 180 { SET brg TO brg - 360. } IF brg < 60 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER goal, options, startPos. SET o TO options[startPos]. IF SLOPE_IS_SAFE(o) AND BEARING_IS_OK(o, goal) { SET nextPoint TO o. RETURN nextPoint. } ELSE { SET startPos TO startPos + 1. DECIDE_NEXT(goal, options, startPos). } } FUNCTION DRIVE_TO { PARAMETER point. SET spd TO 1. // Really stinkin' slow, but safe. // Throttle control variables SET kPT TO 0.05. SET kIT TO 0.25. SET kDT TO 0.75. SET throttlePID TO PIDLOOP(kPT, kIT, kDT, -1, 1). SET throttlePID:SETPOINT TO spd. // Steering control variables SET kPS TO (1/180). SET kIS TO 0.01. SET kDS TO 0.125. SET steerPID TO PIDLOOP(kPS, kIS, kDS, -1, 1). SET steerPID:SETPOINT TO point:HEADING. UNTIL THERE_YET(point) { SET WHEELTHROTTLE TO throttlePID:OUTPUT. SET WHEELSTEER TO steerPID:OUTPUT. } } Fixed it? -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
StartPos is initially 0. -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
https://drive.google.com/file/d/0B1BXLWa5LPIMWmw4M0xPTk1JNE0/view?usp=sharing Ok, corrected the order of parameters bug / typo. It's still not letting me iterate over the options, though... Attached is a screenshot of the error. -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
// Until the goal has been reached, go through this process. // The loop... Functions are defined below UNTIL THERE_YET(goal) { POPULATE(). DECIDE_NEXT(options, goal). DRIVE_TO(nextPoint). } LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 0.5. UNLOCK ALL. BRAKES ON. FUNCTION THERE_YET { PARAMETER point. SET here TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG). SET there TO point. // Crazy formula ahead!!! SET delta TO ARCTAN2(SQRT((COS(there:LAT * SIN(there:LNG - here:LNG))^2) + (COS(here:LAT) * SIN(there:LAT) - SIN(here:LAT) * COS(there:LAT) * COS(there:LNG - here:LNG) ^ 2)), (SIN(here:LAT) * SIN(there:LAT) + COS(here:LNG) * COS(there:LNG) * COS(there:LNG - here:LNG))). // Whew! SET dist TO BODY:RADIUS * delta. IF dist < 10 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION POPULATE { SET offset_90 TO (360 * lookAhead) / (2 * BODY:RADIUS * CONSTANT:PI). //100m north, east, south, or west. SET offset_45 TO offset_90 * SIN(45). SET options TO LIST ( LATLNG(SHIP:GEOPOSITION:LAT + offset_90, SHIP:GEOPOSITION:LNG), // N LATLNG(SHIP:GEOPOSITION:LAT + offset_45, SHIP:GEOPOSITION:LNG + offset_45), // NE LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG + offset_90), // E LATLNG(SHIP:GEOPOSITION:LAT - offset_45, SHIP:GEOPOSITION:LNG + offset_45), // SE LATLNG(SHIP:GEOPOSITION:LAT - offset_90, SHIP:GEOPOSITION:LNG), // S LATLNG(SHIP:GEOPOSITION:LAT - offset_45, SHIP:GEOPOSITION:LNG - offset_45), // SW LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG - offset_90), // W LATLNG(SHIP:GEOPOSITION:LAT + offset_45, SHIP:GEOPOSITION:LNG - offset_45) // W ). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER option. SET here TO SHIP:GEOPOSITION. SET there TO option:GEOPOSITION. SET slope TO ABS(ARCTAN2(there:TERRAINHEIGHT - here:TERRAINHEIGHT, lookAhead)). IF slope < acceptableSlope { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION BEARING_IS_OK { PARAMETER option, goal. SET brg TO ABS(goal:BEARING - option:BEARING). // Make sure the result makes sense... IF brg > 180 { SET brg TO brg - 360. } IF brg < 60 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER goal, options. SET n TO 0. UNTIL FALSE { IF SLOPE_IS_SAFE(options[n]) AND BEARING_IS_OK(options[n], goal) { SET nextPoint TO options[n]. BREAK. } ELSE IF SLOPE_IS_SAFE(options[n]) { SET nextPoint TO options[n]. BREAK. } ELSE { SET n TO n + 1. } } RETURN nextPoint. } FUNCTION DRIVE_TO { PARAMETER point. SET spd TO 1. // Really stinkin' slow, but safe. // Throttle control variables SET kPT TO 0.05. SET kIT TO 0.25. SET kDT TO 0.75. SET throttlePID TO PIDLOOP(kPT, kIT, kDT, -1, 1). SET throttlePID:SETPOINT TO spd. // Steering control variables SET kPS TO (1/180). SET kIS TO 0.01. SET kDS TO 0.125. SET steerPID TO PIDLOOP(kPS, kIS, kDS, -1, 1). SET steerPID:SETPOINT TO point:HEADING. UNTIL THERE_YET(point) { SET WHEELTHROTTLE TO throttlePID:OUTPUT. SET WHEELSTEER TO steerPID:OUTPUT. } } Ok... Revamped the autonav script, but now I'm having trouble with iteration... What's going on? -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
I've corrected as many errors as I can, but it's still throwing the same exception. PARAMETER hdg. // 0 -> 359; 0 = north, 90 = east, etc. FUNCTION NOTIFY { PARAMETER message. HUDTEXT("kOS: " + message, 5, 2, 50, GREEN, FALSE). } FUNCTION SET_GOAL { PARAMETER theta. SET position_here TO SHIP:GEOPOSITION. SET height_here TO pos:TERRAINHEIGHT. SET planet_radius TO BODY:RADIUS. SET d TO (2 * CONSTANT:PI * planet_radius) * ARCSIN(SQRT((planet_radius + height_here)^2 - planet_radius^2) / ((planet_radius + height_here) / 360)). // Radio horizon equation SET delta TO d * 0.95. // 5% safety margin SET goal TO LATLNG(pos:LATITUDE + (delta * SIN(theta)), pos:LONGITUDE + (delta * COS(theta))). RETURN goal. } FUNCTION ARRIVED { PARAMETER this, that. SET here TO LATLNG(this:LAT, this:LNG). SET there TO LATLNG(this:LAT, that:LNG). SET dist TO BODY:RADIUS * ARCCOS((SIN(here:LNG) * SIN(there:LNG)) + (COS(here:LNG) * COS(there:LNG) * COS(ABS(here:LAT - there:LAT)))). IF dist < 10 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION POPULATE { SET location TO LATLNG(SHIP:GEOPOSITION). SET off_90 TO 36000/(2*CONSTANT:PI*BODY:RADIUS). SET off_675 TO off_90 * SIN(67.5). SET off_45 TO off_90 * SIN(45). SET off_225 TO off_90 * SIN(22.5). SET options TO LIST ( LATLNG(location:LAT + off_90, location:LNG), // N LATLNG(location:LAT + off_675, location:LNG + off_225), // NNE LATLNG(location:LAT + off_45, location:LNG + off_45), // NE LATLNG(location:LAT + off_225, location:LNG + off_675), // ENE LATLNG(location:LAT, location:LNG + off_90), // E LATLNG(location:LAT - off_225, location:LNG + off_675), // ESE LATLNG(location:LAT - off_45, location:LNG + off_45), // SE LATLNG(location:LAT - off_675, location:LNG + off_225), // SSE LATLNG(location:LAT - off_90, location:LNG), // S LATLNG(location:LAT - off_675, location:LNG - off_225), // SSW LATLNG(location:LAT - off_45, location:LNG - off_45), // SW LATLNG(location:LAT - off_225, location:LNG - off_675), // WSW LATLNG(location:LAT, location:LNG - off_90), // W LATLNG(location:LAT + off_225, location:LNG - off_675), // WNW LATLNG(location:LAT + off_45, location:LNG - off_45), // NW LATLNG(location:LAT + off_675, location:LNG - off_225) // NNW ). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER point. SET geo_point TO GEOPOSITION(point:LATITUDE, point:LONGITUDE). SET slope TO ABS(ARCTAN2(geo_point:TERRAINHEIGHT - SHIP:ALTITUDE, 100)). IF slope < 15 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION ANGLE_IS_REASONABLE { PARAMETER option, goal. SET angle TO ABS(goal:BEARING - option:BEARING). IF angle < 60 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_SAFE(o) { IF ANGLE_IS_REASONABLE(o, goal) { SET nextpoint TO LATLNG(o:LAT, o:LNG). RETURN nextpoint. } } } } FUNCTION DRIVE_TO { PARAMETER point. LOCK turnlimit TO MIN(1, 1.5 / GROUNDSPEED). // Scale the // turning radius // based on current speed SET loopTime TO 0.01. SET loopEndTime TO TIME:SECONDS. SET eWheelThrottle TO 0. // Error between target speed and actual speed SET iWheelThrottle TO 0. // Accumulated speed error SET wtVAL TO 0. //Wheel Throttle Value SET eSteer TO 0. // Steering error SET kTurn TO 0. //Wheel turn value. SET targetspeed TO 0. //Cruise control starting speed SET targetHeading TO 90. //Used for autopilot steering SET NORTHPOLE TO LATLNG(90, 0). //Reference heading CLEARSCREEN. PRINT("Activate action group 10 to begin driving."). ON AG10 { SET runmode TO 0. } UNTIL runmode = -1 { IF SHIP:SENSORS:LIGHT < 0.75 { LIGHTS ON. } ELSE { LIGHTS OFF. } IF runmode = 0 { //Update the compass: // I want the heading to match the navball // and be out of 360' instead of +/-180' // I do this by judging the heading relative // to a latlng set to the north pole IF NORTHPOLE:BEARING <= 0 { SET cHeading TO ABS(NORTHPOLE:BEARING). } ELSE { SET cHeading TO (180 - NORTHPOLE:BEARING) + 180. } IF targetHeading > 360 { SET targetHeading TO targetHeading - 360. } ELSE IF targetHeading < 0 { SET targetHeading TO targetHeading + 360. } BRAKES OFF. SET eWT TO targetSpeed - GROUNDSPEED. SET iWT TO MIN(1, MAX(-1, iWheelThrottle + (eWheelThrottle * loopTime))). SET wtVAL TO MIN(1, MAX(-1, eWT + iWT)). SET eSteer TO targetHeading - cHeading. IF eSteer > 180 { SET eSteer TO eSteer - 360. } SET desiredSteering TO -eSteer / 10. SET kTurn TO MIN(1, MAX(-1, desiredSteering)) * turnLimit. } SET SHIP:CONTROL:WHEELTHROTTLE TO wtVAL. SET SHIP:CONTROL:WHEELSTEER TO kTurn. SET loopTime TO TIME:SECONDS - loopEndTime. SET loopEndTime TO TIME:SECONDS. IF ARRIVED(SHIP:GEOPOSITION, point:GEOPOSITION) { SET runmode TO -1. } } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. NOTIFY("Arrived at waypoint. Setting next."). } SET_GOAL(hdg). UNTIL ARRIVED(SHIP:GEOPOSITION, goal) { POPULATE(). DECIDE(options, goal). DRIVE_TO(nextPoint). } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. NOTIFY("Arrived at goal! Shutting down."). FOR ants IN SHIP:PARTSNAMED("rtLongAntenna2") { ants:GETMODULE("ModuleAnimateGeneric"):DOEVENT("Extend"). } LIGHTS ON. SHUTDOWN. -
I have something that looks promising, but it refuses to run... Can someone tell me why? PARAMETER hdg. // 0 -> 359; 0 = north, 90 = east, etc. FUNCTION NOTIFY { PARAMETER message. HUDTEXT("kOS: " + message, 5, 2, 50, GREEN, FALSE). } FUNCTION SET_GOAL { PARAMETER theta. SET pos TO SHIP:GEOPOSITION. SET h TO pos:TERRAINHEIGHT. SET r TO BODY:RADIUS. SET d TO (2 * CONSTANT:PI * BODY:RADIUS) * ARCSIN(SQRT((R+h)^2-R^2)/((R+h)/360)). // Radio horizon equation SET delta TO d * 0.95. // 5% safety margin SET goal TO LATLNG ( pos:LAT + (delta * SIN(theta)), pos:LNG + (delta * COS(theta)) ). RETURN goal. } FUNCTION ARRIVED { PARAMETER location, setpoint. SET here TO LATLNG(location:LAT, location:LNG). SET there TO LATLNG(setpoint:LAT, setpoint:LNG). SET dist TO BODY:RADIUS * ARCCOS((SIN(here:LNG) * SIN(there:LNG)) + (COS(here:LNG) * COS(there:LNG) * COS(ABS(here:LAT - there:LAT)))). IF dist < 10 { SET arrived TO TRUE. } ELSE { SET arrived TO FALSE. } RETURN arrived. } FUNCTION POPULATE { SET loc TO LATLNG(SHIP:GEOPOSITION). SET off_90 TO 36000/(2*CONSTANT:PI*BODY:RADIUS). SET off_675 TO off_90 * SIN(67.5). SET off_45 TO off_90 * SIN(45). SET off_225 TO off_90 * SIN(22.5). SET a TO LATLNG(loc:LAT + off_90, loc:LNG). // N SET b TO LATLNG(loc:LAT + off_675, loc:LNG + off_225). // NNE SET c TO LATLNG(loc:LAT + off_45, loc:LNG + off_45). // NE SET d TO LATLNG(loc:LAT + off_225, loc:LNG + off_675). // ENE SET e TO LATLNG(loc:LAT, LOC:LNG + off_90). // E SET f TO LATLNG(loc:LAT - off_225, loc:LNG + off_675). // ESE SET g TO LATLNG(loc:LAT - off_45, loc:LNG + off_45). // SE SET h TO LATLNG(loc:LAT - off_675, loc:LNG + off_225). // SSE SET i TO LATLNG(loc:LAT - off_90, loc:LNG). // S SET j TO LATLNG(loc:LAT - off_675, loc:LNG - off_225). // SSW SET k TO LATLNG(loc:LAT - off_45, loc:LNG - off_45). // SW SET l TO LATLNG(loc:LAT - off_225, loc:LNG - off_675). // WSW SET m TO LATLNG(loc:LAT, loc:LNG - off_90). // W SET n TO LATLNG(loc:LAT + off_225, loc:LNG - off_675). // WNW SET o TO LATLNG(loc:LAT + off_45, loc:LNG - off_45). // NW SET p TO LATLNG(loc:LAT + off_675, loc:LNG - off_225). // NNW SET options TO LIST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER point. SET slope TO ABS(ARCTAN2(point:TERRAINHEIGHT - SHIP:ALTITUDE, 100)). IF slope < 15 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION ANGLE_IS_REASONABLE { PARAMETER point, goal. SET angle TO ABS(goal:BEARING - point:BEARING). IF angle < 60 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_SAFE(o) { IF ANGLE_IS_REASONABLE(o, goal) { SET nextpoint TO LATLNG(o:LAT, o:LNG). RETURN nextpoint. } } } } FUNCTION DRIVE_TO { PARAMETER point. LOCK turnlimit TO MIN(1, 1.5 / GROUNDSPEED). // Scale the // turning radius // based on current speed SET loopTime TO 0.01. SET loopEndTime TO TIME:SECONDS. SET eWheelThrottle TO 0. // Error between target speed and actual speed SET iWheelThrottle TO 0. // Accumulated speed error SET wtVAL TO 0. //Wheel Throttle Value SET eSteer TO 0. // Steering error SET kTurn TO 0. //Wheel turn value. SET targetspeed TO 0. //Cruise control starting speed SET targetHeading TO 90. //Used for autopilot steering SET NORTHPOLE TO LATLNG( 90, 0). //Reference heading CLEARSCREEN. PRINT("Activate action group 10 to begin driving."). ON AG10 { SET runmode TO 0. } UNTIL runmode = -1 { IF SHIP:SENSORS:LIGHT < 0.75 { LIGHTS ON. } ELSE { LIGHTS OFF. } IF runmode = 0 { //Update the compass: // I want the heading to match the navball // and be out of 360' instead of +/-180' // I do this by judging the heading relative // to a latlng set to the north pole IF NORTHPOLE:BEARING <= 0 { SET cHeading TO ABS(NORTHPOLE:BEARING). } ELSE { SET cHeading TO (180 - NORTHPOLE:BEARING) + 180. } IF targetHeading > 360 { SET targetHeading TO targetHeading - 360. } ELSE IF targetHeading < 0 { SET targetHeading TO targetHeading + 360. } BRAKES OFF. SET eWT TO targetSpeed - GROUNDSPEED. SET iWT TO MIN(1, MAX(-1, iWheelThrottle + (eWheelThrottle * loopTime))). SET wtVAL TO MIN(1, MAX(-1, eWT + iWT)). SET eSteer TO targetHeading - cHeading. IF eSteer > 180 { SET eSteer TO eSteer - 360. } SET desiredSteering TO -eSteer / 10. SET kTurn TO MIN(1, MAX(-1, desiredSteering)) * turnLimit. } SET SHIP:CONTROL:WHEELTHROTTLE TO wtVAL. SET SHIP:CONTROL:WHEELSTEER TO kTurn. SET loopTime TO TIME:SECONDS - loopEndTime. SET loopEndTime TO TIME:SECONDS. IF ARRIVED(SHIP:GEOPOSITION, point:GEOPOSITION) { SET runmode TO -1. } } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. NOTIFY("Arrived at waypoint. Setting next."). } SET_GOAL(hdg). UNTIL ARRIVED(SHIP:GEOPOSITION, goal) { POPULATE(). DECIDE(options, goal). DRIVE_TO(nextPoint). } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. NOTIFY("Arrived at goal! Shutting down."). FOR ants IN SHIP:PARTSNAMED("rtLongAntenna2") { ants:GETMODULE("ModuleAnimateGeneric"):DOEVENT("Extend"). } LIGHTS ON. SHUTDOWN.
-
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
Where would I find the error log for kOS? Do I need to change any settings? -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
@LAZYGLOBAL OFF. PARAMETER hdg, numberOfLengths. //use to find the initial bearing for the shortest path around a sphere from... FUNCTION CIRCLE_BEARING { PARAMETER p1, //...this point... p2. //...to this point. RETURN MOD(360 + ARCTAN2(SIN(p2:LNG - p1:LNG) * COS(p2:LAT), COS(p1:LAT) * SIN(p2:LAT) - SIN(p1:LAT) * COS(p2:LAT) * COS(p2:LNG - p1:LNG)), 360). } //use to find where you will end up if you travel from... FUNCTION CIRCLE_DESTINATION { PARAMETER p1, //...this point... b, // ...with this as your intitial bearing... d, // ...for this distance... r. // ...around a sphere of this radious. LOCAL lat IS ARCSIN(SIN(p1:LAT)*COS((d*180)/(r*CONSTANT:PI))+COS(p1:LAT)*SIN((d*180)/(r*CONSTANT:PI))*COS(b)). LOCAL lng IS 0. IF ABS(lat) <> 90 { SET lng TO p1:LNG+ARCTAN2(SIN(b)*SIN((d*180)/(r*CONSTANT:PI))*COS(p1:LAT),COS((d*180)/(r*CONSTANT:PI)) - SIN(p1:LAT)*SIN(lat)). } RETURN LATLNG(lat,lng). } //use to find the distance from... FUNCTION CIRCLE_DISTANCE { PARAMETER p1, //...this point... p2, //...to this point... radius. //...around a body of this radius. (note: if you are flying you may want to use ship:body:radius + altitude). LOCAL A IS SIN((p1:LAT - p2:LAT) / 2)^2 + COS(p1:LAT) * COS(p2:LAT) * SIN((p1:LNG-p2:LNG) / 2)^2. RETURN r * CONSTANT():PI * ARCTAN2(SQRT(A), SQRT(1 - A)) / 90. } //use to find the mid point on the outside of a sphere between... FUNCTION CIRCLE_MIDPOINT { PARAMETER p1, //...this point... p2. //...and this point. LOCAL A IS COS(p2:LAT) * COS(p2:LNG - p1:LNG). LOCAL B IS COS(p2:LAT) * SIN(p2:LNG - p1:LNG). RETURN LATLNG(ARCTAN2(SIN(p1:LAT) + SIN(p2:LAT), SQRT((COS(p1:LAT) + A)^2 + B^2)), p1:LNG+ARCTAN2(B, COS(p1:LAT) + A)). } FUNCTION THERE_YET { PARAMETER goal. IF CIRCLE_DISTANCE(point, goal, BODY:RADIUS) <= 20 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION POPULATE { SET off_90 TO ((360 * 100) / (CONSTANT:PI * BODY:RADIUS * 2)). SET off_675 TO off_90 * SIN(67.5). SET off_45 TO off_90 * SIN(45). SET off_225 TO off_90 * SIN(22.5). SET a TO LATLNG(SHIP:GEOPOSITION:LAT + off_90, SHIP:GEOPOSITION:LNG). // North SET b TO LATLNG(SHIP:GEOPOSITION:LAT + off_675, SHIP:GEOPOSITION:LNG + off_225). // North-northeast SET c TO LATLNG(SHIP:GEOPOSITION:LAT + off_45, SHIP:GEOPOSITION:LNG + off_45). // Northeast SET d TO LATLNG(SHIP:GEOPOSITION:LAT + off_225, SHIP:GEOPOSITION:LNG + off_675). // East-northeast SET e TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG + off_90). // East SET f TO LATLNG(SHIP:GEOPOSITION:LAT - off_225, SHIP:GEOPOSITION:LNG + off_675). // East-southeast SET g TO LATLNG(SHIP:GEOPOSITION:LAT - off_45, SHIP:GEOPOSITION:LNG + off_45). // Southeast SET h TO LATLNG(SHIP:GEOPOSITION:LAT - off_675, SHIP:GEOPOSITION:LNG + off_225). // South-southeast SET i TO LATLNG(SHIP:GEOPOSITION:LAT - off_90, SHIP:GEOPOSITION:LNG). // South SET j TO LATLNG(SHIP:GEOPOSITION:LAT - off_675, SHIP:GEOPOSITION:LNG - off_225). // South-southwest SET k TO LATLNG(SHIP:GEOPOSITION:LAT - off_45, SHIP:GEOPOSITION:LNG - off_45). // Southwest SET l TO LATLNG(SHIP:GEOPOSITION:LAT - off_225, SHIP:GEOPOSITION:LNG - off_675). // West-southwest SET m TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG - off_90). // West SET n TO LATLNG(SHIP:GEOPOSITION:LAT + off_225, SHIP:GEOPOSITION:LNG - off_675). // West-northwest SET o TO LATLNG(SHIP:GEOPOSITION:LAT + off_45, SHIP:GEOPOSITION:LNG - off_45). // Northwest SET p TO LATLNG(SHIP:GEOPOSITION:LAT + off_675, SHIP:GEOPOSITION:LNG - off_225). // North-northwest SET options TO LIST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER point. SET loc TO GEOPOSITION(point:LATITUDE, point:LONGITUDE). SET curPos TO SHIP:GEOPOSITION. SET slope TO ABS(ARCTAN2((loc:TERRAINHEIGHT - curPos:TERRAINHEIGHT), 100)). IF slope < 15 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION BEARING_IS_REASONABLE { PARAMETER point, goal. SET brg TO ABS(goal:BEARING - point:BEARING). IF brg < 60 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_SAFE(o) AND BEARING_IS_REASONABLE(point, goal) { SET nextPoint TO LATLNG(o:LAT, o:LNG). RETURN nextPoint. } } } FUNCTION DRIVE_TO { PARAMETER point. SET spd TO 5. SET loopT TO 0.01. SET loopEndT TO TIME:SECONDS. UNTIL arrived(point) { // PI controller for speed SET pWT TO spd - GROUNDSPEED. SET iWT TO MIN(1, MAX(-1, iWT + (pWT * loopT))). SET wtVal TO pWT + iWT. // Proportional control for heading SET pSteer TO COMPASS_FOR(SHIP) - point:HEADING. SET steerVal TO (pSteer / 180). // Now write the outputs to the physical systems. LOCK WHEELTHROTTLE TO wtVal. LOCK WHEELSTEER TO steerVal. SET loopT TO TIME:SECONDS - loopEndT. SET loopEndT TO TIME:SECONDS. } } GLOBAL v IS SHIP:ALTITUDE. GLOBAL r IS BODY:RADIUS. GLOBAL point IS SHIP:GEOPOSITION. GLOBAL radioHorizon IS SQRT((R+v)^2 - (R^2)). GLOBAL dist IS (360 * (0.95 * radioHorizon * numberOfLengths)) / (2 * CONSTANT:PI * BODY:RADIUS). GLOBAL goal IS CIRCLE_DESTINATION(point, hdg, dist, R). UNTIL THERE_YET(goal) { POPULATE(). DECIDE_NEXT(options, goal). DRIVE_TO(nextPoint). WAIT 5. BRAKES OFF. } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. I'm stumped... Can you give me any feedback as to how to get this to work? To test it, just put the script on a generic rover and give the kOS terminal the command "RUN autonav(270,1). -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
It drives in circles. Also, I made a new version, but it won't run at all... The error it gives me is "the given key is not in the dictionary". @LAZYGLOBAL OFF. PARAMETER hdg, numberOfLengths. //use to find the initial bearing for the shortest path around a sphere from... FUNCTION CIRCLE_BEARING { PARAMETER p1, //...this point... p2. //...to this point. RETURN MOD(360 + ARCTAN2(SIN(p2:LNG - p1:LNG) * COS(p2:LAT), COS(p1:LAT) * SIN(p2:LAT) - SIN(p1:LAT) * COS(p2:LAT) * COS(p2:LNG - p1:LNG)), 360). } //use to find where you will end up if you travel from... FUNCTION CIRCLE_DESTINATION { PARAMETER p1, //...this point... b, // ...with this as your intitial bearing... d, // ...for this distance... radius. // ...around a sphere of this radious. LOCAL lat IS ARCSIN(SIN(p1:LAT)*COS((d*180)/(radius*CONSTANT():PI))+COS(p1:LAT)*SIN((d*180)/(radius*CONSTANT():PI))*COS(b)). LOCAL lng IS 0. IF ABS(lat) <> 90 { SET lng TO p1:LNG+ARCTAN2(SIN(b)*SIN((d*180)/(radius*CONSTANT():PI))*COS(p1:LAT),COS((d*180)/(radius*CONSTANT():PI)) - SIN(p1:LAT)*SIN(lat)). } RETURN LATLNG(lat,lng). } //use to find the distance from... FUNCTION CIRCLE_DISTANCE { PARAMETER p1, //...this point... p2, //...to this point... radius. //...around a body of this radius. (note: if you are flying you may want to use ship:body:radius + altitude). LOCAL A IS SIN((p1:LAT - p2:LAT) / 2)^2 + COS(p1:LAT) * COS(p2:LAT) * SIN((p1:LNG-p2:LNG) / 2)^2. RETURN radius * CONSTANT():PI * ARCTAN2(SQRT(A), SQRT(1 - A)) / 90. } //use to find the mid point on the outside of a sphere between... FUNCTION CIRCLE_MIDPOINT { PARAMETER p1, //...this point... p2. //...and this point. LOCAL A IS COS(p2:LAT) * COS(p2:LNG - p1:LNG). LOCAL B IS COS(p2:LAT) * SIN(p2:LNG - p1:LNG). RETURN LATLNG(ARCTAN2(SIN(p1:LAT) + SIN(p2:LAT), SQRT((COS(p1:LAT) + A)^2 + B^2)), p1:LNG+ARCTAN2(B, COS(p1:LAT) + A)). } FUNCTION THERE_YET { PARAMETER goal. IF CIRCLE_DISTANCE(point, goal, BODY:RADIUS) <= 20 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION POPULATE { SET off_90 TO ((360 * 100) / (CONSTANT:PI * BODY:RADIUS * 2)). SET off_675 TO off_90 * SIN(67.5). SET off_45 TO off_90 * SIN(45). SET off_225 TO off_90 * SIN(22.5). SET a TO LATLNG(SHIP:GEOPOSITION:LAT + off_90, SHIP:GEOPOSITION:LNG). // North SET b TO LATLNG(SHIP:GEOPOSITION:LAT + off_675, SHIP:GEOPOSITION:LNG + off_225). // North-northeast SET c TO LATLNG(SHIP:GEOPOSITION:LAT + off_45, SHIP:GEOPOSITION:LNG + off_45). // Northeast SET d TO LATLNG(SHIP:GEOPOSITION:LAT + off_225, SHIP:GEOPOSITION:LNG + off_675). // East-northeast SET e TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG + off_90). // East SET f TO LATLNG(SHIP:GEOPOSITION:LAT - off_225, SHIP:GEOPOSITION:LNG + off_675). // East-southeast SET g TO LATLNG(SHIP:GEOPOSITION:LAT - off_45, SHIP:GEOPOSITION:LNG + off_45). // Southeast SET h TO LATLNG(SHIP:GEOPOSITION:LAT - off_675, SHIP:GEOPOSITION:LNG + off_225). // South-southeast SET i TO LATLNG(SHIP:GEOPOSITION:LAT - off_90, SHIP:GEOPOSITION:LNG). // South SET j TO LATLNG(SHIP:GEOPOSITION:LAT - off_675, SHIP:GEOPOSITION:LNG - off_225). // South-southwest SET k TO LATLNG(SHIP:GEOPOSITION:LAT - off_45, SHIP:GEOPOSITION:LNG - off_45). // Southwest SET l TO LATLNG(SHIP:GEOPOSITION:LAT - off_225, SHIP:GEOPOSITION:LNG - off_675). // West-southwest SET m TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG - off_90). // West SET n TO LATLNG(SHIP:GEOPOSITION:LAT + off_225, SHIP:GEOPOSITION:LNG - off_675). // West-northwest SET o TO LATLNG(SHIP:GEOPOSITION:LAT + off_45, SHIP:GEOPOSITION:LNG - off_45). // Northwest SET p TO LATLNG(SHIP:GEOPOSITION:LAT + off_675, SHIP:GEOPOSITION:LNG - off_225). // North-northwest SET options TO LIST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p). RETURN options. } FUNCTION SLOPE_IS_SAFE { PARAMETER point. SET loc TO GEOPOSITION(point:LATITUDE, point:LONGITUDE). SET curPos TO SHIP:GEOPOSITION. SET slope TO ABS(ARCTAN2((loc:TERRAINHEIGHT - curPos:TERRAINHEIGHT), 100)). IF slope < 15 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION BEARING_IS_REASONABLE { PARAMETER point, goal. SET brg TO ABS(goal:BEARING - point:BEARING). IF brg < 60 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_SAFE(o) AND BEARING_IS_REASONABLE(point, goal) { SET nextPoint TO LATLNG(o:LAT, o:LNG). RETURN nextPoint. } } } FUNCTION DRIVE_TO { PARAMETER point. SET spd TO 5. SET loopT TO 0.01. SET loopEndT TO TIME:SECONDS. UNTIL arrived(point) { SET pWT TO spd - GROUNDSPEED. SET iWT TO MIN(1, MAX(-1, iWT + (pWT * loopT))). LOCK WHEELTHROTTLE TO pWT + iWT. SET pSteer TO COMPASS_FOR(SHIP) - point:HEADING. LOCK WHEELSTEER TO (pSteer / 180). SET loopT TO TIME:SECONDS - loopEndT. SET loopEndT TO TIME:SECONDS. } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. } SET h TO SHIP:ALTITUDE. SET R TO BODY:RADIUS. SET point TO SHIP:GEOPOSITION. SET radioHorizon TO SQRT((R+h)^2 - (R^2)). SET dist TO (360 * (radioHorizon * numberOfLengths)) / (2 * CONSTANT:PI * BODY:RADIUS). SET goal TO CIRCLE_DESTNATION(point, hdg, dist, R). UNTIL arrived(goal) { POPULATE(). DECIDE_NEXT(options, goal). DRIVE_TO(nextPoint). WAIT 5. BRAKES OFF. } LOCK WHEELSTEER TO 0. LOCK WHEELTHROTTLE TO -1. WAIT UNTIL GROUNDSPEED < 1. UNLOCK ALL. BRAKES ON. -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
How do I move this question to the kOS thread? -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
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. -
Gah! I don't know what I did, but now it crashes KSP... time to start over... Can someone help me develop this? I need a kOS program that takes a LATLNG and iteratively navigates to it. Steps of the iteration:
-
UPDATE: Found the bug! // Auto Nav // Takes a LATLNG() of a goal, and iteratively navigates to it. PARAMETER goal. FUNCTION POPULATE { SET pos TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG). SET a TO 360000/(2*CONSTANT:PI*BODY:RADIUS). // 10m in any cardinal direction SET b TO SIN(45)*a. SET oA TO LATLNG(pos:LAT + a, pos:LNG). // North SET oB TO LATLNG(pos:LAT + B, pos:LNG + b). // Northeast SET oC TO LATLNG(pos:LAT, pos:LNG + a). // East SET oD TO LATLNG(pos:LAT - b, pos:LNG + b). // Southeast SET oE TO LATLNG(pos:LAT - a, pos:LNG). // South SET oF TO LATLNG(pos:LAT - b, pos:LNG - b). // Southwest SET oG TO LATLNG(pos:LAT, pos:LNG - a). //West SET oH TO LATLNG(pos:LAT + b, pos:LNG - b). // Northwest SET options TO LIST(oA, oB, oC, oD, oE, oF, oG, oH). RETURN options. } FUNCTION SLOPE_IS_OK { PARAMETER point. SET location TO LATLNG(point:LAT, point:LNG). SET slope TO ABS(ARCTAN2((location:TERRAINHEIGHT - SHIP:ALTITUDE), 10)). IF slope < 11.25 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION ANGLE_IS_OK { PARAMETER point, goal. SET angle TO ABS(goal:BEARING - point:BEARING). IF angle < 45 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_OK(o) AND ANGLE_IS_OK(goal, o) { SET nextPoint TO LATLNG(o:LAT, o:LNG). RETURN nextPoint. BREAK. } ELSE { // Just keep swimming... } } } FUNCTION DRIVE { PARAMETER waypt. CLEARSCREEN. SET spd TO 10. SET hdg TO waypt:HEADING. SET loopT TO 0.01. SET loopEndT TO TIME:SECONDS. SET pWT TO 0. SET iWT TO 0. SET dWT TO 0. SET lastPWT TO 0. SET eSteer TO 0. SET dSteer TO 0. SET lastESteer TO 0. SET wtVal TO 0. SET NORTHPOLE TO LATLNG(90,0). SET runmode TO 0. IF waypt:DISTANCE < 5 { BRAKES ON. SET runmode TO -1. } UNTIL runmode = -1 { IF NORTHPOLE:BEARING <= 0 { set cHdg TO ABS(NORTHPOLE:BEARING). } ELSE { SET cHdg TO (180 - NORTHPOLE:BEARING) + 180. } IF runmode = 0 { SET pWT TO spd - GROUNDSPEED. SET iWT TO MIN(1, MAX(-1, iWT + (pWT * loopT))). SET dWT TO ((pWT - lastPWT) / (loopEndT - loopT)). SET wtVal TO MIN(1, MAX(-1, pWT + iWT + dWT)). SET eSteer TO (hdg - cHdg) / 180. SET dSteer TO ((eSteer - lastESteer)/(loopEndT - loopT)). SET steerVal TO -eSteer + dSteer. SET SHIP:CONTROL:WHEELTHROTTLE TO wtVal. SET SHIP:CONTROL:WHEELSTEER TO steerVal. SET lastPWT TO pWT. SET lastESteer TO eSteer. SET loopT TO TIME:SECONDS - loopEndT. SET loopEndT TO TIME:SECONDS. } PRINT("pWT: " + pWT) AT (2, 5). PRINT("iWT: " + iWT) AT (2, 6). PRINT("dWT: " + dWT) AT (2,7). PRINT("eSteer: " + eSteer) AT (2, 9). PRINT("steerVal: " + steerVal) AT (2,10). } } UNTIL goal:DISTANCE < 5 { POPULATE(). DECIDE_NEXT(options, goal). DRIVE(nextPoint). BRAKES ON. WAIT 5. BRAKES OFF. } BRAKES ON.
-
Ok, fixed the driving-in-circles thing. Now it just drives backward and doesn't control the steering or throttle at all! I think the decision-making algorithm works, though... // Auto Nav // Takes a LATLNG() of a goal, and iteratively navigates to it. PARAMETER goal. GEAR OFF. LOCK THROTTLE TO 0. SAS OFF. RCS OFF. BRAKES ON. FUNCTION POPULATE { SET pos TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG). SET a TO (360 * 1000)/(2*CONSTANT:PI*BODY:RADIUS). // 10m in any cardinal direction SET b TO SIN(45)*a. SET oA TO LATLNG((pos:LAT + a), (pos:LNG)). // North SET oB TO LATLNG((pos:LAT + b), (pos:LNG + b)). // Northeast SET oC TO LATLNG((pos:LAT), (pos:LNG + a)). // East SET oD TO LATLNG((pos:LAT - b), (pos:LNG + b)). // Southeast SET oE TO LATLNG((pos:LAT - a), (pos:LNG)). // South SET oF TO LATLNG((pos:LAT - b), (pos:LNG - b)). // Southwest SET oG TO LATLNG((pos:LAT), (pos:LNG - a)). //West SET oH TO LATLNG((pos:LAT + b), (pos:LNG - b)). // Northwest SET options TO LIST(oA, oB, oC, oD, oE, oF, oG, oH). RETURN options. } FUNCTION SLOPE_IS_OK { PARAMETER point. SET location TO LATLNG(point:LAT, point:LNG). SET slope TO ABS(ARCTAN2((location:TERRAINHEIGHT - SHIP:ALTITUDE), 10)). IF slope < 11.25 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION ANGLE_IS_OK { PARAMETER point, goal. SET angle TO ABS(goal:BEARING - point:BEARING). IF angle < 45 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_OK(o) AND ANGLE_IS_OK(goal, o) { SET nextPoint TO LATLNG(o:LAT, o:LNG). RETURN nextPoint. BREAK. } ELSE { // Just keep swimming... } } } FUNCTION DRIVE { PARAMETER waypt. SET spd TO 5. SET loopT TO 0.01. SET loopEndT TO TIME:SECONDS. SET eWT TO 0. SET iWT TO 0. SET wtVAL TO 0. SET NORTHPOLE TO LATLNG(90,0). SET eSteer TO 0. LOCK turnLimit TO MIN(1, 1.5/GROUNDSPEED). UNTIL waypt:DISTANCE < 2.5 { IF NORTHPOLE:BEARING <= 0 { SET cHead TO ABS(NORTHPOLE:BEARING). } ELSE { SET cHead TO (180 - NORTHPOLE:BEARING) + 180. } SET wtVAL TO MIN(1, MAX(-1, (-eWT + iWT))). SET eSteer TO (hdg - cHead). IF eSteer > 180 { //Make sure the headings make sense SET eSteer TO eSteer - 360. } ELSE IF eSteer < -180 { SET eSteer TO eSteer + 360. } IF spd - GROUNDSPEED > spd + spd * 0.1 // We're too fast! { LOCK THROTTLE TO -1. } ELSE IF GROUNDSPEED < spd - spd * 0.1 { LOCK THROTTLE TO 1. } SET desiredSteering TO -eSteer / 10. set kturn to min(1, max( -1, desiredSteering)). SET SHIP:CONTROL:WHEELSTEER TO kTurn. PRINT("Distance to waypoint: " + ROUND(waypt:DISTANCE, 2)) AT (2, 21). PRINT("Wheel Throttle: " + wtVAL) AT (2,22). SET loopT TO TIME:SECONDS - loopEndT. SET loopEndT TO TIME:SECONDS. } } UNTIL goal:DISTANCE < 50 { IF SHIP:SENSORS:LIGHT < 0.75 { LIGHTS ON. } ELSE { LIGHTS OFF. } CLEARSCREEN. POPULATE(). PRINT("=====Autonavigation v1.0=====") AT (0,2). PRINT("Populating options...") AT (2,5). WAIT 1. PRINT("Options: " + ROUND(oA:LAT, 5) + ", " + ROUND(oA:LNG, 2)) AT (2,10). PRINT(ROUND(oB:LAT, 5) + ", " + ROUND(oB:LNG, 2)) AT (11,11). PRINT(ROUND(oC:LAT, 5) + ", " + ROUND(oC:LNG, 2)) AT (11,12). PRINT(ROUND(oD:LAT, 5) + ", " + ROUND(oD:LNG, 2)) AT (11,13). PRINT(ROUND(oE:LAT, 5) + ", " + ROUND(oE:LNG, 2)) AT (11,14). PRINT(ROUND(oF:LAT, 5) + ", " + ROUND(oF:LNG, 2)) AT (11,15). PRINT(ROUND(oG:LAT, 5) + ", " + ROUND(oG:LNG, 2)) AT (11,16). PRINT(ROUND(oH:LAT, 5) + ", " + ROUND(oH:LNG, 2)) AT (11,17). WAIT 1. DECIDE_NEXT(options, goal). PRINT("Driving to " + "(" + ROUND(nextPoint:LAT,5) + ", " + ROUND(nextPoint:LNG, 5) + ")") AT (2,20). BRAKES OFF. IF nextPoint:BEARING > 20 { LOCK WHEELSTEER TO nextPoint. LOCK WHEELTHROTTLE TO -0.5. WAIT UNTIL nextPoint:BEARING < 30. } DRIVE(nextPoint). BRAKES ON. WAIT 5. BRAKES OFF. } BRAKES ON.
-
I've been having trouble with my roverDriver script again...My rover keeps driving in a left-handed circle probably 20m in radius... I got it to return no errors this time though! Here's my code... // Auto Nav // Takes a LATLNG() of a goal, and iteratively navigates to it. PARAMETER goal. FUNCTION POPULATE { SET pos TO LATLNG(SHIP:GEOPOSITION:LAT, SHIP:GEOPOSITION:LNG). SET a TO 3600/(2*CONSTANT:PI*BODY:RADIUS). // 10m in any cardinal direction SET b TO SIN(45)*a. SET oA TO LATLNG(pos:LAT + a, pos:LNG). // North SET oB TO LATLNG(pos:LAT + B, pos:LNG + b). // Northeast SET oC TO LATLNG(pos:LAT, pos:LNG + a). // East SET oD TO LATLNG(pos:LAT - b, pos:LNG + b). // Southeast SET oE TO LATLNG(pos:LAT - a, pos:LNG). // South SET oF TO LATLNG(pos:LAT - b, pos:LNG - b). // Southwest SET oG TO LATLNG(pos:LAT, pos:LNG - a). //West SET oH TO LATLNG(pos:LAT + b, pos:LNG - b). // Northwest SET options TO LIST(oA, oB, oC, oD, oE, oF, oG, oH). RETURN options. } FUNCTION SLOPE_IS_OK { PARAMETER point. SET location TO LATLNG(point:LAT, point:LNG). SET slope TO ABS(ARCTAN2((location:TERRAINHEIGHT - SHIP:ALTITUDE), 10)). IF slope < 11.25 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION ANGLE_IS_OK { PARAMETER point, goal. SET angle TO ABS(goal:BEARING - point:BEARING). IF angle < 45 { RETURN TRUE. } ELSE { RETURN FALSE. } } FUNCTION DECIDE_NEXT { PARAMETER options, goal. FOR o IN options { IF SLOPE_IS_OK(o) AND ANGLE_IS_OK(goal, o) { SET nextPoint TO LATLNG(o:LAT, o:LNG). RETURN nextPoint. BREAK. } ELSE { // Just keep swimming... } } } FUNCTION DRIVE { PARAMETER waypt. SET spd TO 10. SET hdg TO waypt:HEADING. SET loopT TO 0.01. SET loopEndT TO TIME:SECONDS. SET pWT TO 0. SET iWT TO 0. SET dWT TO 0. SET lastPWT TO 0. SET wtVal TO 0. SET NORTHPOLE TO LATLNG(90,0). SET runmode TO 0. IF waypt:DISTANCE < 5 { BRAKES ON. SET runmode TO -1. } UNTIL runmode = -1 { IF NORTHPOLE:BEARING <= 0 { set cHdg TO ABS(NORTHPOLE:BEARING). } ELSE { SET cHdg TO (180 - NORTHPOLE:BEARING) + 180. } IF runmode = 0 { SET pWT TO spd - GROUNDSPEED. SET iWT TO MIN(1, MAX(-1, iWT + (pWT * loopT))). SET dWT TO ((pWT - lastPWT) / (loopEndT - loopT)). SET wtVal TO MIN(1, MAX(-1, pWT + iWT + dWT)). SET SHIP:CONTROL:WHEELTHROTTLE TO wtVal. SET SHIP:CONTROL:WHEELSTEER TO hdg. SET loopT TO TIME:SECONDS - loopEndT. SET loopEndT TO TIME:SECONDS. } } } UNTIL goal:DISTANCE < 5 { POPULATE(). DECIDE_NEXT(options, goal). DRIVE(nextPoint). BRAKES ON. WAIT 5. BRAKES OFF. } BRAKES ON.
-
Elcano Challenge - Driving Around the Mun with kOS
MAFman replied to magico13's topic in KSP1 Mission Reports
The link to your code is broken... Can you post your raw code in a spoiler tag? -
Request: Dedicated Footprints/Rover Tracks Mod
MAFman replied to LaytheDragon's topic in KSP1 Mods Discussions
YES! This needs more attention!- 3 replies
-
- 3
-
-
- request
- footprints
-
(and 1 more)
Tagged with:
-
I just got done copying Seth Persigehl's rover.ks script to try to adapt it, but I'm stuck...How do I properly implement a PID for both wheel steering and wheel throttle, to maintain constant speed and heading? Also, can someone explain how to use boot scripts to do things like displaying info with HUDTEXT()?
-
RasterPropMonitor does provide a readout if you have VesselView installed. It gives you a realtime schematic view of your ship.
-
I'm working on a rover control library that implements a generic PID library. The thing I'm kind of stuck on is automatic navigation, either dynamic (paying attention to bearing to target and terrain slope), or manual (like Seth Persigehl's rover script).
-
Recently, I got hooked on the kOS mod, which implements coding in KSP. I'm currently developing methods of rover control, both manual and automatic. I'd appreciate any and all ideas / suggestions / whatever!
-
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
A bit too math-y for my overtired mind at the moment, but I like that idea, and I'll have to investigate later! Can you help me update the code so it works in 1.1.4 or whatever the current KSP version is, and so that I can just input a latitude and longitude pair for the waypoints instead of needing to use vessels? -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
I'm trying to think of/design a rover driver script that senses terrain slope in all directions 10m away and continuously navigates to a goal LATLNG() while avoiding steep slopes. Can someone help me with this? -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
Hey, can someone help me create an autonavigation script for rovers? It's supposed to keep speed constant, drive toward waypoints, and (this is the hard part) set its own waypoints intelligently based on traversability and how close each option is to a user-defined target latlng(). Something like DRIVE_TO_GOAL(145.02873, -0.04968). -
[1.3] kOS Scriptable Autopilot System v1.1.3.0
MAFman replied to erendrake's topic in KSP1 Mod Releases
Is it possible to make a kind of Curiosity-like autonav algorithm for rovers? If so, what would be used to measure terrain roughness/height and safety?