Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AttitudeController interface #2881

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 251 additions & 0 deletions doc/source/structures/vessels/attitudecontroller.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
.. _attitudecontroller:

Attitude Controller
===================

A ship usually has various parts that can rotate or translate the ship.
(These include areodynamic control surfaces, engines with gimbaled thrust,
RCS thrusters, reaction wheels, and drain valves.)
Information about these controllers can be read, and in some cases set,
using the ``AttitudeController`` structure defined on this page.

Example::

local controllers is ship:AttitudeControllers.
print(controllers[0]:part + " allows pitch? " + controllers[0]:allowPitch).

.. structure:: AttitudeController

.. list-table:: Members
:header-rows: 1
:widths: 1 1 2

* - Suffix
- Type (units)
- Description

* - :attr:`PART`
- :struct:`Part <Part>`
- The part this controller belongs to.
* - :attr:`MODULE`
- :struct:`PartModule <PartModule>`
- The module this controller belongs to. Will return false if there is no matching module.
* - :attr:`ALLOWPITCH`
- :ref:`Boolean <boolean>`
- Gets or sets wheter this controller should respond to pitch input.
* - :attr:`ALLOWYAW`
- :ref:`Boolean <boolean>`
- Gets or sets wheter this controller should respond to yaw input.
* - :attr:`ALLOWROLL`
- :ref:`Boolean <boolean>`
- Gets or sets wheter this controller should respond to roll input.
* - :attr:`ALLOWX`
- :ref:`Boolean <boolean>`
- Gets or sets wheter this controller should respond to x translation input.
* - :attr:`ALLOWY`
- :ref:`Boolean <boolean>`
- Gets or sets wheter this controller should respond to y translation input.
* - :attr:`ALLOWZ`
- :ref:`Boolean <boolean>`
- Gets or sets wheter this controller should respond to z translation input.
* - :attr:`HASCUSTOMTHROTTLE`
- :ref:`Boolean <boolean>`
- Wheter this controller has a custom throttle input.
* - :attr:`CUSTOMTHROTTLE`
- :ref:`scalar <scalar>` (%)
- The value the custom throttle.
* - :attr:`ROTATIONAUTHORITYLIMITER`
- :ref:`scalar <scalar>` (%)
- The authority limit for rotation.
* - :attr:`TRANSLATIONAUTHORITYLIMITER`
- :ref:`scalar <scalar>` (%)
- The authority limit for translation.
* - :attr:`CONTROLLERTYPE`
- :ref:`string <string>`
- The type of the controller.
* - :attr:`STATUS`
- :ref:`string <string>`
- A string indicating more detailed status about the controller if available.
* - :attr:`RESPONSETIME`
- :ref:`scalar <scalar>`
- The reported responsetime of the controller.
* - :attr:`POSITIVEROTATION`
- :struct:`AttitudeCorrectionResult <AttitudeCorrectionResult>`
- What is expected to happen when you provide a positive value to pitch, yaw, roll.
* - :attr:`NEGATIVEROTATION`
- :struct:`AttitudeCorrectionResult <AttitudeCorrectionResult>`
- What is expected to happen when you provide a negative value to pitch, yaw, roll.
* - :meth:`RESPONSEFOR`
- :struct:`AttitudeCorrectionResult <AttitudeCorrectionResult>`
- What is expected to happen for arbitrary combinations of pitch, yaw, roll, translate x, translate y, translate z, custom throttle.


.. note::

The rotation responses are simplified models of reality and are likely to be off to various degrees.



.. _attitudecontroller_PART:

.. attribute:: AttitudeController:PART

:access: Get
:type: :struct:`Part <Part>`

The part this controller belongs to.

.. _attitudecontroller_MODULE:

.. attribute:: AttitudeController:MODULE

:access: Get only
:type: :struct:`PartModule <PartModule>`

The module this controller belongs to. Will return false if there is no matching module.

.. _attitudecontroller_ALLOWPITCH:

.. attribute:: AttitudeController:ALLOWPITCH

