CogniPilot

MODELICA LIBRARY · ENGINEERING REFERENCE

function

Control.Multirotor.RateLoop.bodyMoment

Body moment from a proportional body-rate error with gyroscopic feed-forward

Maps a body-rate error into a body moment for a rigid multirotor: M = I (k (omega_sp - omega)) + omega x (I omega). The gyroscopic term is a feed-forward that cancels the rigid-body coupling so the proportional term only has to close the tracking error. Inputs and the returned moment share the vehicle body frame.

Public declarations

Explicit source declarations; dimensions, modifications and defaults are shown as written, without evaluation.

RoleNameTypeDimensions / attributes / defaultDescription
inputangularVelocitySetpointReal[3](each unit = "rad/s")Commanded body angular velocity
inputangularVelocityReal[3](each unit = "rad/s")Measured body angular velocity
inputinertiaReal[3](each unit = "kg.m2")Diagonal body inertia {ixx, iyy, izz}
inputrateGainReal[3](each unit = "1/s")Proportional body-rate bandwidth per axis
inputgyroscopicFeedforwardBoolean= trueAdd omega x (I omega) so the moment holds a spinning body on rate
outputmomentReal[3](each unit = "N.m")Commanded body moment

Modelica declarations and implementation

Show parameters, interfaces and source

Parameters, inputs, outputs, defaults and equations from the source file.

function bodyMoment
    "Body moment from a proportional body-rate error with gyroscopic feed-forward"
    input Real angularVelocitySetpoint[3](each unit = "rad/s")
      "Commanded body angular velocity";
    input Real angularVelocity[3](each unit = "rad/s")
      "Measured body angular velocity";
    input Real inertia[3](each unit = "kg.m2")
      "Diagonal body inertia {ixx, iyy, izz}";
    input Real rateGain[3](each unit = "1/s")
      "Proportional body-rate bandwidth per axis";
    input Boolean gyroscopicFeedforward = true
      "Add omega x (I omega) so the moment holds a spinning body on rate";
    output Real moment[3](each unit = "N.m") "Commanded body moment";
  protected
    Real angularMomentum[3](each unit = "kg.m2/s");
  algorithm
    for axis in 1:3 loop
      moment[axis] := inertia[axis] * rateGain[axis]
        * (angularVelocitySetpoint[axis] - angularVelocity[axis]);
    end for;
    if gyroscopicFeedforward then
      angularMomentum := {
        inertia[1] * angularVelocity[1],
        inertia[2] * angularVelocity[2],
        inertia[3] * angularVelocity[3]};
      moment := moment + cross(angularVelocity, angularMomentum);
    end if;
    annotation(Documentation(info="<html>
      <p>Maps a body-rate error into a body moment for a rigid multirotor:
      <code>M = I (k (omega_sp - omega)) + omega x (I omega)</code>. The
      gyroscopic term is a feed-forward that cancels the rigid-body coupling so
      the proportional term only has to close the tracking error. Inputs and the
      returned moment share the vehicle body frame.</p>
    </html>"));
  end bodyMoment;