WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
LinearSystemUtil.hpp
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <complex>
8
9#include <Eigen/Core>
10#include <Eigen/Eigenvalues>
11#include <Eigen/QR>
12
14
15namespace wpi::math {
16
17/**
18 * Returns true if (A, B) is a stabilizable pair.
19 *
20 * (A, B) is stabilizable if and only if the uncontrollable eigenvalues of A, if
21 * any, have absolute values less than one, where an eigenvalue is
22 * uncontrollable if rank([λI - A, B]) < n where n is the number of states.
23 *
24 * @tparam States Number of states.
25 * @tparam Inputs Number of inputs.
26 * @param A System matrix.
27 * @param B Input matrix.
28 */
29template <int States, int Inputs>
30bool IsStabilizable(const Eigen::Matrix<double, States, States>& A,
31 const Eigen::Matrix<double, States, Inputs>& B) {
32 Eigen::EigenSolver<Eigen::Matrix<double, States, States>> es{A, false};
33
34 for (int i = 0; i < A.rows(); ++i) {
35 if (std::norm(es.eigenvalues()[i]) < 1) {
36 continue;
37 }
38
39 if constexpr (States != Eigen::Dynamic && Inputs != Eigen::Dynamic) {
40 Eigen::Matrix<std::complex<double>, States, States + Inputs> E;
41 E << es.eigenvalues()[i] * Eigen::Matrix<std::complex<double>, States,
42 States>::Identity() -
43 A,
44 B;
45
46 Eigen::ColPivHouseholderQR<
47 Eigen::Matrix<std::complex<double>, States, States + Inputs>>
48 qr{E};
49 if (qr.rank() < States) {
50 return false;
51 }
52 } else {
53 Eigen::MatrixXcd E{A.rows(), A.rows() + B.cols()};
54 E << es.eigenvalues()[i] *
55 Eigen::MatrixXcd::Identity(A.rows(), A.rows()) -
56 A,
57 B;
58
59 Eigen::ColPivHouseholderQR<Eigen::MatrixXcd> qr{E};
60 if (qr.rank() < A.rows()) {
61 return false;
62 }
63 }
64 }
65 return true;
66}
67
69 const Eigen::Matrix<double, 1, 1>& A, const Eigen::Matrix<double, 1, 1>& B);
71 const Eigen::Matrix<double, 2, 2>& A, const Eigen::Matrix<double, 2, 1>& B);
72extern template WPILIB_DLLEXPORT bool
74 const Eigen::MatrixXd& B);
75
76/**
77 * Returns true if (A, C) is a detectable pair.
78 *
79 * (A, C) is detectable if and only if the unobservable eigenvalues of A, if
80 * any, have absolute values less than one, where an eigenvalue is unobservable
81 * if rank([λI - A; C]) < n where n is the number of states.
82 *
83 * @tparam States Number of states.
84 * @tparam Outputs Number of outputs.
85 * @param A System matrix.
86 * @param C Output matrix.
87 */
88template <int States, int Outputs>
89bool IsDetectable(const Eigen::Matrix<double, States, States>& A,
90 const Eigen::Matrix<double, Outputs, States>& C) {
91 return IsStabilizable<States, Outputs>(A.transpose(), C.transpose());
92}
93
94extern template WPILIB_DLLEXPORT bool
96 const Eigen::MatrixXd& C);
97
98} // namespace wpi::math
#define WPILIB_DLLEXPORT
Definition SymbolExports.hpp:36
Definition LinearSystem.hpp:20
template WPILIB_DLLEXPORT bool IsDetectable< Eigen::Dynamic, Eigen::Dynamic >(const Eigen::MatrixXd &A, const Eigen::MatrixXd &C)
bool IsDetectable(const Eigen::Matrix< double, States, States > &A, const Eigen::Matrix< double, Outputs, States > &C)
Returns true if (A, C) is a detectable pair.
Definition LinearSystemUtil.hpp:89
template WPILIB_DLLEXPORT bool IsStabilizable< 1, 1 >(const Eigen::Matrix< double, 1, 1 > &A, const Eigen::Matrix< double, 1, 1 > &B)
template WPILIB_DLLEXPORT bool IsStabilizable< 2, 1 >(const Eigen::Matrix< double, 2, 2 > &A, const Eigen::Matrix< double, 2, 1 > &B)
bool IsStabilizable(const Eigen::Matrix< double, States, States > &A, const Eigen::Matrix< double, States, Inputs > &B)
Returns true if (A, B) is a stabilizable pair.
Definition LinearSystemUtil.hpp:30
template WPILIB_DLLEXPORT bool IsStabilizable< Eigen::Dynamic, Eigen::Dynamic >(const Eigen::MatrixXd &A, const Eigen::MatrixXd &B)