Skip to content

Controller Architecture

Dyros Robot Controller separates robot state from controller computation into two distinct classes.

Class Hierarchy

RobotData          ← owns model, state, and all derived kinematics/dynamics
    └─► RobotController   ← consumes RobotData; computes control commands
            ├─ QPIK / QPID         (single-priority QP solvers)
            └─ HQPIK / HQPID       (hierarchical QP solvers)

RobotData

RobotData wraps a Pinocchio model and caches every quantity that the controller needs at each timestep.

Quantity Method Symbol
Joint positions / velocities getJointPosition() / getJointVelocity() \(q,\;\dot{q}\)
Link SE(3) pose getPose(link_name) \(T \in SE(3)\)
Link Jacobian getJacobian(link_name) \(J \in \mathbb{R}^{6 \times n}\)
Link Jacobian time-derivative getJacobianTimeVariation(link_name) \(\dot{J}\)
Mass matrix / inverse getMassMatrix() / getMassMatrixInv() \(M,\;M^{-1}\)
Coriolis vector getCoriolis() \(c\)
Gravity vector getGravity() \(g\)
Nonlinear effects getNonlinearEffects() \(\text{nle} = c + g\)
Minimum self-collision distance getMinDistance(...) \(d_{\min}\)
Manipulability + gradient getManipulability(...) \(w,\;\nabla_q w\)

Call updateState(q, qdot) once per control cycle to refresh all cached quantities before calling any controller method.

RobotController

RobotController consumes a shared RobotData pointer and exposes the following controller groups:

Group Methods Details
Joint-space moveJoint* Joint-Space Control
CLIK CLIK*, CLIKStep*, CLIKCubic* Task-Space Control → CLIK
OSF OSF*, OSFStep*, OSFCubic* Task-Space Control → OSF
QP-IK QPIK*, QPIKStep*, QPIKCubic* QP and HQP → QPIK
QP-ID QPID*, QPIDStep*, QPIDCubic* QP and HQP → QPID
HQP-IK HQPIK*, HQPIKStep*, HQPIKCubic* QP and HQP → HQP
HQP-ID HQPID*, HQPIDStep*, HQPIDCubic* QP and HQP → HQP

Method naming convention

Each controller has three variants:

Suffix Input Description
(none) xdot_desired / xddot_desired Desired velocity or acceleration fed directly to the solver.
Step x_desired, xdot_desired Computes a proportional + feedforward reference from pose error, then calls the bare solver.
Cubic x_init, xdot_init, x_desired, xdot_desired, control_start_time, current_time Generates a cubic spline reference, then calls Step.

Task Data Flow

Task-space methods accept a std::map<std::string, TaskSpaceData> keyed by link name. TaskSpaceData bundles all fields needed by any variant:

struct TaskSpaceData {
    Affine3d  x_desired;           // target SE(3) pose
    Vector6d  xdot_desired;        // target 6D velocity
    Vector6d  xddot_desired;       // target 6D acceleration
    Affine3d  x_init;              // initial SE(3) pose  (Cubic variants)
    Vector6d  xdot_init;           // initial 6D velocity (Cubic variants)
    double    control_start_time;  // trajectory start time (Cubic variants)
    double    current_time;        // current simulation time (Cubic variants)
};

Unused fields are ignored silently.

Mobile Manipulator Outputs

Mobile manipulator QP / HQP methods return two separate command vectors:

Eigen::VectorXd opt_qdot_mobile;       // mobile-base DoF
Eigen::VectorXd opt_qdot_manipulator;  // manipulator DoF

The whole-body Jacobian is stacked internally and the solution is split at the mobile / manipulator DoF boundary.