41 #include <Eigen/Dense>
48 template <
typename TA,
typename TB,
typename TQ,
typename TR>
49 Lqr(
const Eigen::MatrixBase<TA>& A,
const Eigen::MatrixBase<TB>& B,
const Eigen::MatrixBase<TQ>& Q,
50 const Eigen::MatrixBase<TR>& R)
54 static_assert(TA::RowsAtCompileTime == TA::ColsAtCompileTime,
"lqr: A should be square matrix");
56 static_assert(TB::RowsAtCompileTime == TA::RowsAtCompileTime,
"lqr: B rows should be equal to A rows");
58 static_assert(TQ::RowsAtCompileTime == TA::RowsAtCompileTime && TQ::ColsAtCompileTime == TA::ColsAtCompileTime,
59 "lqr: The rows and columns of Q should be equal to A");
61 static_assert(TR::RowsAtCompileTime == TB::ColsAtCompileTime && TR::ColsAtCompileTime == TB::ColsAtCompileTime,
62 "lqr: The rows and columns of R should be equal to the cols of B");
64 k_.resize(TB::ColsAtCompileTime, TB::RowsAtCompileTime);
69 const Eigen::MatrixXd& R, Eigen::MatrixXd& P)
74 Eigen::MatrixXd ham = Eigen::MatrixXd::Zero(2 * dim_x, 2 * dim_x);
75 ham << A, -B * R.inverse() * B.transpose(), -Q, -A.transpose();
78 Eigen::EigenSolver<Eigen::MatrixXd> eigs(ham);
81 Eigen::MatrixXcd eigvec = Eigen::MatrixXcd::Zero(2 * dim_x, dim_x);
83 for (
int i = 0; i < 2 * dim_x; ++i)
85 if (eigs.eigenvalues()[i].real() < 0.)
87 eigvec.col(j) = eigs.eigenvectors().block(0, i, 2 * dim_x, 1);
93 Eigen::MatrixXcd vs_1, vs_2;
94 vs_1 = eigvec.block(0, 0, dim_x, dim_x);
95 vs_2 = eigvec.block(dim_x, 0, dim_x, dim_x);
96 P = (vs_2 * vs_1.inverse()).real();
103 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > q_solver(
q_);
104 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > r_solver(
r_);
105 if (q_solver.info() != Eigen::Success || r_solver.info() != Eigen::Success)
108 for (
int i = 0; i < q_solver.eigenvalues().cols(); ++i)
110 if (q_solver.eigenvalues()[i] < 0)
113 for (
int i = 0; i < r_solver.eigenvalues().cols(); ++i)
115 if (r_solver.eigenvalues()[i] <= 0)
123 k_ =
r_.inverse() * (
b_.transpose() * p.transpose());
127 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
getK()
135 for (
int i = 0; i < m.rows() - 1; ++i)
137 for (
int j = i + 1; j < m.cols(); ++j)
139 if (m(i, j - i) != m(j - i, i))