From fd2acd837e63f4fe894202e7c24aceb3b6183eba Mon Sep 17 00:00:00 2001 From: Dunbaratu Date: Thu, 31 Dec 2015 22:53:21 -0600 Subject: [PATCH] some_documentation_fixes: Fixes #439 #655 #1021 #1236 #1254 #1263 #1278 #1288 #1297 #1299 #1301 #1326 #1340 --- doc/source/bindings.rst | 8 ++ doc/source/commands/flight/cooked.rst | 73 ++++++++++++++++++- doc/source/commands/flight/raw.rst | 9 ++- doc/source/commands/prediction.rst | 15 ++++ doc/source/language/variables.rst | 9 ++- doc/source/library.rst | 24 ++---- .../structures/celestial_bodies/body.rst | 20 ++++- doc/source/structures/misc/kuniverse.rst | 2 +- doc/source/structures/misc/time.rst | 4 - doc/source/structures/vessels/vessel.rst | 58 +++++++++++---- doc/source/tutorials/designpatterns.rst | 2 +- doc/source/tutorials/exenode.rst | 22 +++++- doc/source/tutorials/pidloops.rst | 16 ++++ doc/source/tutorials/quickstart.rst | 36 +++++---- 14 files changed, 240 insertions(+), 58 deletions(-) diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst index 30f7127f9..1ae82974f 100644 --- a/doc/source/bindings.rst +++ b/doc/source/bindings.rst @@ -324,6 +324,14 @@ TIME is the time since the entire saved game campaign started, in the kerbal universe's time. i.e. TIME = 0 means a brand new campaign was just started. +KUNIVERSE +~~~~~~~~~ + +:ref:`Kuniverse ` is a structure that contains many settings that +break the fourth wall a little bit and control the game simulation directly. +The eventual goal is probably to move many of the variables you see listed +below into ``kuniverse``. + Config ~~~~~~ diff --git a/doc/source/commands/flight/cooked.rst b/doc/source/commands/flight/cooked.rst index 219cceeb5..90126c22a 100644 --- a/doc/source/commands/flight/cooked.rst +++ b/doc/source/commands/flight/cooked.rst @@ -17,7 +17,7 @@ In this style of controlling the craft, you do not steer the craft directly, but This sets the main throttle of the ship to *value*. Where *value* is a floating point number between 0.0 and 1.0. A value of 0.0 means the throttle is idle, and a value of 1.0 means the throttle is at maximum. A value of 0.5 means the throttle is at the halfway point, and so on. .. _LOCK STEERING: -.. object:: LOCK STEERING TO value. +.. object:: LOCK STEERING TO value. // value range [0.0 .. 1.0] This sets the direction **kOS** should point the ship where *value* is a :struct:`Vector` or a :ref:`Direction ` created from a :ref:`Rotation ` or :ref:`Heading `: @@ -57,6 +57,77 @@ In this style of controlling the craft, you do not steer the craft directly, but Like all ``LOCK`` expressions, the steering and throttle continually update on their own when using this style of control. If you lock your steering to velocity, then as your velocity changes, your steering will change to match it. Unlike with other ``LOCK`` expressions, the steering and throttle are special in that the lock expression gets executed automatically all the time in the background, while other ``LOCK`` expressions only get executed when you try to read the value of the variable. The reason is that the **kOS** computer is constantly querying the lock expression multiple times per second as it adjusts the steering and throttle in the background. + +.. _LOCK WHEELTHROTTLE: +.. object:: LOCK WHEELTHROTTLE TO value. // value range [-1.0 .. 1.0] + + **(For Rovers)** This is used to control the throttle that is used when + driving a wheeled vehicle on the ground. It is an entirely independent + control from the flight throttle used with ``LOCK THROTTLE`` above. + It is analagous to holding the 'W' (value of +1) or 'S' (value of -1) + key when driving a rover manually under default keybindings. + + ``WHEELTHROTTLE`` allows you to set + a negative value, up to -1.0, while ``THROTTLE`` can't go below zero. + A negative value means you are trying to accelerate in reverse. + + Unlike trying to drive manually, using ``WHEELTHROTTLE`` in kOS does + not cause the torque wheels to engage as well. In stock KSP using + the 'W' or 'S' keys on a rover engages both the wheel driving AND the + torque wheel rotational power. In kOS those two features are + done independantly. + +.. _LOCK WHEELSTEERING: +.. object:: LOCK WHEELSTEERING TO value. + + **(For Rovers)** This is used to tell the rover's cooked steering + where to go. The rover's cooked steering doesn't use nearly as + sophisticated a PID control system as the flight cooked steering + does, but it does usually get the job done, as driving has more + physical effects that help dampen the steering down automatically. + + There are 3 kinds of value understood by WHEELSTEERING: + + - :struct:`GeoCoordinates` - If you lock wheelsteering to a + :ref:`latlng`, that will mean the rover will try to steer in + whichever compass direction will aim at that location. + + - :struct:`Vessel` - If you try to lock wheelsteering to a vessel, + that will mean the rover will try to steer in whichever compass + direction will aim at that vessel. The vessel being aimed at + does not need to be landed. If it is in the sky, the rover will + attempt to aim at a location directly underneath it on the ground. + + - *Scalar Number* - If you try to lock wheelsteering to just a plain + scalar number, that will mean the rover will try to aim at that + compass heading. For example ``lock wheelsteering to 45.`` will + try to drive the rover northeast. + + For more precise control over steering, you can use raw steering to + just directly tell the rover to yaw left and right as it drives and + that will translate into wheel steering provided the vessel is landed + and you have a probe core aiming the right way. + + **A warning about WHEELSTEERING and vertically mounted probe cores**: + + If you built your rover in such a way that the probe core controlling it + is stack-mounted facing up at the sky when the rover is driving, that + will confuse the ``lock WHEELSTEERING`` cooked control mechanism. This + is a common building pattern for KSP players and it seems to work okay + when driving manually, but when driving by a kOS script, the fact that + the vessel's facing is offically pointing up at the sky causes it to + get confused. If you notice that your rover tends to drive in the + correct direction only when on a flat or slight downslope, but then + turns around and around in circles when driving toward the target + requires going up a slope, then this may be exactly what's happening. + When it tilted back, the 'forward' vector aiming up at the sky started + pointing behind it, and the cooked steering thought the rover was + aimed in the opposite direction to the way it was really going. + To fix this problem, either mount your rover probe core facing the + front of the rover, or perform a "control from here" on some forward + facing docking port or something like that to get it to stop thinking + of the sky as "forward". + Unlocking controls ------------------ diff --git a/doc/source/commands/flight/raw.rst b/doc/source/commands/flight/raw.rst index 71738cb7f..354f29182 100644 --- a/doc/source/commands/flight/raw.rst +++ b/doc/source/commands/flight/raw.rst @@ -43,7 +43,14 @@ Raw Flight Controls Reference These "Raw" controls allow you the direct control of flight parameters while the current program is running. .. note:: - The ``MAINTHROTTLE`` requires active engines and, of course, sufficient and appropriate fuel. The rotational controls ``YAW``, ``PITCH`` and ``ROW`` require active reaction wheels with sufficient energy or *RCS* to be ON with properly placed thrusters and appropriate fuel. The translational controls ``FORE``, ``STARBOARD`` and ``TOP`` require *RCS* to be ON with properly placed thrusters and appropriate fuel. + The ``MAINTHROTTLE`` requires active engines and, of course, + sufficient and appropriate fuel. The rotational controls ``YAW``, + ``PITCH`` and ``ROW`` require one of the following: active reaction + wheels with sufficient energy, *RCS* to be ON with properly placed + thrusters and appropriate fuel, or control surfaces with an atmosphere + in which to operate. The translational controls ``FORE``, ``STARBOARD`` + and ``TOP`` only work with *RCS*, and require RCS to be ON with + properly placed thrusters and appropriate fuel. .. list-table:: diff --git a/doc/source/commands/prediction.rst b/doc/source/commands/prediction.rst index cf68049aa..f7ec2b8db 100644 --- a/doc/source/commands/prediction.rst +++ b/doc/source/commands/prediction.rst @@ -44,6 +44,11 @@ These return predicted information about the future position and velocity of an Returns a prediction of where the :struct:`Orbitable` will be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + *Prerequisite:* If you are in a career mode game rather than a + sandbox mode game, This function requires that you have your space + center's buildings advanced to the point where you can make manuever + nodes on the map view, as described in :struct:`Career:CANMAKENODES`. + .. function:: VELOCITYAT(orbitable,time) :param orbitable: A :struct:`Vessel`, :struct:`Body` or other :struct:`Orbitable` object @@ -54,6 +59,11 @@ These return predicted information about the future position and velocity of an Returns a prediction of what the :ref:`Orbitable's ` velocity will be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :struct:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + *Prerequisite:* If you are in a career mode game rather than a + sandbox mode game, This function requires that you have your space + center's buildings advanced to the point where you can make manuever + nodes on the map view, as described in :struct:`Career:CANMAKENODES`. + .. function:: ORBITAT(orbitable,time) :param orbitable: A :Ref:`Vessel `, :struct:`Body` or other :struct:`Orbitable` object @@ -64,6 +74,11 @@ These return predicted information about the future position and velocity of an Returns the :ref:`Orbit patch ` where the :struct:`Orbitable` object is predicted to be at some :ref:`universal Timestamp `. If the :struct:`Orbitable` is a :struct:`Vessel`, and the :struct:`Vessel` has planned :ref:`maneuver nodes `, the prediction assumes they will be executed exactly as planned. + *Prerequisite:* If you are in a career mode game rather than a + sandbox mode game, This function requires that you have your space + center's buildings advanced to the point where you can make manuever + nodes on the map view, as described in :struct:`Career:CANMAKENODES`. + Examples:: //kOS diff --git a/doc/source/language/variables.rst b/doc/source/language/variables.rst index 41e34cf9d..73930192a 100644 --- a/doc/source/language/variables.rst +++ b/doc/source/language/variables.rst @@ -233,7 +233,6 @@ only gets executed if the system needed to pad a missing argument. - .. note:: **Pass By Value** @@ -688,6 +687,14 @@ all variables you use in a declaration somewhere (with the exception of the built-in variables such as THROTTLE, STEERING, SHIP, and so on.) +.. note:: + The @LAZYGLOBAL directive does not affect LOCK statements. + LOCKS are a special case that define new pseudo-functions + when encountered and don't quite work the same way as + SET statements do. Thus even with @LAZYGLOBAL OFF, it's still + possible to make a LOCK statement with a typo in the identifier + name and it will still create the new typo'ed lock that way. + @LAZYGLOBAL Can only exist at the top of your code. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/library.rst b/doc/source/library.rst index 4690b7e66..6f39f9615 100644 --- a/doc/source/library.rst +++ b/doc/source/library.rst @@ -6,9 +6,9 @@ Community Examples Library Starting with version 0.17.0 of kOS, we have decided to support a separate repository of examples and libraries that "live" entirely in kerboscript code only. This is a useful place to find helpful -code written by other users of kOS, some of whom may be members of -the main kOS development team, and some of whom might ber users in the -community. +code written mostly by other users of kOS, some of whom may be members +of the main kOS development team, but most of whom are not and are +just ordinary users of kOS like you. The separate repository is found here: @@ -16,18 +16,10 @@ https://github.com/KSP-KOS/KSLib Some examples of useful things you can find there are: -* A generic all-purpose **PID controller** function: - - * library script: https://github.com/KSP-KOS/KSLib/blob/master/library/lib_pid.ks - * documentation: https://github.com/KSP-KOS/KSLib/blob/master/doc/lib_pid.md - * example https://github.com/KSP-KOS/KSLib/blob/master/examples/example_lib_pid.ks - * A library for getting **navball orientation** information: - - * library script https://github.com/KSP-KOS/KSLib/blob/master/library/lib_navball.ks - * documentation https://github.com/KSP-KOS/KSLib/blob/master/doc/lib_navball.md - * example https://github.com/KSP-KOS/KSLib/blob/master/examples/example_lib_navball.ks - * An example of how to use the :ref:`sasmode ` feature: - - * example https://github.com/KSP-KOS/KSLib/blob/master/examples/example_testsasmode.ks +* A helpful set of routines letting you enumerate over lists, queues, and stacks, using callback delegates. +* An example of a seven-segment display controller. +* A keypad emulator that lets you move a 'finger' cursor around a visual keyboard and type letters. +* A library for drawing chunky lines out of the character cells of the terminal. +* A library routine to help calculate when to launch from the launchpad to match a given target inclination orbit. diff --git a/doc/source/structures/celestial_bodies/body.rst b/doc/source/structures/celestial_bodies/body.rst index 7aebd78bc..fe3105d11 100644 --- a/doc/source/structures/celestial_bodies/body.rst +++ b/doc/source/structures/celestial_bodies/body.rst @@ -55,7 +55,7 @@ All of the main celestial bodies in the game are reserved variable names. The fo :attr:`RADIUS` scalar (m) :attr:`MU` scalar (:math:`m^3 s^{−2}`) :attr:`ATM` :struct:`Atmosphere` - :attr:`ANGULARVEL` :struct:`Direction` in :ref:`SHIP-RAW ` + :attr:`ANGULARVEL` :struct:`Vector` in :ref:`SHIP-RAW ` :attr:`GEOPOSITIONOF` :struct:`GeoCoordinates` in :ref:`SHIP-RAW ` :attr:`ALTITUDEOF` scalar (m) :attr:`SOIRADIUS` scalar (m) @@ -102,7 +102,23 @@ All of the main celestial bodies in the game are reserved variable names. The fo .. attribute:: Body:ANGULARVEL - Despite the name, this is technically not a velocity. It only tells you the axis of rotation, not the speed of rotation around that axis. + Angular velocity of the body's rotation about its axis (its + day) expressed as a vector. + + The direction the angular velocity points is in Ship-Raw orientation, + and represents the axis of rotation. Remember that everything in + Kerbal Space Program uses a *left-handed coordinate system*, which + affects which way the angular velocity vector will point. If you + curl the fingers of your **left** hand in the direction of the rotation, + and stick out your thumb, the thumb's direction is the way the + angular velocity vector will point. + + The magnitude of the vector is the speed of the rotation. + + Note, unlike many of the other parts of kOS, the rotaion speed is + expressed in radians rather than degrees. This is to make it + congruent with how VESSEL:ANGULARMOMENTUM is expressed, and for + backward compatibility with older kOS scripts. .. attribute:: Body:GEOPOSITIONOF diff --git a/doc/source/structures/misc/kuniverse.rst b/doc/source/structures/misc/kuniverse.rst index 80ead12c0..6bb45d332 100644 --- a/doc/source/structures/misc/kuniverse.rst +++ b/doc/source/structures/misc/kuniverse.rst @@ -240,7 +240,7 @@ KUniverse 4th wall methods **** Examples -======== +-------- Switch to an active vessel called "vessel 2":: diff --git a/doc/source/structures/misc/time.rst b/doc/source/structures/misc/time.rst index 8e6df3267..9344588ef 100644 --- a/doc/source/structures/misc/time.rst +++ b/doc/source/structures/misc/time.rst @@ -74,10 +74,6 @@ You can use the TIME special variable to detect whether or not a real physics 't The epoch (time zero) in the KSP game is the time at which you first started the new campaign. All campaign games begin with the planets in precisely the same position and the clock set to zero years, zero days, zero hours, and so on. -.. warning:: - - Beware that the times returned from :struct:`FileInfo` for the time a file was modified or created are NOT in this :struct:`TimeSpan` structure but instead are just raw strings. That is because they represent the time the file was affected in the real world and NOT times taken from the KSP simulation clock. That is a necessity because your files in the Archive exist globally across all multiple saved games. Different saved games won't have synchronized calendars with each other. - .. structure:: TimeSpan diff --git a/doc/source/structures/vessels/vessel.rst b/doc/source/structures/vessels/vessel.rst index bef8b0afb..d3f9233d0 100644 --- a/doc/source/structures/vessels/vessel.rst +++ b/doc/source/structures/vessels/vessel.rst @@ -42,8 +42,8 @@ All vessels share a structure. To get a variable referring to any vessel you can :attr:`MASS` scalar (metric tons) Mass of the ship :attr:`WETMASS` scalar (metric tons) Mass of the ship fully fuelled :attr:`DRYMASS` scalar (metric tons) Mass of the ship with no resources - :attr:`DYNAMICPRESSURE` scalar (kilopascals) Air Pressure surrounding the vessel - :attr:`Q` scalar (kilopascals) Alias name for DYNAMICPRESSURE + :attr:`DYNAMICPRESSURE` scalar (ATM's) Air Pressure surrounding the vessel + :attr:`Q` scalar (ATM's) Alias name for DYNAMICPRESSURE :attr:`VERTICALSPEED` scalar (m/s) How fast the ship is moving "up" :attr:`GROUNDSPEED` scalar (m/s) How fast the ship is moving "horizontally" :attr:`AIRSPEED` scalar (m/s) How fast the ship is moving relative to the air @@ -161,14 +161,18 @@ All vessels share a structure. To get a variable referring to any vessel you can .. attribute:: Vessel:DYNAMICPRESSURE - :type: scalar (kiloPascals, kPa) + :type: scalar (ATM's) :access: Get only Returns what the air pressure is in the atmosphere surrounding the vessel. + The value is returned in units of sea-level Kerbin atmospheres. Many + fomulae expect you to plug in a value expressed in kiloPascals, or + kPA. You can convert this value into kPa by multiplying it by + `constant:ATMtokPa`. .. attribute:: Vessel:Q - :type: scalar (kiloPascals, kPa) + :type: scalar (ATM's) :access: Get only Alias for DYNAMICPRESSURE @@ -243,8 +247,29 @@ All vessels share a structure. To get a variable referring to any vessel you can :type: :struct:`Direction` :access: Get only - Given in :ref:`SHIP_RAW ` reference frame. The vector represents the axis of the rotation, and its magnitude is the angular momentum of the rotation, which varies not only with the speed of the rotation, but also with the angular inertia of the vessel. - + Given in :ref:`SHIP_RAW ` reference frame. The vector + represents the axis of the rotation (in left-handed convention, + not right handed as most physics textbooks show it), and its + magnitude is the angular momentum of the rotation, which varies + not only with the speed of the rotation, but also with the angular + inertia of the vessel. + + Units are expressed in: (Megagrams * meters^2) / (seconds * radians) + + (Normal SI units would use kilograms, but in KSP all masses use a + 1000x scaling factor.) + + **Justification for radians here:** + Unlike the trigonometry functions in kOS, this value uses radians + rather than degrees. The convention of always expressing angular + momentum using a formula that assumes you're using radians is a very + strongly adhered to universal convention, for... reasons. + It's so common that it's often not even explicitly + mentioned in information you may find when doing a web search on + helpful formulae about angular momentum. This is why kOS doesn't + use degrees here. (That an backward compatibility for old scripts. + It's been like this for quite a while.). + .. note:: .. versionchanged:: 0.15.4 @@ -253,16 +278,23 @@ All vessels share a structure. To get a variable referring to any vessel you can .. attribute:: Vessel:ANGULARVEL - :type: :struct:`Direction` - :access: Get only + Angular velocity of the body's rotation about its axis (its + day) expressed as a vector. - Given in :ref:`SHIP_RAW ` reference frame. The vector represents the axis of the rotation, and its magnitude is the speed of that rotation (Presumably in degrees per second? This is not documented in the KSP API and may take some experimentation to discover if it's radians or degrees). + The direction the angular velocity points is in Ship-Raw orientation, + and represents the axis of rotation. Remember that everything in + Kerbal Space Program uses a *left-handed coordinate system*, which + affects which way the angular velocity vector will point. If you + curl the fingers of your **left** hand in the direction of the rotation, + and stick out your thumb, the thumb's direction is the way the + angular velocity vector will point. - .. note:: + The magnitude of the vector is the speed of the rotation. - .. versionchanged:: 0.15.4 - - This has been changed to a vector, as it should have been all along. + Note, unlike many of the other parts of kOS, the rotaion speed is + expressed in radians rather than degrees. This is to make it + congruent with how VESSEL:ANGULARMOMENTUM is expressed, and for + backward compatibility with older kOS scripts. .. attribute:: Vessel:SENSORS diff --git a/doc/source/tutorials/designpatterns.rst b/doc/source/tutorials/designpatterns.rst index a9a4a5de6..cbba1add6 100644 --- a/doc/source/tutorials/designpatterns.rst +++ b/doc/source/tutorials/designpatterns.rst @@ -57,7 +57,7 @@ Here, we introduce IF/ELSE logic into UNTIL loops: STAGE. UNTIL SHIP:ALTITUDE > 20000 { IF SHIP:ALTITUDE > 10000 { - LOCK STEERING TO R(0,0,-90) + HEADING(90,45). + LOCK STEERING TO TO R(0,0,-90) + HEADING(90,45). } IF STAGE:LIQUIDFUEL < 0.1 { STAGE. diff --git a/doc/source/tutorials/exenode.rst b/doc/source/tutorials/exenode.rst index 7bae9c704..efe8a31c7 100644 --- a/doc/source/tutorials/exenode.rst +++ b/doc/source/tutorials/exenode.rst @@ -3,7 +3,7 @@ Advanced Tutorial ================= -Let's try to automate one of the most common tasks in orbital maneuvering - execution of the maneuver node. In this tutorial I'll try to show you how to write a script for precise maneuver node execution. +Let's try to automate one of the most common tasks in orbital maneuvering - execution of the maneuver node. In this tutorial I'll try to show you how to write a script for somewhat precise maneuver node execution. So to start our script we need to get the next available :ref:`maneuver node `:: @@ -17,9 +17,23 @@ Our next step is to calculate how much time our vessel needs to burn at full thr //calculate ship's max acceleration set max_acc to ship:maxthrust/ship:mass. - //now we just need to divide deltav:mag by our ship's max acceleration + // Now we just need to divide deltav:mag by our ship's max acceleration + // to get the estimated time of the burn. + // + // Please note, this is not exactly correct. The real calculation + // needs to take into account the fact that the mass will decrease + // as you lose fuel during the burn. In fact throwing the fuel out + // the back of the engine very fast is the entire reason you're able + // to thrust at all in space. The proper caclulation for this + // can be found easily enough online by searching for the phrase + // "Tsiolkovsky rocket equation". + // This example here will keep it simple for demonstration purposes, + // but if you're going to build a serious node execution script, you + // need to look into the Tsiolkovsky rocket equation to account for + // the change in mass over time as you burn. + // set burn_duration to nd:deltav:mag/max_acc. - print "Estimated burn duration: " + round(burn_duration) + "s". + print "Crude Estimated burn duration: " + round(burn_duration) + "s". So now we have our node's deltav vector, ETA to the node and we calculated our burn duration. All that is left for us to do is wait until we are close to node's ETA less half of our burn duration. But we want to write a universal script, and some of our current and/or future ships can be quite slow to turn, so let's give us some time, 60 seconds, to prepare for the maneuver burn:: @@ -29,7 +43,7 @@ This wait can be tedious and you'll most likely end up warping some time, but we The wait has finished, and now we need to start turning our ship in the direction of the burn:: - set np to lookdirup(nd:deltav, ship:facing:topvector). //points to node, keeping roll the same. + set np to nd:deltav. //points to node, don't care about the roll direction. lock steering to np. //now we need to wait until the burn vector and ship's facing are aligned diff --git a/doc/source/tutorials/pidloops.rst b/doc/source/tutorials/pidloops.rst index 39d9f5cd4..694243e88 100644 --- a/doc/source/tutorials/pidloops.rst +++ b/doc/source/tutorials/pidloops.rst @@ -3,6 +3,22 @@ PID Loops in kOS ================ +.. versionadded:: 0.18.1 + + Note, this is an older tutorial. As of + kOS version 0.18.1 and up, a new :struct:`pidloop` + feature was added to kOS to allow you to use a built-in PID + controller that executes very quickly in the kOS "hardware" + rather than in your script code. You can use it to perform + the work described in detail on this page. However, this + tutorial is still quite important because it walks you through + how a PID controller works and what it's really doing under the + hood. It's probably a good idea to use the built-in + :struct:`pidloop` instead of the program shown here, once you + understand the topic this page describes. However, it's also + a good idea to have a read through this page to get an + understanding of what that built-in feature is really doing. + This tutorial covers how one can implement a `PID loop`_ using kOS. A P-loop, or "proportional feedback loop" was already introduced in the second section of the :ref:`Design Patterns Tutorial `, and that will serve as our starting point. After some code rearrangement, the integral and derivative terms will be added and discussed in turn. Next, a couple extra features will be added to the full PID-loop. Lastly, we'll show a case-study in tuning a full PID loop using the Ziegler-Nichols method. We'll use the LOG method to dump telemetry from KSP into a file and our favorite graphing software to visualize the data. .. _PID loop: http://en.wikipedia.org/wiki/PID_controller diff --git a/doc/source/tutorials/quickstart.rst b/doc/source/tutorials/quickstart.rst index fd53df4a2..80723d17c 100644 --- a/doc/source/tutorials/quickstart.rst +++ b/doc/source/tutorials/quickstart.rst @@ -394,8 +394,10 @@ So for example, HEADING(45,10) would aim northeast, 10 degrees above the horizon Instead of using WAIT UNTIL to pause the script and keep it from exiting, we can use an UNTIL loop to constantly perform actions until a certain condition is met. For example:: + SET MYSTEER TO HEADING(90,90). //90 degrees east and pitched up 90 degrees (straight up) + LOCK STEERING TO MYSTEER. // from now on we'll be able to change steering by just assigning a new value to MYSTEER UNTIL APOAPSIS > 100000 { - LOCK STEERING TO HEADING(90,90). //90 degrees east and pitched up 90 degrees (straight up) + SET MYSTEER TO HEADING(90,90). //90 degrees east and pitched up 90 degrees (straight up) PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). // prints new number, rounded to the nearest integer. //We use the PRINT AT() command here to keep from printing the same thing over and //over on a new line every time the loop iterates. Instead, this will always print @@ -406,6 +408,8 @@ This loop will continue to execute all of its instructions until the apoapsis re We can combine this with IF statements in order to have one main loop that only executes certain chunks of its code under certain conditions. For example:: + SET MYSTEER TO HEADING(90,90). + LOCK STEERING TO MYSTEER. UNTIL SHIP:APOAPSIS > 100000 { //Remember, all altitudes will be in meters, not kilometers //For the initial ascent, we want our steering to be straight @@ -413,11 +417,11 @@ We can combine this with IF statements in order to have one main loop that only IF SHIP:VELOCITY:SURFACE:MAG < 100 { //This sets our steering 90 degrees up and yawed to the compass //heading of 90 degrees (east) - LOCK STEERING TO HEADING(90,90). + SET MYSTEER TO HEADING(90,90). //Once we pass 100m/s, we want to pitch down ten degrees } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 100 AND SHIP:VELOCITY:SURFACE:MAG < 200 { - LOCK STEERING TO HEADING(90,80). + SET MYSTEER TO HEADING(90,80). PRINT "Pitching to 80 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). }. @@ -458,6 +462,8 @@ Putting this into your script, it should look like this:: //than 100km. Each cycle, it will check each of the IF //statements inside and perform them if their conditions //are met + SET MYSTEER TO HEADING(90,90). + LOCK STEERING TO MYSTEER. // from now on we'll be able to change steering by just assigning a new value to MYSTEER UNTIL SHIP:APOAPSIS > 100000 { //Remember, all altitudes will be in meters, not kilometers //For the initial ascent, we want our steering to be straight @@ -465,11 +471,11 @@ Putting this into your script, it should look like this:: IF SHIP:VELOCITY:SURFACE:MAG < 100 { //This sets our steering 90 degrees up and yawed to the compass //heading of 90 degrees (east) - LOCK STEERING TO HEADING(90,90). + SET MYSTEER TO HEADING(90,90). //Once we pass 100m/s, we want to pitch down ten degrees } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 100 { - LOCK STEERING TO HEADING(90,80). + SET MYSTEER TO HEADING(90,80). PRINT "Pitching to 80 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). }. @@ -524,6 +530,8 @@ Copy this into your script and run it. It should take you nearly to orbit:: //than 100km. Each cycle, it will check each of the IF //statements inside and perform them if their conditions //are met + SET MYSTEER TO HEADING(90,90). + LOCK STEERING TO MYSTEER. // from now on we'll be able to change steering by just assigning a new value to MYSTEER UNTIL SHIP:APOAPSIS > 100000 { //Remember, all altitudes will be in meters, not kilometers //For the initial ascent, we want our steering to be straight @@ -531,11 +539,11 @@ Copy this into your script and run it. It should take you nearly to orbit:: IF SHIP:VELOCITY:SURFACE:MAG < 100 { //This sets our steering 90 degrees up and yawed to the compass //heading of 90 degrees (east) - LOCK STEERING TO HEADING(90,90). + SET MYSTEER TO HEADING(90,90). //Once we pass 100m/s, we want to pitch down ten degrees } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 100 AND SHIP:VELOCITY:SURFACE:MAG < 200 { - LOCK STEERING TO HEADING(90,80). + SET MYSTEER TO HEADING(90,80). PRINT "Pitching to 80 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). @@ -543,39 +551,39 @@ Copy this into your script and run it. It should take you nearly to orbit:: //is within a 100m/s block and adjusts our heading down another //ten degrees if so } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 200 AND SHIP:VELOCITY:SURFACE:MAG < 300 { - LOCK STEERING TO HEADING(90,70). + SET MYSTEER TO HEADING(90,70). PRINT "Pitching to 70 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 300 AND SHIP:VELOCITY:SURFACE:MAG < 400 { - LOCK STEERING TO HEADING(90,60). + SET MYSTEER TO HEADING(90,60). PRINT "Pitching to 60 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 400 AND SHIP:VELOCITY:SURFACE:MAG < 500 { - LOCK STEERING TO HEADING(90,50). + SET MYSTEER TO HEADING(90,50). PRINT "Pitching to 50 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 500 AND SHIP:VELOCITY:SURFACE:MAG < 600 { - LOCK STEERING TO HEADING(90,40). + SET MYSTEER TO HEADING(90,40). PRINT "Pitching to 40 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 600 AND SHIP:VELOCITY:SURFACE:MAG < 700 { - LOCK STEERING TO HEADING(90,30). + SET MYSTEER TO HEADING(90,30). PRINT "Pitching to 30 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 700 AND SHIP:VELOCITY:SURFACE:MAG < 800 { - LOCK STEERING TO HEADING(90,11). + SET MYSTEER TO HEADING(90,11). PRINT "Pitching to 20 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16). //Beyond 800m/s, we can keep facing towards 10 degrees above the horizon and wait //for the main loop to recognize that our apoapsis is above 100km } ELSE IF SHIP:VELOCITY:SURFACE:MAG >= 800 { - LOCK STEERING TO HEADING(90,10). + SET MYSTEER TO HEADING(90,10). PRINT "Pitching to 10 degrees" AT(0,15). PRINT ROUND(SHIP:APOAPSIS,0) AT (0,16).