akreon-control
Optimal and robust control and state estimation in C++26.
Loading...
Searching...
No Matches
polytopic_state_feedback.hpp
Go to the documentation of this file.
1/*
2 * Copyright © 2025-2026 Akreon LLC
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
9#include "akreon/convex/composed/quad_form.hpp"
10#include "akreon/convex/composed/weighted_sum.hpp"
11#include "akreon/convex/convex_problem.hpp"
12#include "akreon/convex/intersection.hpp"
13#include "akreon/convex/variable.hpp"
14
15namespace control {
16
35template <ContinuousPlantModelLike Plant, std::size_t N>
37 using Model = linalg::remove_cvref_t<Plant>;
38
41
42 static constexpr std::size_t StateDim = VertexFeedback::StateDim;
43 static constexpr std::size_t InputDim = VertexFeedback::InputDim;
44 static constexpr std::size_t PDim = VertexFeedback::PDim;
45 static constexpr std::size_t YDim = VertexFeedback::YDim;
46 static constexpr std::size_t ZDim = VertexFeedback::ZDim;
47
48 using PMat = typename VertexFeedback::PMat;
49 using YMat = typename VertexFeedback::YMat;
50 using KMat = typename VertexFeedback::KMat;
51 using FMat = typename VertexFeedback::FMat;
53 using Fs = typename VertexFeedback::Fs;
54 using Polytope = linalg::Vector<Plant, N>;
55
64 template <convex::AtomLike ZVar>
65 constexpr auto operator()(const Polytope& poly, const ZVar& Z,
66 T margin = 1e-6) const {
67 return apply(poly, Z, margin);
68 }
69
78 template <convex::AtomLike ZVar>
79 constexpr auto apply(const Polytope& poly, const ZVar& Z,
80 T margin = 1e-6) const {
81 static_assert(convex::is_var_type_v<ZVar>, "Input atom is not a var");
82 using ZDom = convex::meta_dom_t<convex::atom_meta_t<ZVar>>;
83 static_assert(convex::dom_vartype_v<ZDom> == convex::VarType::FREE,
84 "Merged decision var must be free");
85 using ZVarSpace = convex::dom_space_t<ZDom>;
86 static_assert(std::same_as<ZVarSpace, ZSpace>,
87 "Expected merged decision size [svec(P); vec(Y)]");
88
89 const auto p_lmi = VertexFeedback().p_constraint(Z, margin);
90
91 auto make_vertex_lmi = [&]<std::size_t idx>() {
92 return VertexFeedback().stability_constraint(poly(idx), Z);
93 };
94
95 auto form_intersection = [&]<std::size_t... Is>(
96 std::index_sequence<Is...>) {
97 return convex::Intersection(p_lmi,
98 make_vertex_lmi.template operator()<Is>()...);
99 };
100
101 return form_intersection(std::make_index_sequence<N>{});
102 }
103
114 constexpr auto K(const PMat& P, const YMat& Y) const {
115 return VertexFeedback().K(P, Y);
116 }
117};
118
130template <ContinuousPlantModelLike Plant, std::size_t N, convex::AtomLike ZVar>
132 const linalg::Vector<plant_type_t<Plant>,
134 const linalg::Vector<plant_type_t<Plant>,
136 const ZVar& Z) {
137 using T = plant_type_t<Plant>;
139
140 linalg::Vector<T, PSF::ZDim> c{};
141 for (std::size_t i = 0; i < PSF::PDim; ++i) c(i) = p_weights(i);
142 for (std::size_t i = 0; i < PSF::YDim; ++i) c(PSF::PDim + i) = y_weights(i);
143
144 return convex::make_weighted_sum(c, Z);
145}
146
158template <ContinuousPlantModelLike Plant, std::size_t N, convex::AtomLike ZVar>
160 const linalg::Matrix<plant_type_t<Plant>,
163 const linalg::Vector<plant_type_t<Plant>,
165 const ZVar& Z) {
166 return convex::make_quad_form(P, q, Z);
167}
168
179template <ContinuousPlantModelLike Plant, std::size_t N, convex::AtomLike ZVar>
181 const linalg::Vector<Plant, N>& poly, const ZVar& Z, const auto& obj,
184 return convex::make_problem(Z).in_set(pldi).minimize(obj);
185}
186
196template <ContinuousPlantModelLike Plant, std::size_t N, convex::AtomLike ZVar>
198 const linalg::Vector<Plant, N>& poly, const ZVar& Z,
201 return convex::make_problem(Z).in_set(pldi).feasibility();
202}
203
204} // namespace control
constexpr bool is_continuous_v
check if continuous or not
constexpr auto make_polytopic_state_feedback_linear_objective(const linalg::Vector< plant_type_t< Plant >, PolytopicStateFeedback< Plant, N >::PDim > &p_weights, const linalg::Vector< plant_type_t< Plant >, PolytopicStateFeedback< Plant, N >::YDim > &y_weights, const ZVar &Z)
make linear objective over merged PLDI variable
typename plant_traits< linalg::remove_cvref_t< Plant > >::T plant_type_t
extract scalar type from plant
constexpr auto make_polytopic_state_feedback_problem(const linalg::Vector< Plant, N > &poly, const ZVar &Z, const auto &obj, plant_type_t< Plant > margin=1e-6)
make PLDI problem with objective
constexpr auto make_polytopic_state_feedback_quadratic_objective(const linalg::Matrix< plant_type_t< Plant >, PolytopicStateFeedback< Plant, N >::ZDim, PolytopicStateFeedback< Plant, N >::ZDim > &P, const linalg::Vector< plant_type_t< Plant >, PolytopicStateFeedback< Plant, N >::ZDim > &q, const ZVar &Z)
make quadratic objective over merged PLDI variable
constexpr auto operator()(const Polytope &poly, const ZVar &Z, T margin=1e-6) const
operator overload (form polytopic state feedback)
static constexpr std::size_t StateDim
typename VertexFeedback::ZSpace ZSpace
constexpr auto apply(const Polytope &poly, const ZVar &Z, T margin=1e-6) const
apply (polytopic state feedback)
linalg::remove_cvref_t< Plant > Model
static constexpr std::size_t InputDim
constexpr auto K(const PMat &P, const YMat &Y) const
K.
linalg::Matrix< T, StateDim, StateDim > PMat
static constexpr std::size_t StateDim
linalg::RowVector< T, ZDim > ZSpace
static constexpr std::size_t PDim
static constexpr std::size_t ZDim
static constexpr std::size_t InputDim
linalg::Matrix< T, InputDim, StateDim > KMat
linalg::Matrix< T, InputDim, StateDim > YMat
linalg::Vector< FMat, ZDim > Fs
static constexpr std::size_t YDim