Skip to content

[AUD-003][Critical] Include D12 in H-infinity state-feedback synthesis #299

Description

@gabrielsantosphilips

Audit finding

  • ID: AUD-003
  • Status: Verified defect
  • Severity: Critical
  • Confidence: High
  • Audited revision: 2f479320d805a1f9f35ebe4afaaeeded48913a94

Problem

The public generalized plant accepts D12, but BuildAugmented() never reads it and hardcodes the control weight to identity. For z = C1 x + D12 u, synthesis requires the D12^T D12 control term and the C1^T D12 cross-term. Changing D12 therefore cannot change the controller, so the implementation solves a different game from the advertised model.

Source:

std::size_t DisturbanceSize,
std::size_t ControlSize,
std::size_t ErrorSize>
struct GeneralizedPlant
{
static_assert(std::is_floating_point_v<T>, "GeneralizedPlant supports floating-point types");
using StateMatrix = math::SquareMatrix<T, StateSize>;
using DisturbanceMatrix = math::Matrix<T, StateSize, DisturbanceSize>;
using ControlMatrix = math::Matrix<T, StateSize, ControlSize>;
using ErrorStateMatrix = math::Matrix<T, ErrorSize, StateSize>;
using ErrorControlMatrix = math::Matrix<T, ErrorSize, ControlSize>;
StateMatrix A{};
DisturbanceMatrix B1{};
ControlMatrix B2{};
ErrorStateMatrix C1{};
ErrorControlMatrix D12{};
};
and
typename HInfinityStateFeedback<T, StateSize, DisturbanceSize, ControlSize, ErrorSize>::Augmented
HInfinityStateFeedback<T, StateSize, DisturbanceSize, ControlSize, ErrorSize>::BuildAugmented(T g) const
{
Augmented aug{};
aug.B.SetBlock(plant.B2, 0, 0);
aug.B.SetBlock(plant.B1, 0, ControlSize);
auto controlWeight = math::SquareMatrix<T, ControlSize>::Identity();
auto disturbanceWeight = math::SquareMatrix<T, DisturbanceSize>::Identity();
disturbanceWeight *= -(g * g);
aug.Rtilde.SetBlock(controlWeight, 0, 0);
aug.Rtilde.SetBlock(disturbanceWeight, ControlSize, ControlSize);
aug.Q = plant.C1.Transpose() * plant.C1;
return aug;
}

Feasibility additionally checks only diagonal signs and permits an absolute Riccati residual up to 1.

Acceptance criteria

  • Implement the generalized D12 and cross-term formulation, or narrow the public API to the actually supported normalization.
  • Use valid definiteness checks rather than diagonal-only tests.
  • Use a scale-aware Riccati residual tolerance.
  • Add an independent test where changing D12 changes the synthesized gain and achieved bound.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions