mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[wpimath] Add typedefs for common types
This makes complex code significantly easier to read. frc::Vectord<Size> = Eigen::Vector<double, Size> frc::Matrixd<Rows, Cols> = Eigen::Matrix<double, Rows, Cols>
This commit is contained in:
@@ -6,47 +6,46 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "frc/EigenCore.h"
|
||||
#include "frc/controller/ControlAffinePlantInversionFeedforward.h"
|
||||
#include "units/time.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
Eigen::Vector<double, 2> Dynamics(const Eigen::Vector<double, 2>& x,
|
||||
const Eigen::Vector<double, 1>& u) {
|
||||
return Eigen::Matrix<double, 2, 2>{{1.0, 0.0}, {0.0, 1.0}} * x +
|
||||
Eigen::Matrix<double, 2, 1>{0.0, 1.0} * u;
|
||||
Vectord<2> Dynamics(const Vectord<2>& x, const Vectord<1>& u) {
|
||||
return Matrixd<2, 2>{{1.0, 0.0}, {0.0, 1.0}} * x +
|
||||
Matrixd<2, 1>{0.0, 1.0} * u;
|
||||
}
|
||||
|
||||
Eigen::Vector<double, 2> StateDynamics(const Eigen::Vector<double, 2>& x) {
|
||||
return Eigen::Matrix<double, 2, 2>{{1.0, 0.0}, {0.0, 1.0}} * x;
|
||||
Vectord<2> StateDynamics(const Vectord<2>& x) {
|
||||
return Matrixd<2, 2>{{1.0, 0.0}, {0.0, 1.0}} * x;
|
||||
}
|
||||
|
||||
TEST(ControlAffinePlantInversionFeedforwardTest, Calculate) {
|
||||
std::function<Eigen::Vector<double, 2>(const Eigen::Vector<double, 2>&,
|
||||
const Eigen::Vector<double, 1>&)>
|
||||
std::function<Vectord<2>(const Vectord<2>&, const Vectord<1>&)>
|
||||
modelDynamics = [](auto& x, auto& u) { return Dynamics(x, u); };
|
||||
|
||||
frc::ControlAffinePlantInversionFeedforward<2, 1> feedforward{
|
||||
modelDynamics, units::second_t{0.02}};
|
||||
|
||||
Eigen::Vector<double, 2> r{2, 2};
|
||||
Eigen::Vector<double, 2> nextR{3, 3};
|
||||
Vectord<2> r{2, 2};
|
||||
Vectord<2> nextR{3, 3};
|
||||
|
||||
EXPECT_NEAR(48, feedforward.Calculate(r, nextR)(0, 0), 1e-6);
|
||||
}
|
||||
|
||||
TEST(ControlAffinePlantInversionFeedforwardTest, CalculateState) {
|
||||
std::function<Eigen::Vector<double, 2>(const Eigen::Vector<double, 2>&)>
|
||||
modelDynamics = [](auto& x) { return StateDynamics(x); };
|
||||
std::function<Vectord<2>(const Vectord<2>&)> modelDynamics = [](auto& x) {
|
||||
return StateDynamics(x);
|
||||
};
|
||||
|
||||
Eigen::Matrix<double, 2, 1> B{0, 1};
|
||||
Matrixd<2, 1> B{0, 1};
|
||||
|
||||
frc::ControlAffinePlantInversionFeedforward<2, 1> feedforward{
|
||||
modelDynamics, B, units::second_t(0.02)};
|
||||
|
||||
Eigen::Vector<double, 2> r{2, 2};
|
||||
Eigen::Vector<double, 2> nextR{3, 3};
|
||||
Vectord<2> r{2, 2};
|
||||
Vectord<2> nextR{3, 3};
|
||||
|
||||
EXPECT_NEAR(48, feedforward.Calculate(r, nextR)(0, 0), 1e-6);
|
||||
}
|
||||
|
||||
@@ -24,40 +24,37 @@ TEST(DifferentialDriveAccelerationLimiterTest, LowLimits) {
|
||||
DifferentialDriveAccelerationLimiter accelLimiter{plant, trackwidth, maxA,
|
||||
maxAlpha};
|
||||
|
||||
Eigen::Vector<double, 2> x{0.0, 0.0};
|
||||
Eigen::Vector<double, 2> xAccelLimiter{0.0, 0.0};
|
||||
Vectord<2> x{0.0, 0.0};
|
||||
Vectord<2> xAccelLimiter{0.0, 0.0};
|
||||
|
||||
// Ensure voltage exceeds acceleration before limiting
|
||||
{
|
||||
Eigen::Vector<double, 2> accels =
|
||||
plant.A() * xAccelLimiter +
|
||||
plant.B() * Eigen::Vector<double, 2>{12.0, 12.0};
|
||||
Vectord<2> accels =
|
||||
plant.A() * xAccelLimiter + plant.B() * Vectord<2>{12.0, 12.0};
|
||||
units::meters_per_second_squared_t a{(accels(0) + accels(1)) / 2.0};
|
||||
EXPECT_GT(units::math::abs(a), maxA);
|
||||
}
|
||||
{
|
||||
Eigen::Vector<double, 2> accels =
|
||||
plant.A() * xAccelLimiter +
|
||||
plant.B() * Eigen::Vector<double, 2>{-12.0, 12.0};
|
||||
Vectord<2> accels =
|
||||
plant.A() * xAccelLimiter + plant.B() * Vectord<2>{-12.0, 12.0};
|
||||
units::radians_per_second_squared_t alpha{(accels(1) - accels(0)) /
|
||||
trackwidth.value()};
|
||||
EXPECT_GT(units::math::abs(alpha), maxAlpha);
|
||||
}
|
||||
|
||||
// Forward
|
||||
Eigen::Vector<double, 2> u{12.0, 12.0};
|
||||
Vectord<2> u{12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
auto [left, right] =
|
||||
accelLimiter.Calculate(units::meters_per_second_t{xAccelLimiter(0)},
|
||||
units::meters_per_second_t{xAccelLimiter(1)},
|
||||
units::volt_t{u(0)}, units::volt_t{u(1)});
|
||||
xAccelLimiter = plant.CalculateX(xAccelLimiter,
|
||||
Eigen::Vector<double, 2>{left, right}, dt);
|
||||
xAccelLimiter =
|
||||
plant.CalculateX(xAccelLimiter, Vectord<2>{left, right}, dt);
|
||||
|
||||
Eigen::Vector<double, 2> accels =
|
||||
plant.A() * xAccelLimiter +
|
||||
plant.B() * Eigen::Vector<double, 2>{left, right};
|
||||
Vectord<2> accels =
|
||||
plant.A() * xAccelLimiter + plant.B() * Vectord<2>{left, right};
|
||||
units::meters_per_second_squared_t a{(accels(0) + accels(1)) / 2.0};
|
||||
units::radians_per_second_squared_t alpha{(accels(1) - accels(0)) /
|
||||
trackwidth.value()};
|
||||
@@ -66,19 +63,18 @@ TEST(DifferentialDriveAccelerationLimiterTest, LowLimits) {
|
||||
}
|
||||
|
||||
// Backward
|
||||
u = Eigen::Vector<double, 2>{-12.0, -12.0};
|
||||
u = Vectord<2>{-12.0, -12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
auto [left, right] =
|
||||
accelLimiter.Calculate(units::meters_per_second_t{xAccelLimiter(0)},
|
||||
units::meters_per_second_t{xAccelLimiter(1)},
|
||||
units::volt_t{u(0)}, units::volt_t{u(1)});
|
||||
xAccelLimiter = plant.CalculateX(xAccelLimiter,
|
||||
Eigen::Vector<double, 2>{left, right}, dt);
|
||||
xAccelLimiter =
|
||||
plant.CalculateX(xAccelLimiter, Vectord<2>{left, right}, dt);
|
||||
|
||||
Eigen::Vector<double, 2> accels =
|
||||
plant.A() * xAccelLimiter +
|
||||
plant.B() * Eigen::Vector<double, 2>{left, right};
|
||||
Vectord<2> accels =
|
||||
plant.A() * xAccelLimiter + plant.B() * Vectord<2>{left, right};
|
||||
units::meters_per_second_squared_t a{(accels(0) + accels(1)) / 2.0};
|
||||
units::radians_per_second_squared_t alpha{(accels(1) - accels(0)) /
|
||||
trackwidth.value()};
|
||||
@@ -87,19 +83,18 @@ TEST(DifferentialDriveAccelerationLimiterTest, LowLimits) {
|
||||
}
|
||||
|
||||
// Rotate CCW
|
||||
u = Eigen::Vector<double, 2>{-12.0, 12.0};
|
||||
u = Vectord<2>{-12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
auto [left, right] =
|
||||
accelLimiter.Calculate(units::meters_per_second_t{xAccelLimiter(0)},
|
||||
units::meters_per_second_t{xAccelLimiter(1)},
|
||||
units::volt_t{u(0)}, units::volt_t{u(1)});
|
||||
xAccelLimiter = plant.CalculateX(xAccelLimiter,
|
||||
Eigen::Vector<double, 2>{left, right}, dt);
|
||||
xAccelLimiter =
|
||||
plant.CalculateX(xAccelLimiter, Vectord<2>{left, right}, dt);
|
||||
|
||||
Eigen::Vector<double, 2> accels =
|
||||
plant.A() * xAccelLimiter +
|
||||
plant.B() * Eigen::Vector<double, 2>{left, right};
|
||||
Vectord<2> accels =
|
||||
plant.A() * xAccelLimiter + plant.B() * Vectord<2>{left, right};
|
||||
units::meters_per_second_squared_t a{(accels(0) + accels(1)) / 2.0};
|
||||
units::radians_per_second_squared_t alpha{(accels(1) - accels(0)) /
|
||||
trackwidth.value()};
|
||||
@@ -123,19 +118,19 @@ TEST(DifferentialDriveAccelerationLimiterTest, HighLimits) {
|
||||
DifferentialDriveAccelerationLimiter accelLimiter{
|
||||
plant, trackwidth, 1e3_mps_sq, 1e3_rad_per_s_sq};
|
||||
|
||||
Eigen::Vector<double, 2> x{0.0, 0.0};
|
||||
Eigen::Vector<double, 2> xAccelLimiter{0.0, 0.0};
|
||||
Vectord<2> x{0.0, 0.0};
|
||||
Vectord<2> xAccelLimiter{0.0, 0.0};
|
||||
|
||||
// Forward
|
||||
Eigen::Vector<double, 2> u{12.0, 12.0};
|
||||
Vectord<2> u{12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
auto [left, right] =
|
||||
accelLimiter.Calculate(units::meters_per_second_t{xAccelLimiter(0)},
|
||||
units::meters_per_second_t{xAccelLimiter(1)},
|
||||
units::volt_t{u(0)}, units::volt_t{u(1)});
|
||||
xAccelLimiter = plant.CalculateX(xAccelLimiter,
|
||||
Eigen::Vector<double, 2>{left, right}, dt);
|
||||
xAccelLimiter =
|
||||
plant.CalculateX(xAccelLimiter, Vectord<2>{left, right}, dt);
|
||||
|
||||
EXPECT_DOUBLE_EQ(x(0), xAccelLimiter(0));
|
||||
EXPECT_DOUBLE_EQ(x(1), xAccelLimiter(1));
|
||||
@@ -144,15 +139,15 @@ TEST(DifferentialDriveAccelerationLimiterTest, HighLimits) {
|
||||
// Backward
|
||||
x.setZero();
|
||||
xAccelLimiter.setZero();
|
||||
u = Eigen::Vector<double, 2>{-12.0, -12.0};
|
||||
u = Vectord<2>{-12.0, -12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
auto [left, right] =
|
||||
accelLimiter.Calculate(units::meters_per_second_t{xAccelLimiter(0)},
|
||||
units::meters_per_second_t{xAccelLimiter(1)},
|
||||
units::volt_t{u(0)}, units::volt_t{u(1)});
|
||||
xAccelLimiter = plant.CalculateX(xAccelLimiter,
|
||||
Eigen::Vector<double, 2>{left, right}, dt);
|
||||
xAccelLimiter =
|
||||
plant.CalculateX(xAccelLimiter, Vectord<2>{left, right}, dt);
|
||||
|
||||
EXPECT_DOUBLE_EQ(x(0), xAccelLimiter(0));
|
||||
EXPECT_DOUBLE_EQ(x(1), xAccelLimiter(1));
|
||||
@@ -161,15 +156,15 @@ TEST(DifferentialDriveAccelerationLimiterTest, HighLimits) {
|
||||
// Rotate CCW
|
||||
x.setZero();
|
||||
xAccelLimiter.setZero();
|
||||
u = Eigen::Vector<double, 2>{-12.0, 12.0};
|
||||
u = Vectord<2>{-12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
auto [left, right] =
|
||||
accelLimiter.Calculate(units::meters_per_second_t{xAccelLimiter(0)},
|
||||
units::meters_per_second_t{xAccelLimiter(1)},
|
||||
units::volt_t{u(0)}, units::volt_t{u(1)});
|
||||
xAccelLimiter = plant.CalculateX(xAccelLimiter,
|
||||
Eigen::Vector<double, 2>{left, right}, dt);
|
||||
xAccelLimiter =
|
||||
plant.CalculateX(xAccelLimiter, Vectord<2>{left, right}, dt);
|
||||
|
||||
EXPECT_DOUBLE_EQ(x(0), xAccelLimiter(0));
|
||||
EXPECT_DOUBLE_EQ(x(1), xAccelLimiter(1));
|
||||
|
||||
@@ -19,11 +19,11 @@ TEST(ImplicitModelFollowerTest, SameModel) {
|
||||
|
||||
ImplicitModelFollower<2, 2> imf{plant, plant};
|
||||
|
||||
Eigen::Vector<double, 2> x{0.0, 0.0};
|
||||
Eigen::Vector<double, 2> xImf{0.0, 0.0};
|
||||
Vectord<2> x{0.0, 0.0};
|
||||
Vectord<2> xImf{0.0, 0.0};
|
||||
|
||||
// Forward
|
||||
Eigen::Vector<double, 2> u{12.0, 12.0};
|
||||
Vectord<2> u{12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
xImf = plant.CalculateX(xImf, imf.Calculate(xImf, u), dt);
|
||||
@@ -33,7 +33,7 @@ TEST(ImplicitModelFollowerTest, SameModel) {
|
||||
}
|
||||
|
||||
// Backward
|
||||
u = Eigen::Vector<double, 2>{-12.0, -12.0};
|
||||
u = Vectord<2>{-12.0, -12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
xImf = plant.CalculateX(xImf, imf.Calculate(xImf, u), dt);
|
||||
@@ -43,7 +43,7 @@ TEST(ImplicitModelFollowerTest, SameModel) {
|
||||
}
|
||||
|
||||
// Rotate CCW
|
||||
u = Eigen::Vector<double, 2>{-12.0, 12.0};
|
||||
u = Vectord<2>{-12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
xImf = plant.CalculateX(xImf, imf.Calculate(xImf, u), dt);
|
||||
@@ -68,11 +68,11 @@ TEST(ImplicitModelFollowerTest, SlowerRefModel) {
|
||||
|
||||
ImplicitModelFollower<2, 2> imf{plant, plantRef};
|
||||
|
||||
Eigen::Vector<double, 2> x{0.0, 0.0};
|
||||
Eigen::Vector<double, 2> xImf{0.0, 0.0};
|
||||
Vectord<2> x{0.0, 0.0};
|
||||
Vectord<2> xImf{0.0, 0.0};
|
||||
|
||||
// Forward
|
||||
Eigen::Vector<double, 2> u{12.0, 12.0};
|
||||
Vectord<2> u{12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
xImf = plant.CalculateX(xImf, imf.Calculate(xImf, u), dt);
|
||||
@@ -84,7 +84,7 @@ TEST(ImplicitModelFollowerTest, SlowerRefModel) {
|
||||
// Backward
|
||||
x.setZero();
|
||||
xImf.setZero();
|
||||
u = Eigen::Vector<double, 2>{-12.0, -12.0};
|
||||
u = Vectord<2>{-12.0, -12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
xImf = plant.CalculateX(xImf, imf.Calculate(xImf, u), dt);
|
||||
@@ -96,7 +96,7 @@ TEST(ImplicitModelFollowerTest, SlowerRefModel) {
|
||||
// Rotate CCW
|
||||
x.setZero();
|
||||
xImf.setZero();
|
||||
u = Eigen::Vector<double, 2>{-12.0, 12.0};
|
||||
u = Vectord<2>{-12.0, 12.0};
|
||||
for (auto t = 0_s; t < 3_s; t += dt) {
|
||||
x = plant.CalculateX(x, u, dt);
|
||||
xImf = plant.CalculateX(xImf, imf.Calculate(xImf, u), dt);
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "frc/EigenCore.h"
|
||||
#include "frc/controller/LinearPlantInversionFeedforward.h"
|
||||
#include "units/time.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
TEST(LinearPlantInversionFeedforwardTest, Calculate) {
|
||||
Eigen::Matrix<double, 2, 2> A{{1, 0}, {0, 1}};
|
||||
Eigen::Matrix<double, 2, 1> B{0, 1};
|
||||
Matrixd<2, 2> A{{1, 0}, {0, 1}};
|
||||
Matrixd<2, 1> B{0, 1};
|
||||
|
||||
frc::LinearPlantInversionFeedforward<2, 1> feedforward{A, B,
|
||||
units::second_t(0.02)};
|
||||
|
||||
Eigen::Vector<double, 2> r{2, 2};
|
||||
Eigen::Vector<double, 2> nextR{3, 3};
|
||||
Vectord<2> r{2, 2};
|
||||
Vectord<2> nextR{3, 3};
|
||||
|
||||
EXPECT_NEAR(47.502599, feedforward.Calculate(r, nextR)(0, 0), 0.002);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "frc/EigenCore.h"
|
||||
#include "frc/controller/LinearQuadraticRegulator.h"
|
||||
#include "frc/system/LinearSystem.h"
|
||||
#include "frc/system/plant/DCMotor.h"
|
||||
@@ -30,7 +30,7 @@ TEST(LinearQuadraticRegulatorTest, ElevatorGains) {
|
||||
|
||||
return frc::LinearSystemId::ElevatorSystem(motors, m, r, G);
|
||||
}();
|
||||
Eigen::Matrix<double, 1, 2> K =
|
||||
Matrixd<1, 2> K =
|
||||
LinearQuadraticRegulator<2, 1>{plant, {0.02, 0.4}, {12.0}, 5.05_ms}.K();
|
||||
|
||||
EXPECT_NEAR(522.15314269, K(0, 0), 1e-6);
|
||||
@@ -54,7 +54,7 @@ TEST(LinearQuadraticRegulatorTest, ArmGains) {
|
||||
motors, 1.0 / 3.0 * m * r * r, G);
|
||||
}();
|
||||
|
||||
Eigen::Matrix<double, 1, 2> K =
|
||||
Matrixd<1, 2> K =
|
||||
LinearQuadraticRegulator<2, 1>{plant, {0.01745, 0.08726}, {12.0}, 5.05_ms}
|
||||
.K();
|
||||
|
||||
@@ -77,7 +77,7 @@ TEST(LinearQuadraticRegulatorTest, FourMotorElevator) {
|
||||
|
||||
return frc::LinearSystemId::ElevatorSystem(motors, m, r, G);
|
||||
}();
|
||||
Eigen::Matrix<double, 1, 2> K =
|
||||
Matrixd<1, 2> K =
|
||||
LinearQuadraticRegulator<2, 1>{plant, {0.1, 0.2}, {12.0}, 20_ms}.K();
|
||||
|
||||
EXPECT_NEAR(10.38, K(0, 0), 1e-1);
|
||||
@@ -99,50 +99,44 @@ TEST(LinearQuadraticRegulatorTest, FourMotorElevator) {
|
||||
* @param dt Discretization timestep.
|
||||
*/
|
||||
template <int States, int Inputs>
|
||||
Eigen::Matrix<double, Inputs, States> GetImplicitModelFollowingK(
|
||||
const Eigen::Matrix<double, States, States>& A,
|
||||
const Eigen::Matrix<double, States, Inputs>& B,
|
||||
const Eigen::Matrix<double, States, States>& Q,
|
||||
const Eigen::Matrix<double, Inputs, Inputs>& R,
|
||||
const Eigen::Matrix<double, States, States>& Aref, units::second_t dt) {
|
||||
Matrixd<Inputs, States> GetImplicitModelFollowingK(
|
||||
const Matrixd<States, States>& A, const Matrixd<States, Inputs>& B,
|
||||
const Matrixd<States, States>& Q, const Matrixd<Inputs, Inputs>& R,
|
||||
const Matrixd<States, States>& Aref, units::second_t dt) {
|
||||
// Discretize real dynamics
|
||||
Eigen::Matrix<double, States, States> discA;
|
||||
Eigen::Matrix<double, States, Inputs> discB;
|
||||
Matrixd<States, States> discA;
|
||||
Matrixd<States, Inputs> discB;
|
||||
DiscretizeAB<States, Inputs>(A, B, dt, &discA, &discB);
|
||||
|
||||
// Discretize desired dynamics
|
||||
Eigen::Matrix<double, States, States> discAref;
|
||||
Matrixd<States, States> discAref;
|
||||
DiscretizeA<States>(Aref, dt, &discAref);
|
||||
|
||||
Eigen::Matrix<double, States, States> Qimf =
|
||||
Matrixd<States, States> Qimf =
|
||||
(discA - discAref).transpose() * Q * (discA - discAref);
|
||||
Eigen::Matrix<double, Inputs, Inputs> Rimf =
|
||||
discB.transpose() * Q * discB + R;
|
||||
Eigen::Matrix<double, States, Inputs> Nimf =
|
||||
(discA - discAref).transpose() * Q * discB;
|
||||
Matrixd<Inputs, Inputs> Rimf = discB.transpose() * Q * discB + R;
|
||||
Matrixd<States, Inputs> Nimf = (discA - discAref).transpose() * Q * discB;
|
||||
|
||||
return LinearQuadraticRegulator<States, Inputs>{A, B, Qimf, Rimf, Nimf, dt}
|
||||
.K();
|
||||
}
|
||||
|
||||
TEST(LinearQuadraticRegulatorTest, MatrixOverloadsWithSingleIntegrator) {
|
||||
Eigen::Matrix<double, 2, 2> A{Eigen::Matrix<double, 2, 2>::Zero()};
|
||||
Eigen::Matrix<double, 2, 2> B{Eigen::Matrix<double, 2, 2>::Identity()};
|
||||
Eigen::Matrix<double, 2, 2> Q{Eigen::Matrix<double, 2, 2>::Identity()};
|
||||
Eigen::Matrix<double, 2, 2> R{Eigen::Matrix<double, 2, 2>::Identity()};
|
||||
Matrixd<2, 2> A{Matrixd<2, 2>::Zero()};
|
||||
Matrixd<2, 2> B{Matrixd<2, 2>::Identity()};
|
||||
Matrixd<2, 2> Q{Matrixd<2, 2>::Identity()};
|
||||
Matrixd<2, 2> R{Matrixd<2, 2>::Identity()};
|
||||
|
||||
// QR overload
|
||||
Eigen::Matrix<double, 2, 2> K =
|
||||
LinearQuadraticRegulator<2, 2>{A, B, Q, R, 5_ms}.K();
|
||||
Matrixd<2, 2> K = LinearQuadraticRegulator<2, 2>{A, B, Q, R, 5_ms}.K();
|
||||
EXPECT_NEAR(0.99750312499512261, K(0, 0), 1e-10);
|
||||
EXPECT_NEAR(0.0, K(0, 1), 1e-10);
|
||||
EXPECT_NEAR(0.0, K(1, 0), 1e-10);
|
||||
EXPECT_NEAR(0.99750312499512261, K(1, 1), 1e-10);
|
||||
|
||||
// QRN overload
|
||||
Eigen::Matrix<double, 2, 2> N{Eigen::Matrix<double, 2, 2>::Identity()};
|
||||
Eigen::Matrix<double, 2, 2> Kimf =
|
||||
LinearQuadraticRegulator<2, 2>{A, B, Q, R, N, 5_ms}.K();
|
||||
Matrixd<2, 2> N{Matrixd<2, 2>::Identity()};
|
||||
Matrixd<2, 2> Kimf = LinearQuadraticRegulator<2, 2>{A, B, Q, R, N, 5_ms}.K();
|
||||
EXPECT_NEAR(1.0, Kimf(0, 0), 1e-10);
|
||||
EXPECT_NEAR(0.0, Kimf(0, 1), 1e-10);
|
||||
EXPECT_NEAR(0.0, Kimf(1, 0), 1e-10);
|
||||
@@ -153,21 +147,19 @@ TEST(LinearQuadraticRegulatorTest, MatrixOverloadsWithDoubleIntegrator) {
|
||||
double Kv = 3.02;
|
||||
double Ka = 0.642;
|
||||
|
||||
Eigen::Matrix<double, 2, 2> A{{0, 1}, {0, -Kv / Ka}};
|
||||
Eigen::Matrix<double, 2, 1> B{{0}, {1.0 / Ka}};
|
||||
Eigen::Matrix<double, 2, 2> Q{{1, 0}, {0, 0.2}};
|
||||
Eigen::Matrix<double, 1, 1> R{0.25};
|
||||
Matrixd<2, 2> A{{0, 1}, {0, -Kv / Ka}};
|
||||
Matrixd<2, 1> B{{0}, {1.0 / Ka}};
|
||||
Matrixd<2, 2> Q{{1, 0}, {0, 0.2}};
|
||||
Matrixd<1, 1> R{0.25};
|
||||
|
||||
// QR overload
|
||||
Eigen::Matrix<double, 1, 2> K =
|
||||
LinearQuadraticRegulator<2, 1>{A, B, Q, R, 5_ms}.K();
|
||||
Matrixd<1, 2> K = LinearQuadraticRegulator<2, 1>{A, B, Q, R, 5_ms}.K();
|
||||
EXPECT_NEAR(1.9960017786537287, K(0, 0), 1e-10);
|
||||
EXPECT_NEAR(0.51182128351092726, K(0, 1), 1e-10);
|
||||
|
||||
// QRN overload
|
||||
Eigen::Matrix<double, 2, 2> Aref{{0, 1}, {0, -Kv / (Ka * 2.0)}};
|
||||
Eigen::Matrix<double, 1, 2> Kimf =
|
||||
GetImplicitModelFollowingK<2, 1>(A, B, Q, R, Aref, 5_ms);
|
||||
Matrixd<2, 2> Aref{{0, 1}, {0, -Kv / (Ka * 2.0)}};
|
||||
Matrixd<1, 2> Kimf = GetImplicitModelFollowingK<2, 1>(A, B, Q, R, Aref, 5_ms);
|
||||
EXPECT_NEAR(0.0, Kimf(0, 0), 1e-10);
|
||||
EXPECT_NEAR(-5.367540084534802e-05, Kimf(0, 1), 1e-10);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "frc/EigenCore.h"
|
||||
#include "frc/controller/LinearPlantInversionFeedforward.h"
|
||||
#include "frc/controller/SimpleMotorFeedforward.h"
|
||||
#include "units/acceleration.h"
|
||||
@@ -21,16 +21,16 @@ TEST(SimpleMotorFeedforwardTest, Calculate) {
|
||||
double Ka = 0.6;
|
||||
auto dt = 0.02_s;
|
||||
|
||||
Eigen::Matrix<double, 1, 1> A{-Kv / Ka};
|
||||
Eigen::Matrix<double, 1, 1> B{1.0 / Ka};
|
||||
Matrixd<1, 1> A{-Kv / Ka};
|
||||
Matrixd<1, 1> B{1.0 / Ka};
|
||||
|
||||
frc::LinearPlantInversionFeedforward<1, 1> plantInversion{A, B, dt};
|
||||
frc::SimpleMotorFeedforward<units::meter> simpleMotor{
|
||||
units::volt_t{Ks}, units::volt_t{Kv} / 1_mps,
|
||||
units::volt_t{Ka} / 1_mps_sq};
|
||||
|
||||
Eigen::Vector<double, 1> r{2.0};
|
||||
Eigen::Vector<double, 1> nextR{3.0};
|
||||
Vectord<1> r{2.0};
|
||||
Vectord<1> nextR{3.0};
|
||||
|
||||
EXPECT_NEAR(37.524995834325161 + Ks,
|
||||
simpleMotor.Calculate(2_mps, 3_mps, dt).value(), 0.002);
|
||||
|
||||
Reference in New Issue
Block a user