:access: Get/Set
:type: :ref:`boolean <boolean>`

Determines whether this controller is allowed to respond to pitch input. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_ALLOWYAW:

.. attribute:: AttitudeController:ALLOWYAW

:access: Get/Set
:type: :ref:`boolean <boolean>`

Determines whether this controller is allowed to respond to yaw input. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_ALLOWROLL:

.. attribute:: AttitudeController:ALLOWROLL

:access: Get/Set
:type: :ref:`boolean <boolean>`

Determines whether this controller is allowed to respond to roll input. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_ALLOWX:

.. attribute:: AttitudeController:ALLOWX

:access: Get/Set
:type: :ref:`boolean <boolean>`

Determines whether this controller is allowed to respond to translation fore input. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_ALLOWY:

.. attribute:: AttitudeController:ALLOWY

:access: Get/Set
:type: :ref:`boolean <boolean>`

Determines whether this controller is allowed to respond to translation top input. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_ALLOWZ:

.. attribute:: AttitudeController:ALLOWZ

:access: Get/Set
:type: :ref:`boolean <boolean>`

Determines whether this controller is allowed to respond to translation star input. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_HASCUSTOMTHROTTLE:

.. attribute:: AttitudeController:HASCUSTOMTHROTTLE`

:access: Get only
:type: :ref:`boolean <boolean>`

Returns true if this controller has a custom throttle you can modify.

.. _attitudecontroller_CUSTOMTHROTTLE:

.. attribute:: AttitudeController:CUSTOMTHROTTLE

:access: Get/Set
:type: :ref:`scalar <scalar>` (%)

Sets the custom throttle for this controller. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_ROTATIONAUTHORITYLIMITER:

.. attribute:: AttitudeController:ROTATIONAUTHORITYLIMITER

:access: Get/Set
:type: :ref:`scalar <scalar>` (%)

Sets the authority limiter used during rotation. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_TRANSLATIONAUTHORITYLIMITER:

.. attribute:: AttitudeController:TRANSLATIONAUTHORITYLIMITER

:access: Get/Set
:type: :ref:`scalar <scalar>` (%)

Sets the authority limiter used during translation. Not all controller types allow setting this, make sure to check the value after setting it!

.. _attitudecontroller_CONTROLLERTYPE:

.. attribute:: AttitudeController:CONTROLLERTYPE

:access: Get only
:type: :ref:`string <string>`

The type of the attitude controller (ENGINE, DRAINVALVE, ROTOR, RCS, REACTIONWHEEL) or UNKNOWN if the exact type is unknown.

.. _attitudecontroller_STATUS:

.. attribute:: AttitudeController:STATUS

:access: Get only
:type: :ref:`string <string>`

The status of the controller if known. UNKNOWN otherwise.

.. _attitudecontroller_RESPONSETIME:

.. attribute:: AttitudeController:RESPONSETIME

:access: Get only
:type: :ref:`scalar <scalar>`

The reported response time of this controller.

.. _attitudecontroller_POSITIVEROTATION:

.. attribute:: AttitudeController:POSITIVEROTATION

:access: Get only
:type: :struct:`AttitudeCorrectionResult <AttitudeCorrectionResult>`

What is expected to happen when you provide a positive value to pitch, yaw, roll.

.. _attitudecontroller_NEGATIVEROTATION:

.. attribute:: AttitudeController:NEGATIVEROTATION

:access: Get only
:type: :struct:`AttitudeCorrectionResult <AttitudeCorrectionResult>`

What is expected to happen when you provide a negative value to pitch, yaw, roll.

.. _attitudecontroller_RESPONSEFOR:

.. method:: AttitudeController:RESPONSEFOR(pitchYawRollInput, translateXYZInput, throttle)

:parameter pitchYawRollInput: A vector describing user pitch, yaw, roll input between -1 and 1.
:parameter translateXYZInput: A vector describing user fore, top, star translation input between -1 and 1.
:parameter throttle: A scalar representing the custom throttle value in percent.
:type: :struct:`AttitudeCorrectionResult <AttitudeCorrectionResult>`

Simulates the effect of the given input on the ship. This allows computing things like RCS thruster inbalances.
23 changes: 23 additions & 0 deletions doc/source/structures/vessels/attitudecorrectionresult.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.. _attitudecorrectionresult:

Attitude Correction Result
======

When you perform a control action on a ship (yaw, pitch, roll, fore, top, star, throttle) this always has two effects on the ship. Part of the impulse will be be imparted as rotation and part of it will be translation.

.. structure:: AttitudeCorrectionResult

.. list-table:: Members
:header-rows: 1
:widths: 1 1 2

* - Suffix
- Type (units)
- Description

* - :attr:`TORQUE`
- :struct:`Vector <Vector>`
- The torque vector (pitch, roll, yaw).
* - :attr:`TRANSLATION`
- :struct:`Vector <Vector>`
- The translation force (fore, top, star)
8 changes: 8 additions & 0 deletions doc/source/structures/vessels/part.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ These are the generic properties every PART has. You can obtain a list of values
* - :meth:`ALLTAGGEDPARTS`
- :struct:`List` (of :struct:`Part`)
- Search the branch from here down for all parts with a non-blank tag name.
* - :meth:`ATTITUDECONTROLLERS`
- :struct:`List` (of :struct:`AttitudeController`)
- List of Attitude Controllers in this part.


.. attribute:: Part:NAME
Expand Down Expand Up @@ -609,3 +612,8 @@ These are the generic properties every PART has. You can obtain a list of values
branch of the vessel's part tree from the current part down through
its children and its children's children and so on.

.. method:: Vessel::ATTITUDECONTROLLERS()

:return: :struct:`List` of :struct:`AttitudeController` objects

Return all Attitude Controllers in this part.
12 changes: 12 additions & 0 deletions doc/source/structures/vessels/vessel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Vessels are also :ref:`Orbitable<orbitable>`, and as such have all the associate
:attr:`SIZECLASS` :struct:`String` Return the size class for an asteroid-like object
:attr:`ANGULARMOMENTUM` :struct:`Vector` In :ref:`SHIP_RAW <ship-raw>`
:attr:`ANGULARVEL` :struct:`Vector` In :ref:`SHIP_RAW <ship-raw>`
:attr:`MOMENTOFINERTIA` :struct:`Vector` Moment of inertia over pitch, yaw, roll
:attr:`SENSORS` :struct:`VesselSensors` Sensor data
:attr:`LOADED` :struct:`Boolean` loaded into KSP physics engine or "on rails"
:attr:`UNPACKED` :struct:`Boolean` The ship has individual parts unpacked
Expand All @@ -83,6 +84,7 @@ Vessels are also :ref:`Orbitable<orbitable>`, and as such have all the associate
:meth:`PARTSINGROUP(group)` :struct:`List` :struct:`Parts <Part>` by action group
:meth:`MODULESINGROUP(group)` :struct:`List` :struct:`PartModules <PartModule>` by action group
:meth:`ALLTAGGEDPARTS()` :struct:`List` :struct:`Parts <Part>` that have non-blank nametags
:meth:`ATTITUDECONTROLLERS()` :struct:`List` :struct:`Attitude Controllers <AtttitudeController>` present on this ship.
:attr:`CREWCAPACITY` :struct:`scalar` Crew capacity of this vessel
:meth:`CREW()` :struct:`List` all :struct:`CrewMembers <CrewMember>`
:attr:`CONNECTION` :struct:`Connection` Returns your connection to this vessel
Expand Down Expand Up @@ -420,6 +422,10 @@ Vessels are also :ref:`Orbitable<orbitable>`, and as such have all the associate
congruent with how VESSEL:ANGULARMOMENTUM is expressed, and for
backward compatibility with older kOS scripts.

.. attribute:: Vessel:MOMENTOFINERTIA

The moment of inertia of this ship over the pitch, yaw and roll axis.

.. attribute:: Vessel:SENSORS

:type: :struct:`VesselSensors`
Expand Down Expand Up @@ -628,6 +634,12 @@ Vessels are also :ref:`Orbitable<orbitable>`, and as such have all the associate
Return all parts who's nametag isn't blank.
For more information, see :ref:`ship parts and modules <parts and partmodules>`.

.. method:: Vessel::ATTITUDECONTROLLERS()

:return: :struct:`List` of :struct:`AttitudeController` objects

Return all Attitude Controllers on this ship.

.. attribute:: Vessel:CREWCAPACITY

:type: :ref:`scalar <scalar>`
Expand Down
16 changes: 10 additions & 6 deletions src/kOS/Control/SteeringManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ public void UpdateStateVectors()
// TODO: If stock vessel.MOI stops being so weird, we might be able to change the following line
// into this instead. (See the comment on FindMOI()'s header):
// momentOfInertia = shared.Vessel.MOI;
momentOfInertia = FindMoI();
momentOfInertia = SteeringManager.FindMoI(shared.Vessel);

adjustTorque = Vector3d.zero;
measuredTorque = Vector3d.Scale(momentOfInertia, angularAcceleration);
Expand Down Expand Up @@ -681,7 +681,7 @@ public void UpdateTorque()
/// See https://github.com/KSP-KOS/KOS/issues/2814 for why this wrapper around KSP's API call exists.
/// <para />
/// </summary>
void CorrectedGetPotentialTorque(ITorqueProvider tp, out Vector3 pos, out Vector3 neg)
public void CorrectedGetPotentialTorque(ITorqueProvider tp, out Vector3 pos, out Vector3 neg)
{
if (tp is ModuleRCS)
{
Expand Down Expand Up @@ -776,19 +776,23 @@ void CorrectedGetPotentialTorque(ITorqueProvider tp, out Vector3 pos, out Vector
/// would expect "control from here" to do.)
/// </summary>
/// TODO: Check this again after each KSP stock release to see if it's been changed or not.
public Vector3 FindMoI()
public static Vector3 FindMoI(Vessel vessel)
{
var vesTransform = vessel.ReferenceTransform;
var vesRotation = vesTransform.rotation * Quaternion.Euler(-90, 0, 0);
var vesCenterOfMass = vessel.CoMD;

var tensor = Matrix4x4.zero;
Matrix4x4 partTensor = Matrix4x4.identity;
Matrix4x4 inertiaMatrix = Matrix4x4.identity;
Matrix4x4 productMatrix = Matrix4x4.identity;
foreach (var part in Vessel.Parts)
foreach (var part in vessel.Parts)
{
if (part.rb != null)
{
KSPUtil.ToDiagonalMatrix2(part.rb.inertiaTensor, ref partTensor);

Quaternion rot = Quaternion.Inverse(vesselRotation) * part.transform.rotation * part.rb.inertiaTensorRotation;
Quaternion rot = Quaternion.Inverse(vesRotation) * part.transform.rotation * part.rb.inertiaTensorRotation;
Quaternion inv = Quaternion.Inverse(rot);

Matrix4x4 rotMatrix = Matrix4x4.TRS(Vector3.zero, rot, Vector3.one);
Expand All @@ -797,7 +801,7 @@ public Vector3 FindMoI()
// add the part inertiaTensor to the ship inertiaTensor
KSPUtil.Add(ref tensor, rotMatrix * partTensor * invMatrix);

Vector3 position = vesselTransform.InverseTransformDirection(part.rb.position - centerOfMass);
Vector3 position = vesTransform.InverseTransformDirection(part.rb.position - vesCenterOfMass);

// add the part mass to the ship inertiaTensor
KSPUtil.ToDiagonalMatrix2(part.rb.mass * position.sqrMagnitude, ref inertiaMatrix);
Expand Down
1 change: 1 addition & 0 deletions src/kOS/Function/BuildList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public override void Execute(SharedObjects shared)
case "parts":
case "engines":
case "rcs":
case "reactionwheels":
case "sensors":
case "elements":
case "dockingports":
Expand Down
Loading