Source code for udaan.control.quadrotor_cspayload.payload_controller

"""Payload position + cable attitude controller.

Sreenath, Lee, Kumar (2013) https://ieeexplore.ieee.org/abstract/document/6760219
"""

import numpy as np

from ...control import Gains, PDController
from ...core.defaults import (
    DEFAULT_CABLE_LENGTH,
    DEFAULT_PAYLOAD_CABLE_KD,
    DEFAULT_PAYLOAD_CABLE_KP,
    DEFAULT_PAYLOAD_MASS,
    DEFAULT_PAYLOAD_POS_KD,
    DEFAULT_PAYLOAD_POS_KP,
    DEFAULT_QUAD_INERTIA,
    DEFAULT_QUAD_MASS,
)
from ...utils import hat


[docs] class QuadCSPayloadController(PDController):
[docs] def __init__(self, **kwargs): super().__init__(**kwargs) self._gain_pos = Gains(kp=DEFAULT_PAYLOAD_POS_KP.copy(), kd=DEFAULT_PAYLOAD_POS_KD.copy()) self._gain_cable = Gains( kp=DEFAULT_PAYLOAD_CABLE_KP.copy(), kd=DEFAULT_PAYLOAD_CABLE_KD.copy() ) self._quad_mass = DEFAULT_QUAD_MASS self._quad_inertia = DEFAULT_QUAD_INERTIA.copy() self._quad_inertia_inv = np.linalg.inv(self._quad_inertia) self._payload_mass = DEFAULT_PAYLOAD_MASS self._cable_length = DEFAULT_CABLE_LENGTH
[docs] def compute(self, *args): """payload position control""" t = args[0] s = args[1] # quadrotor payload state sd, dsd, d2sd = self.setpoint(t) ex = s.payload_position - sd ev = s.payload_velocity - dsd q = s.cable_attitude dq = s.dq() mQ = self._quad_mass mL = self._payload_mass l = self._cable_length Fff = (mQ + mL) * (d2sd + self._ge3) + mQ * l * np.dot(dq, dq) * q Fpd = -self._gain_pos.kp * ex - self._gain_pos.kd * ev A = Fff + Fpd # desired load attitude qc = -A / np.linalg.norm(A) # load-attitude ctrl qd = qc dqd = np.zeros(3) # TODO update from differential flatness d2qd = np.zeros(3) # TODO update from differential flatness # calculating errors err_q = hat(q) @ hat(q) @ qd err_dq = dq - np.cross(np.cross(qd, dqd), q) Fpd = -self._gain_cable.kp * err_q - self._gain_cable.kd * err_dq Fff = (mQ * l) * np.dot(q, np.cross(qd, dqd)) * np.cross(q, dq) + (mQ * l) * np.cross( np.cross(qd, d2qd), q ) Fn = np.dot(A, q) * q thrust_force = -Fpd - Fff + Fn return thrust_force