akreon-control
Optimal and robust control and state estimation in C++26.
Loading...
Searching...
No Matches
plant_model.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
8#include <utility>
9
11#include "akreon/linalg/linalg_util.hpp"
12
13namespace control {
14
55template <StateSpaceLike SS, typename InputPorts, typename OutputPorts>
56struct PlantModel {
57 using StateSpace = linalg::remove_cvref_t<SS>;
58 using InputPortsT = linalg::remove_cvref_t<InputPorts>;
59 using OutputPortsT = linalg::remove_cvref_t<OutputPorts>;
62
63 static constexpr std::size_t StateDim = plant_traits<Model>::StateDim;
64 static constexpr std::size_t InputDim = plant_traits<Model>::InputDim;
65 static constexpr std::size_t OutputDim = plant_traits<Model>::OutputDim;
66
67 static_assert(InputPortsT::template validates<InputDim>(),
68 "Input port layout is invalid for the state-space input");
69 static_assert(OutputPortsT::template validates<OutputDim>(),
70 "Output port layout is invalid for the state-space output");
71
75 constexpr explicit PlantModel(const StateSpace& ss) : state_space(ss) {}
76
81 constexpr PlantModel(const StateSpace& ss, const InputPortsT&,
82 const OutputPortsT&)
83 : state_space(ss) {}
84
86 constexpr auto dynamics_matrix() const { return state_space.A; }
87
90 constexpr auto exogenous_matrix() const {
92 }
93
95 constexpr auto control_matrix() const {
97 }
98
100 constexpr auto performance_matrix() const {
102 }
103
105 constexpr auto measurement_matrix() const {
107 }
108
118 template <PortRole OutRole, PortRole InRole>
119 constexpr auto feedthrough() const {
120 constexpr std::size_t Rows = OutputPortsT::template total_size<OutRole>();
121 constexpr std::size_t Cols = InputPortsT::template total_size<InRole>();
122 linalg::Matrix<T, Rows, Cols> result{};
123 if (state_space.D.has_value()) {
125 }
126 return result;
127 }
128
130
131private:
133 template <PortRole Role>
134 constexpr auto input_matrix() const {
135 constexpr std::size_t Cols = InputPortsT::template total_size<Role>();
136 linalg::Matrix<T, StateDim, Cols> result{};
138 return result;
139 }
140
142 template <PortRole Role>
143 constexpr auto output_matrix() const {
144 constexpr std::size_t Rows = OutputPortsT::template total_size<Role>();
145 linalg::Matrix<T, Rows, StateDim> result{};
147 return result;
148 }
149
151 template <PortRole Role, std::size_t Index, std::size_t DestOffset,
152 typename Mat>
153 constexpr void copy_input_ports(Mat& result) const {
154 constexpr std::size_t Count = InputPortsT::template count<Role>();
155 if constexpr (Index < Count) {
156 constexpr std::size_t Offset =
157 InputPortsT::template offset<Role, Index>();
158 constexpr std::size_t Size = InputPortsT::template size<Role, Index>();
159 const auto block =
160 linalg::get_block<0, StateDim, Offset, Offset + Size>(state_space.B);
161 result = linalg::set_block<0, StateDim, DestOffset, DestOffset + Size>(
162 result, block);
164 }
165 }
166
168 template <PortRole Role, std::size_t Index, std::size_t DestOffset,
169 typename Mat>
170 constexpr void copy_output_ports(Mat& result) const {
171 constexpr std::size_t Count = OutputPortsT::template count<Role>();
172 if constexpr (Index < Count) {
173 constexpr std::size_t Offset =
174 OutputPortsT::template offset<Role, Index>();
175 constexpr std::size_t Size = OutputPortsT::template size<Role, Index>();
176 const auto block =
177 linalg::get_block<Offset, Offset + Size, 0, StateDim>(state_space.C);
178 result = linalg::set_block<DestOffset, DestOffset + Size, 0, StateDim>(
179 result, block);
181 }
182 }
183
185 template <PortRole OutRole, PortRole InRole, std::size_t OutIndex,
186 std::size_t OutDestOffset, typename Mat>
187 constexpr void copy_feedthrough_ports(Mat& result) const {
188 constexpr std::size_t OutCount = OutputPortsT::template count<OutRole>();
189 if constexpr (OutIndex < OutCount) {
190 constexpr std::size_t OutOffset =
191 OutputPortsT::template offset<OutRole, OutIndex>();
192 constexpr std::size_t OutSize =
193 OutputPortsT::template size<OutRole, OutIndex>();
194 copy_feedthrough_input_ports<OutRole, InRole, OutIndex, OutOffset,
195 OutSize, 0, 0>(result);
196 copy_feedthrough_ports<OutRole, InRole, OutIndex + 1,
198 }
199 }
200
202 template <PortRole OutRole, PortRole InRole, std::size_t OutIndex,
203 std::size_t OutOffset, std::size_t OutSize, std::size_t InIndex,
204 std::size_t InDestOffset, typename Mat>
205 constexpr void copy_feedthrough_input_ports(Mat& result) const {
206 constexpr std::size_t InCount = InputPortsT::template count<InRole>();
207 if constexpr (InIndex < InCount) {
208 constexpr std::size_t InOffset =
209 InputPortsT::template offset<InRole, InIndex>();
210 constexpr std::size_t InSize =
211 InputPortsT::template size<InRole, InIndex>();
212 constexpr std::size_t OutDestOffset =
214 const auto block =
215 linalg::get_block<OutOffset, OutOffset + OutSize, InOffset,
217 result =
218 linalg::set_block<OutDestOffset, OutDestOffset + OutSize,
220 copy_feedthrough_input_ports<OutRole, InRole, OutIndex, OutOffset,
222 result);
223 }
224 }
225
227 template <PortRole Role, std::size_t Index>
228 static consteval std::size_t feedthrough_output_destination() {
229 std::size_t dest = 0;
230 [&]<std::size_t... Is>(std::index_sequence<Is...>) consteval {
232 }(std::make_index_sequence<OutputPortsT::template count<Role>()>{});
233 return dest;
234 }
235};
236
237} // namespace control
constexpr bool is_continuous_v
check if continuous or not
PortRole
Plant port role.
typename plant_traits< linalg::remove_cvref_t< Plant > >::T plant_type_t
extract scalar type from plant
Forward declaration of PlantModel.
static constexpr std::size_t OutputDim
constexpr auto control_matrix() const
Return B_u (StateDim x ControlDim), for actuator inputs.
constexpr PlantModel(const StateSpace &ss, const InputPortsT &, const OutputPortsT &)
Copy a model with layout arguments supplied for type deduction.
static constexpr std::size_t StateDim
linalg::remove_cvref_t< InputPorts > InputPortsT
constexpr auto feedthrough() const
Extract D blocks from the selected input role to output role.
linalg::remove_cvref_t< OutputPorts > OutputPortsT
constexpr auto measurement_matrix() const
Return C_y (MeasurementDim x StateDim), for measured outputs.
constexpr auto dynamics_matrix() const
Return A (StateDim x StateDim), without changing the time domain.
static constexpr std::size_t InputDim
constexpr auto exogenous_matrix() const
Return B_w (StateDim x ExogenousDim), for disturbance/reference/noise inputs.
plant_type_t< Model > T
SS state_space
Owned full model; accessors reflect its current matrices.
constexpr auto performance_matrix() const
Return C_z (PerformanceDim x StateDim), for regulated outputs.
constexpr PlantModel(const StateSpace &ss)
Copy a state-space model using the template-specified layouts.
linalg::remove_cvref_t< SS > StateSpace
base type traits for plant model