diff --git a/wpilibc/src/main/native/cpp/simulation/DifferentialDrivetrainSim.cpp b/wpilibc/src/main/native/cpp/simulation/DifferentialDrivetrainSim.cpp index 4628653dd4..5f53575df8 100644 --- a/wpilibc/src/main/native/cpp/simulation/DifferentialDrivetrainSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/DifferentialDrivetrainSim.cpp @@ -41,8 +41,8 @@ DifferentialDrivetrainSim::DifferentialDrivetrainSim( driveMotor, mass, wheelRadius, trackWidth / 2.0, J, gearing), trackWidth, driveMotor, gearing, wheelRadius, measurementStdDevs) {} -Eigen::Matrix DifferentialDrivetrainSim::ClampInput( - Eigen::Matrix u) { +Eigen::Vector DifferentialDrivetrainSim::ClampInput( + const Eigen::Vector& u) { return frc::NormalizeInputVector<2>(u, frc::RobotController::GetInputVoltage()); } @@ -66,11 +66,11 @@ double DifferentialDrivetrainSim::GetGearing() const { return m_currentGearing; } -Eigen::Matrix DifferentialDrivetrainSim::GetOutput() const { +Eigen::Vector DifferentialDrivetrainSim::GetOutput() const { return m_y; } -Eigen::Matrix DifferentialDrivetrainSim::GetState() const { +Eigen::Vector DifferentialDrivetrainSim::GetState() const { return m_x; } @@ -117,7 +117,7 @@ units::ampere_t DifferentialDrivetrainSim::GetCurrentDraw() const { } void DifferentialDrivetrainSim::SetState( - const Eigen::Matrix& state) { + const Eigen::Vector& state) { m_x = state; } @@ -129,9 +129,8 @@ void DifferentialDrivetrainSim::SetPose(const frc::Pose2d& pose) { m_x(State::kRightPosition) = 0; } -Eigen::Matrix DifferentialDrivetrainSim::Dynamics( - const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector DifferentialDrivetrainSim::Dynamics( + const Eigen::Vector& x, const Eigen::Vector& u) { // Because G^2 can be factored out of A, we can divide by the old ratio // squared and multiply by the new ratio squared to get a new drivetrain // model. @@ -150,7 +149,7 @@ Eigen::Matrix DifferentialDrivetrainSim::Dynamics( double v = (x(State::kLeftVelocity) + x(State::kRightVelocity)) / 2.0; - Eigen::Matrix xdot; + Eigen::Vector xdot; xdot(0) = v * std::cos(x(State::kHeading)); xdot(1) = v * std::sin(x(State::kHeading)); xdot(2) = diff --git a/wpilibc/src/main/native/cpp/simulation/ElevatorSim.cpp b/wpilibc/src/main/native/cpp/simulation/ElevatorSim.cpp index a2951ecf86..31d2f3a89a 100644 --- a/wpilibc/src/main/native/cpp/simulation/ElevatorSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/ElevatorSim.cpp @@ -6,7 +6,6 @@ #include -#include "frc/StateSpaceUtil.h" #include "frc/system/NumericalIntegration.h" #include "frc/system/plant/LinearSystemId.h" @@ -79,25 +78,25 @@ units::ampere_t ElevatorSim::GetCurrentDraw() const { } void ElevatorSim::SetInputVoltage(units::volt_t voltage) { - SetInput(frc::MakeMatrix<1, 1>(voltage.to())); + SetInput(Eigen::Vector{voltage.to()}); } -Eigen::Matrix ElevatorSim::UpdateX( - const Eigen::Matrix& currentXhat, - const Eigen::Matrix& u, units::second_t dt) { +Eigen::Vector ElevatorSim::UpdateX( + const Eigen::Vector& currentXhat, + const Eigen::Vector& u, units::second_t dt) { auto updatedXhat = RKDP( - [&](const Eigen::Matrix& x, - const Eigen::Matrix& u_) - -> Eigen::Matrix { - return m_plant.A() * x + m_plant.B() * u_ + MakeMatrix<2, 1>(0.0, -9.8); + [&](const Eigen::Vector& x, + const Eigen::Vector& u_) -> Eigen::Vector { + return m_plant.A() * x + m_plant.B() * u_ + + Eigen::Vector{0.0, -9.8}; }, currentXhat, u, dt); // Check for collision after updating x-hat. if (WouldHitLowerLimit(units::meter_t(updatedXhat(0)))) { - return MakeMatrix<2, 1>(m_minHeight.to(), 0.0); + return Eigen::Vector{m_minHeight.to(), 0.0}; } if (WouldHitUpperLimit(units::meter_t(updatedXhat(0)))) { - return MakeMatrix<2, 1>(m_maxHeight.to(), 0.0); + return Eigen::Vector{m_maxHeight.to(), 0.0}; } return updatedXhat; } diff --git a/wpilibc/src/main/native/cpp/simulation/FlywheelSim.cpp b/wpilibc/src/main/native/cpp/simulation/FlywheelSim.cpp index fef5792765..442183a163 100644 --- a/wpilibc/src/main/native/cpp/simulation/FlywheelSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/FlywheelSim.cpp @@ -38,5 +38,5 @@ units::ampere_t FlywheelSim::GetCurrentDraw() const { } void FlywheelSim::SetInputVoltage(units::volt_t voltage) { - SetInput(frc::MakeMatrix<1, 1>(voltage.to())); + SetInput(Eigen::Vector{voltage.to()}); } diff --git a/wpilibc/src/main/native/cpp/simulation/SingleJointedArmSim.cpp b/wpilibc/src/main/native/cpp/simulation/SingleJointedArmSim.cpp index 908a340528..eeb982d1d6 100644 --- a/wpilibc/src/main/native/cpp/simulation/SingleJointedArmSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/SingleJointedArmSim.cpp @@ -72,12 +72,12 @@ units::ampere_t SingleJointedArmSim::GetCurrentDraw() const { } void SingleJointedArmSim::SetInputVoltage(units::volt_t voltage) { - SetInput(frc::MakeMatrix<1, 1>(voltage.to())); + SetInput(Eigen::Vector{voltage.to()}); } -Eigen::Matrix SingleJointedArmSim::UpdateX( - const Eigen::Matrix& currentXhat, - const Eigen::Matrix& u, units::second_t dt) { +Eigen::Vector SingleJointedArmSim::UpdateX( + const Eigen::Vector& currentXhat, + const Eigen::Vector& u, units::second_t dt) { // Horizontal case: // Torque = F * r = I * alpha // alpha = F * r / I @@ -88,14 +88,15 @@ Eigen::Matrix SingleJointedArmSim::UpdateX( // We therefore find that f(x, u) = Ax + Bu + [[0] [m * g * r / I * // std::cos(theta)]] - Eigen::Matrix updatedXhat = RKDP( - [&](const auto& x, const auto& u) -> Eigen::Matrix { - Eigen::Matrix xdot = m_plant.A() * x + m_plant.B() * u; + Eigen::Vector updatedXhat = RKDP( + [&](const auto& x, const auto& u) -> Eigen::Vector { + Eigen::Vector xdot = m_plant.A() * x + m_plant.B() * u; if (m_simulateGravity) { - xdot += MakeMatrix<2, 1>(0.0, (m_mass * m_r * -9.8 * 3.0 / - (m_mass * m_r * m_r) * std::cos(x(0))) - .template to()); + xdot += Eigen::Vector{ + 0.0, (m_mass * m_r * -9.8 * 3.0 / (m_mass * m_r * m_r) * + std::cos(x(0))) + .template to()}; } return xdot; }, @@ -103,9 +104,9 @@ Eigen::Matrix SingleJointedArmSim::UpdateX( // Check for collisions. if (WouldHitLowerLimit(units::radian_t(updatedXhat(0)))) { - return MakeMatrix<2, 1>(m_minAngle.to(), 0.0); + return Eigen::Vector{m_minAngle.to(), 0.0}; } else if (WouldHitUpperLimit(units::radian_t(updatedXhat(0)))) { - return MakeMatrix<2, 1>(m_maxAngle.to(), 0.0); + return Eigen::Vector{m_maxAngle.to(), 0.0}; } return updatedXhat; } diff --git a/wpilibc/src/main/native/include/frc/simulation/DifferentialDrivetrainSim.h b/wpilibc/src/main/native/include/frc/simulation/DifferentialDrivetrainSim.h index bcb23e32e1..3de59b5aea 100644 --- a/wpilibc/src/main/native/include/frc/simulation/DifferentialDrivetrainSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/DifferentialDrivetrainSim.h @@ -80,7 +80,7 @@ class DifferentialDrivetrainSim { * @param maxVoltage The maximum voltage. * @return The normalized input. */ - Eigen::Matrix ClampInput(Eigen::Matrix u); + Eigen::Vector ClampInput(const Eigen::Vector& u); /** * Sets the applied voltage to the drivetrain. Note that positive voltage must @@ -178,7 +178,7 @@ class DifferentialDrivetrainSim { * * @param state The state. */ - void SetState(const Eigen::Matrix& state); + void SetState(const Eigen::Vector& state); /** * Sets the system pose. @@ -187,8 +187,8 @@ class DifferentialDrivetrainSim { */ void SetPose(const frc::Pose2d& pose); - Eigen::Matrix Dynamics(const Eigen::Matrix& x, - const Eigen::Matrix& u); + Eigen::Vector Dynamics(const Eigen::Vector& x, + const Eigen::Vector& u); class State { public: @@ -295,7 +295,7 @@ class DifferentialDrivetrainSim { /** * Returns the current output vector y. */ - Eigen::Matrix GetOutput() const; + Eigen::Vector GetOutput() const; /** * Returns an element of the state vector. Note that this will not include @@ -308,7 +308,7 @@ class DifferentialDrivetrainSim { /** * Returns the current state vector x. Note that this will not include noise! */ - Eigen::Matrix GetState() const; + Eigen::Vector GetState() const; LinearSystem<2, 2, 2> m_plant; units::meter_t m_rb; @@ -319,9 +319,9 @@ class DifferentialDrivetrainSim { double m_originalGearing; double m_currentGearing; - Eigen::Matrix m_x; - Eigen::Matrix m_u; - Eigen::Matrix m_y; + Eigen::Vector m_x; + Eigen::Vector m_u; + Eigen::Vector m_y; std::array m_measurementStdDevs; }; } // namespace frc::sim diff --git a/wpilibc/src/main/native/include/frc/simulation/ElevatorSim.h b/wpilibc/src/main/native/include/frc/simulation/ElevatorSim.h index c7849452e1..14b6d2df29 100644 --- a/wpilibc/src/main/native/include/frc/simulation/ElevatorSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/ElevatorSim.h @@ -123,9 +123,9 @@ class ElevatorSim : public LinearSystemSim<2, 1, 1> { * @param u The system inputs (voltage). * @param dt The time difference between controller updates. */ - Eigen::Matrix UpdateX( - const Eigen::Matrix& currentXhat, - const Eigen::Matrix& u, units::second_t dt) override; + Eigen::Vector UpdateX(const Eigen::Vector& currentXhat, + const Eigen::Vector& u, + units::second_t dt) override; private: DCMotor m_gearbox; diff --git a/wpilibc/src/main/native/include/frc/simulation/LinearSystemSim.h b/wpilibc/src/main/native/include/frc/simulation/LinearSystemSim.h index db0a3a7ddc..61cbd4630b 100644 --- a/wpilibc/src/main/native/include/frc/simulation/LinearSystemSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/LinearSystemSim.h @@ -40,9 +40,9 @@ class LinearSystemSim { const LinearSystem& system, const std::array& measurementStdDevs = {}) : m_plant(system), m_measurementStdDevs(measurementStdDevs) { - m_x = Eigen::Matrix::Zero(); - m_y = Eigen::Matrix::Zero(); - m_u = Eigen::Matrix::Zero(); + m_x = Eigen::Vector::Zero(); + m_y = Eigen::Vector::Zero(); + m_u = Eigen::Vector::Zero(); } /** @@ -69,7 +69,7 @@ class LinearSystemSim { * * @return The current output of the plant. */ - const Eigen::Matrix& GetOutput() const { return m_y; } + const Eigen::Vector& GetOutput() const { return m_y; } /** * Returns an element of the current output of the plant. @@ -84,9 +84,7 @@ class LinearSystemSim { * * @param u The system inputs. */ - void SetInput(const Eigen::Matrix& u) { - m_u = ClampInput(u); - } + void SetInput(const Eigen::Vector& u) { m_u = ClampInput(u); } /* * Sets the system inputs. @@ -104,7 +102,7 @@ class LinearSystemSim { * * @param state The new state. */ - void SetState(const Eigen::Matrix& state) { m_x = state; } + void SetState(const Eigen::Vector& state) { m_x = state; } /** * Returns the current drawn by this simulated system. Override this method to @@ -124,9 +122,9 @@ class LinearSystemSim { * @param u The system inputs (usually voltage). * @param dt The time difference between controller updates. */ - virtual Eigen::Matrix UpdateX( - const Eigen::Matrix& currentXhat, - const Eigen::Matrix& u, units::second_t dt) { + virtual Eigen::Vector UpdateX( + const Eigen::Vector& currentXhat, + const Eigen::Vector& u, units::second_t dt) { return m_plant.CalculateX(currentXhat, u, dt); } @@ -137,17 +135,16 @@ class LinearSystemSim { * @param u The input vector. * @return The normalized input. */ - Eigen::Matrix ClampInput( - Eigen::Matrix u) { + Eigen::Vector ClampInput(Eigen::Vector u) { return frc::NormalizeInputVector( u, frc::RobotController::GetInputVoltage()); } LinearSystem m_plant; - Eigen::Matrix m_x; - Eigen::Matrix m_y; - Eigen::Matrix m_u; + Eigen::Vector m_x; + Eigen::Vector m_y; + Eigen::Vector m_u; std::array m_measurementStdDevs; }; } // namespace frc::sim diff --git a/wpilibc/src/main/native/include/frc/simulation/SingleJointedArmSim.h b/wpilibc/src/main/native/include/frc/simulation/SingleJointedArmSim.h index 3fe42ba0fb..4ff29cc0b5 100644 --- a/wpilibc/src/main/native/include/frc/simulation/SingleJointedArmSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/SingleJointedArmSim.h @@ -142,9 +142,9 @@ class SingleJointedArmSim : public LinearSystemSim<2, 1, 1> { * @param u The system inputs (voltage). * @param dt The time difference between controller updates. */ - Eigen::Matrix UpdateX( - const Eigen::Matrix& currentXhat, - const Eigen::Matrix& u, units::second_t dt) override; + Eigen::Vector UpdateX(const Eigen::Vector& currentXhat, + const Eigen::Vector& u, + units::second_t dt) override; private: units::meter_t m_r; diff --git a/wpilibc/src/test/native/cpp/simulation/DifferentialDriveSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/DifferentialDriveSimTest.cpp index 3eeb4ef49a..6d208aa5c8 100644 --- a/wpilibc/src/test/native/cpp/simulation/DifferentialDriveSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/DifferentialDriveSimTest.cpp @@ -30,11 +30,10 @@ TEST(DifferentialDriveSim, Convergence) { frc::LinearPlantInversionFeedforward feedforward{plant, 20_ms}; frc::RamseteController ramsete; - feedforward.Reset(frc::MakeMatrix<2, 1>(0.0, 0.0)); + feedforward.Reset(Eigen::Vector{0.0, 0.0}); // Ground truth. - Eigen::Matrix groundTruthX = - Eigen::Matrix::Zero(); + Eigen::Vector groundTruthX = Eigen::Vector::Zero(); frc::TrajectoryConfig config{1_mps, 1_mps_sq}; config.AddConstraint( @@ -50,7 +49,7 @@ TEST(DifferentialDriveSim, Convergence) { auto [l, r] = kinematics.ToWheelSpeeds(ramseteOut); auto voltages = feedforward.Calculate( - frc::MakeMatrix<2, 1>(l.to(), r.to())); + Eigen::Vector{l.to(), r.to()}); // Sim periodic code. sim.SetInputs(units::volt_t(voltages(0, 0)), units::volt_t(voltages(1, 0))); @@ -58,7 +57,7 @@ TEST(DifferentialDriveSim, Convergence) { // Update ground truth. groundTruthX = frc::RK4( - [&sim](const auto& x, const auto& u) -> Eigen::Matrix { + [&sim](const auto& x, const auto& u) -> Eigen::Vector { return sim.Dynamics(x, u); }, groundTruthX, voltages, 20_ms); diff --git a/wpilibc/src/test/native/cpp/simulation/ElevatorSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/ElevatorSimTest.cpp index 1a52036c1c..340f51338c 100644 --- a/wpilibc/src/test/native/cpp/simulation/ElevatorSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/ElevatorSimTest.cpp @@ -8,7 +8,6 @@ #include "frc/Encoder.h" #include "frc/RobotController.h" -#include "frc/StateSpaceUtil.h" #include "frc/controller/PIDController.h" #include "frc/motorcontrol/PWMVictorSPX.h" #include "frc/simulation/ElevatorSim.h" @@ -33,8 +32,8 @@ TEST(ElevatorSim, StateSpaceSim) { auto nextVoltage = controller.Calculate(encoderSim.GetDistance()); motor.Set(nextVoltage / frc::RobotController::GetInputVoltage()); - auto u = frc::MakeMatrix<1, 1>(motor.Get() * - frc::RobotController::GetInputVoltage()); + Eigen::Vector u{motor.Get() * + frc::RobotController::GetInputVoltage()}; sim.SetInput(u); sim.Update(20_ms); @@ -50,7 +49,7 @@ TEST(ElevatorSim, MinMax) { units::meter_t(0.75 * 25.4 / 1000.0), 0_m, 1_m, {0.01}); for (size_t i = 0; i < 100; ++i) { - sim.SetInput(frc::MakeMatrix<1, 1>(0.0)); + sim.SetInput(Eigen::Vector{0.0}); sim.Update(20_ms); auto height = sim.GetPosition(); @@ -58,7 +57,7 @@ TEST(ElevatorSim, MinMax) { } for (size_t i = 0; i < 100; ++i) { - sim.SetInput(frc::MakeMatrix<1, 1>(12.0)); + sim.SetInput(Eigen::Vector{12.0}); sim.Update(20_ms); auto height = sim.GetPosition(); @@ -75,14 +74,14 @@ TEST(ElevatorSim, Stability) { frc::LinearSystem<2, 1, 1> system = frc::LinearSystemId::ElevatorSystem( m_elevatorGearbox, kCarriageMass, kElevatorDrumRadius, kElevatorGearing); - Eigen::Matrix x0 = frc::MakeMatrix<2, 1>(0.0, 0.0); - Eigen::Matrix u0 = frc::MakeMatrix<1, 1>(12.0); + Eigen::Vector x0{0.0, 0.0}; + Eigen::Vector u0{12.0}; - Eigen::Matrix x1 = frc::MakeMatrix<2, 1>(0.0, 0.0); + Eigen::Vector x1{0.0, 0.0}; for (size_t i = 0; i < 50; i++) { x1 = frc::RKDP( - [&](Eigen::Matrix x, - Eigen::Matrix u) -> Eigen::Matrix { + [&](const Eigen::Vector& x, + const Eigen::Vector& u) -> Eigen::Vector { return system.A() * x + system.B() * u; }, x1, u0, 0.020_s); diff --git a/wpilibc/src/test/native/cpp/simulation/SingleJointedArmSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/SingleJointedArmSimTest.cpp index f682fe7867..7046a5a785 100644 --- a/wpilibc/src/test/native/cpp/simulation/SingleJointedArmSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/SingleJointedArmSimTest.cpp @@ -10,10 +10,10 @@ TEST(SingleJointedArmTest, Disabled) { frc::sim::SingleJointedArmSim sim(frc::DCMotor::Vex775Pro(2), 100, 3_kg_sq_m, 9.5_in, -180_deg, 0_deg, 10_lb, true); - sim.SetState(frc::MakeMatrix<2, 1>(0.0, 0.0)); + sim.SetState(Eigen::Vector{0.0, 0.0}); for (size_t i = 0; i < 12 / 0.02; ++i) { - sim.SetInput(frc::MakeMatrix<1, 1>(0.0)); + sim.SetInput(Eigen::Vector{0.0}); sim.Update(20_ms); } diff --git a/wpilibc/src/test/native/cpp/simulation/StateSpaceSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/StateSpaceSimTest.cpp index 9fafe7c9ef..557e77b9ce 100644 --- a/wpilibc/src/test/native/cpp/simulation/StateSpaceSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/StateSpaceSimTest.cpp @@ -48,8 +48,8 @@ TEST(StateSpaceSimTest, TestFlywheelSim) { // Then, SimulationPeriodic runs frc::sim::RoboRioSim::SetVInVoltage( frc::sim::BatterySim::Calculate({sim.GetCurrentDraw()})); - sim.SetInput(frc::MakeMatrix<1, 1>( - motor.Get() * frc::RobotController::GetInputVoltage())); + sim.SetInput(Eigen::Vector{ + motor.Get() * frc::RobotController::GetInputVoltage()}); sim.Update(20_ms); encoderSim.SetRate(sim.GetAngularVelocity().to()); } diff --git a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp index ce0751facd..bb8a93de47 100644 --- a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp +++ b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -69,8 +68,8 @@ class Robot : public frc::TimedRobot { void SimulationPeriodic() override { // In this method, we update our simulation of what our arm is doing // First, we set our "inputs" (voltages) - m_armSim.SetInput(frc::MakeMatrix<1, 1>( - m_motor.Get() * frc::RobotController::GetInputVoltage())); + m_armSim.SetInput(Eigen::Vector{ + m_motor.Get() * frc::RobotController::GetInputVoltage()}); // Next, we update it. The standard loop time is 20ms. m_armSim.Update(20_ms); diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp index ece158b670..49c607d840 100644 --- a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp +++ b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -68,8 +67,8 @@ class Robot : public frc::TimedRobot { void SimulationPeriodic() override { // In this method, we update our simulation of what our elevator is doing // First, we set our "inputs" (voltages) - m_elevatorSim.SetInput(frc::MakeMatrix<1, 1>( - m_motor.Get() * frc::RobotController::GetInputVoltage())); + m_elevatorSim.SetInput(Eigen::Vector{ + m_motor.Get() * frc::RobotController::GetInputVoltage()}); // Next, we update it. The standard loop time is 20ms. m_elevatorSim.Update(20_ms); diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp index 3d28515b05..71233a30a8 100644 --- a/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp +++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp @@ -3,7 +3,6 @@ // the WPILib BSD license file in the root directory of this project. #include -#include #include #include #include @@ -100,7 +99,7 @@ class Robot : public frc::TimedRobot { void TeleopInit() override { m_loop.Reset( - frc::MakeMatrix<2, 1>(m_encoder.GetDistance(), m_encoder.GetRate())); + Eigen::Vector{m_encoder.GetDistance(), m_encoder.GetRate()}); m_lastProfiledReference = { units::radian_t(m_encoder.GetDistance()), @@ -123,12 +122,12 @@ class Robot : public frc::TimedRobot { m_lastProfiledReference)) .Calculate(20_ms); - m_loop.SetNextR( - frc::MakeMatrix<2, 1>(m_lastProfiledReference.position.to(), - m_lastProfiledReference.velocity.to())); + m_loop.SetNextR(Eigen::Vector{ + m_lastProfiledReference.position.to(), + m_lastProfiledReference.velocity.to()}); // Correct our Kalman filter's state vector estimate with encoder data. - m_loop.Correct(frc::MakeMatrix<1, 1>(m_encoder.GetDistance())); + m_loop.Correct(Eigen::Vector{m_encoder.GetDistance()}); // Update our LQR to generate new voltage commands and use the voltages to // predict the next state with out Kalman filter. diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp index 95471f87d8..70a3ac6bb8 100644 --- a/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp +++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp @@ -3,7 +3,6 @@ // the WPILib BSD license file in the root directory of this project. #include -#include #include #include #include @@ -98,7 +97,7 @@ class Robot : public frc::TimedRobot { void TeleopInit() override { // Reset our loop to make sure it's in a known state. m_loop.Reset( - frc::MakeMatrix<2, 1>(m_encoder.GetDistance(), m_encoder.GetRate())); + Eigen::Vector{m_encoder.GetDistance(), m_encoder.GetRate()}); m_lastProfiledReference = {units::meter_t(m_encoder.GetDistance()), units::meters_per_second_t(m_encoder.GetRate())}; @@ -120,12 +119,12 @@ class Robot : public frc::TimedRobot { m_lastProfiledReference)) .Calculate(20_ms); - m_loop.SetNextR( - frc::MakeMatrix<2, 1>(m_lastProfiledReference.position.to(), - m_lastProfiledReference.velocity.to())); + m_loop.SetNextR(Eigen::Vector{ + m_lastProfiledReference.position.to(), + m_lastProfiledReference.velocity.to()}); // Correct our Kalman filter's state vector estimate with encoder data. - m_loop.Correct(frc::MakeMatrix<1, 1>(m_encoder.GetDistance())); + m_loop.Correct(Eigen::Vector{m_encoder.GetDistance()}); // Update our LQR to generate new voltage commands and use the voltages to // predict the next state with out Kalman filter. diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheel/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheel/cpp/Robot.cpp index 5c07ee8686..1e9e6851a1 100644 --- a/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheel/cpp/Robot.cpp +++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheel/cpp/Robot.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -86,7 +85,7 @@ class Robot : public frc::TimedRobot { } void TeleopInit() override { - m_loop.Reset(frc::MakeMatrix<1, 1>(m_encoder.GetRate())); + m_loop.Reset(Eigen::Vector{m_encoder.GetRate()}); } void TeleopPeriodic() override { @@ -94,14 +93,14 @@ class Robot : public frc::TimedRobot { // setpoint of a PID controller. if (m_joystick.GetRightBumper()) { // We pressed the bumper, so let's set our next reference - m_loop.SetNextR(frc::MakeMatrix<1, 1>(kSpinup.to())); + m_loop.SetNextR(Eigen::Vector{kSpinup.to()}); } else { // We released the bumper, so let's spin down - m_loop.SetNextR(frc::MakeMatrix<1, 1>(0.0)); + m_loop.SetNextR(Eigen::Vector{0.0}); } // Correct our Kalman filter's state vector estimate with encoder data. - m_loop.Correct(frc::MakeMatrix<1, 1>(m_encoder.GetRate())); + m_loop.Correct(Eigen::Vector{m_encoder.GetRate()}); // Update our LQR to generate new voltage commands and use the voltages to // predict the next state with out Kalman filter. diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheelSysId/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheelSysId/cpp/Robot.cpp index 0f3e36315f..32f6ceca28 100644 --- a/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheelSysId/cpp/Robot.cpp +++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceFlywheelSysId/cpp/Robot.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -87,7 +86,7 @@ class Robot : public frc::TimedRobot { } void TeleopInit() override { - m_loop.Reset(frc::MakeMatrix<1, 1>(m_encoder.GetRate())); + m_loop.Reset(Eigen::Vector{m_encoder.GetRate()}); } void TeleopPeriodic() override { @@ -95,14 +94,14 @@ class Robot : public frc::TimedRobot { // setpoint of a PID controller. if (m_joystick.GetRightBumper()) { // We pressed the bumper, so let's set our next reference - m_loop.SetNextR(frc::MakeMatrix<1, 1>(kSpinup.to())); + m_loop.SetNextR(Eigen::Vector{kSpinup.to()}); } else { // We released the bumper, so let's spin down - m_loop.SetNextR(frc::MakeMatrix<1, 1>(0.0)); + m_loop.SetNextR(Eigen::Vector{0.0}); } // Correct our Kalman filter's state vector estimate with encoder data. - m_loop.Correct(frc::MakeMatrix<1, 1>(m_encoder.GetRate())); + m_loop.Correct(Eigen::Vector{m_encoder.GetRate()}); // Update our LQR to generate new voltage commands and use the voltages to // predict the next state with out Kalman filter. diff --git a/wpimath/src/main/java/edu/wpi/first/math/kinematics/MecanumDriveKinematics.java b/wpimath/src/main/java/edu/wpi/first/math/kinematics/MecanumDriveKinematics.java index d613135fbb..3ea39e5d26 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/kinematics/MecanumDriveKinematics.java +++ b/wpimath/src/main/java/edu/wpi/first/math/kinematics/MecanumDriveKinematics.java @@ -109,12 +109,12 @@ public class MecanumDriveKinematics { chassisSpeeds.vyMetersPerSecond, chassisSpeeds.omegaRadiansPerSecond); - var wheelsMatrix = m_inverseKinematics.mult(chassisSpeedsVector); + var wheelsVector = m_inverseKinematics.mult(chassisSpeedsVector); return new MecanumDriveWheelSpeeds( - wheelsMatrix.get(0, 0), - wheelsMatrix.get(1, 0), - wheelsMatrix.get(2, 0), - wheelsMatrix.get(3, 0)); + wheelsVector.get(0, 0), + wheelsVector.get(1, 0), + wheelsVector.get(2, 0), + wheelsVector.get(3, 0)); } /** @@ -137,15 +137,15 @@ public class MecanumDriveKinematics { * @return The resulting chassis speed. */ public ChassisSpeeds toChassisSpeeds(MecanumDriveWheelSpeeds wheelSpeeds) { - var wheelSpeedsMatrix = new SimpleMatrix(4, 1); - wheelSpeedsMatrix.setColumn( + var wheelSpeedsVector = new SimpleMatrix(4, 1); + wheelSpeedsVector.setColumn( 0, 0, wheelSpeeds.frontLeftMetersPerSecond, wheelSpeeds.frontRightMetersPerSecond, wheelSpeeds.rearLeftMetersPerSecond, wheelSpeeds.rearRightMetersPerSecond); - var chassisSpeedsVector = m_forwardKinematics.mult(wheelSpeedsMatrix); + var chassisSpeedsVector = m_forwardKinematics.mult(wheelSpeedsVector); return new ChassisSpeeds( chassisSpeedsVector.get(0, 0), diff --git a/wpimath/src/main/native/cpp/StateSpaceUtil.cpp b/wpimath/src/main/native/cpp/StateSpaceUtil.cpp index 09a4b7873f..869a2bb71a 100644 --- a/wpimath/src/main/native/cpp/StateSpaceUtil.cpp +++ b/wpimath/src/main/native/cpp/StateSpaceUtil.cpp @@ -6,16 +6,16 @@ namespace frc { -Eigen::Matrix PoseTo3dVector(const Pose2d& pose) { - return frc::MakeMatrix<3, 1>(pose.Translation().X().to(), - pose.Translation().Y().to(), - pose.Rotation().Radians().to()); +Eigen::Vector PoseTo3dVector(const Pose2d& pose) { + return Eigen::Vector{pose.Translation().X().to(), + pose.Translation().Y().to(), + pose.Rotation().Radians().to()}; } -Eigen::Matrix PoseTo4dVector(const Pose2d& pose) { - return frc::MakeMatrix<4, 1>(pose.Translation().X().to(), - pose.Translation().Y().to(), - pose.Rotation().Cos(), pose.Rotation().Sin()); +Eigen::Vector PoseTo4dVector(const Pose2d& pose) { + return Eigen::Vector{pose.Translation().X().to(), + pose.Translation().Y().to(), + pose.Rotation().Cos(), pose.Rotation().Sin()}; } template <> @@ -30,9 +30,9 @@ bool IsStabilizable<2, 1>(const Eigen::Matrix& A, return detail::IsStabilizableImpl<2, 1>(A, B); } -Eigen::Matrix PoseToVector(const Pose2d& pose) { - return frc::MakeMatrix<3, 1>(pose.X().to(), pose.Y().to(), - pose.Rotation().Radians().to()); +Eigen::Vector PoseToVector(const Pose2d& pose) { + return Eigen::Vector{pose.X().to(), pose.Y().to(), + pose.Rotation().Radians().to()}; } } // namespace frc diff --git a/wpimath/src/main/native/cpp/estimator/DifferentialDrivePoseEstimator.cpp b/wpimath/src/main/native/cpp/estimator/DifferentialDrivePoseEstimator.cpp index 8ec18eb27b..a82384b13d 100644 --- a/wpimath/src/main/native/cpp/estimator/DifferentialDrivePoseEstimator.cpp +++ b/wpimath/src/main/native/cpp/estimator/DifferentialDrivePoseEstimator.cpp @@ -19,9 +19,9 @@ DifferentialDrivePoseEstimator::DifferentialDrivePoseEstimator( units::second_t nominalDt) : m_observer( &DifferentialDrivePoseEstimator::F, - [](const Eigen::Matrix& x, - const Eigen::Matrix& u) { - return frc::MakeMatrix<3, 1>(x(3, 0), x(4, 0), x(2, 0)); + [](const Eigen::Vector& x, + const Eigen::Vector& u) { + return Eigen::Vector{x(3, 0), x(4, 0), x(2, 0)}; }, stateStdDevs, localMeasurementStdDevs, frc::AngleMean<5, 5>(2), frc::AngleMean<3, 5>(2), frc::AngleResidual<5>(2), @@ -30,12 +30,13 @@ DifferentialDrivePoseEstimator::DifferentialDrivePoseEstimator( SetVisionMeasurementStdDevs(visionMeasurmentStdDevs); // Create correction mechanism for vision measurements. - m_visionCorrect = [&](const Eigen::Matrix& u, - const Eigen::Matrix& y) { + m_visionCorrect = [&](const Eigen::Vector& u, + const Eigen::Vector& y) { m_observer.Correct<3>( u, y, - [](const Eigen::Matrix& x, - const Eigen::Matrix&) { return x.block<3, 1>(0, 0); }, + [](const Eigen::Vector& x, const Eigen::Vector&) { + return x.block<3, 1>(0, 0); + }, m_visionContR, frc::AngleMean<3, 5>(2), frc::AngleResidual<3>(2), frc::AngleResidual<5>(2), frc::AngleAdd<5>(2)); }; @@ -94,15 +95,15 @@ Pose2d DifferentialDrivePoseEstimator::UpdateWithTime( auto angle = gyroAngle + m_gyroOffset; auto omega = (gyroAngle - m_previousAngle).Radians() / dt; - auto u = frc::MakeMatrix<3, 1>( + auto u = Eigen::Vector{ (wheelSpeeds.left + wheelSpeeds.right).to() / 2.0, 0.0, - omega.to()); + omega.to()}; m_previousAngle = angle; - auto localY = frc::MakeMatrix<3, 1>(leftDistance.to(), - rightDistance.to(), - angle.Radians().to()); + auto localY = Eigen::Vector{leftDistance.to(), + rightDistance.to(), + angle.Radians().to()}; m_latencyCompensator.AddObserverState(m_observer, u, localY, currentTime); m_observer.Predict(u, dt); @@ -111,26 +112,24 @@ Pose2d DifferentialDrivePoseEstimator::UpdateWithTime( return GetEstimatedPosition(); } -Eigen::Matrix DifferentialDrivePoseEstimator::F( - const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector DifferentialDrivePoseEstimator::F( + const Eigen::Vector& x, const Eigen::Vector& u) { // Apply a rotation matrix. Note that we do not add x because Runge-Kutta does // that for us. - auto& theta = x(2, 0); - Eigen::Matrix toFieldRotation = frc::MakeMatrix<5, 5>( - // clang-format off - std::cos(theta), -std::sin(theta), 0.0, 0.0, 0.0, - std::sin(theta), std::cos(theta), 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 1.0); // clang-format on + auto& theta = x(2); + Eigen::Matrix toFieldRotation{ + {std::cos(theta), -std::sin(theta), 0.0, 0.0, 0.0}, + {std::sin(theta), std::cos(theta), 0.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 1.0}}; return toFieldRotation * - frc::MakeMatrix<5, 1>(u(0, 0), u(1, 0), u(2, 0), u(0, 0), u(1, 0)); + Eigen::Vector{u(0, 0), u(1, 0), u(2, 0), u(0, 0), u(1, 0)}; } template wpi::array DifferentialDrivePoseEstimator::StdDevMatrixToArray( - const Eigen::Matrix& stdDevs) { + const Eigen::Vector& stdDevs) { wpi::array array; for (size_t i = 0; i < Dim; ++i) { array[i] = stdDevs(i); @@ -138,11 +137,11 @@ wpi::array DifferentialDrivePoseEstimator::StdDevMatrixToArray( return array; } -Eigen::Matrix DifferentialDrivePoseEstimator::FillStateVector( +Eigen::Vector DifferentialDrivePoseEstimator::FillStateVector( const Pose2d& pose, units::meter_t leftDistance, units::meter_t rightDistance) { - return frc::MakeMatrix<5, 1>( + return Eigen::Vector{ pose.Translation().X().to(), pose.Translation().Y().to(), pose.Rotation().Radians().to(), leftDistance.to(), - rightDistance.to()); + rightDistance.to()}; } diff --git a/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp b/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp index ef086bd73e..0d1413d9e0 100644 --- a/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp +++ b/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp @@ -18,26 +18,26 @@ frc::MecanumDrivePoseEstimator::MecanumDrivePoseEstimator( const wpi::array& localMeasurementStdDevs, const wpi::array& visionMeasurementStdDevs, units::second_t nominalDt) - : m_observer([](const Eigen::Matrix& x, - const Eigen::Matrix& u) { return u; }, - [](const Eigen::Matrix& x, - const Eigen::Matrix& u) { - return x.block<1, 1>(2, 0); - }, - stateStdDevs, localMeasurementStdDevs, frc::AngleMean<3, 3>(2), - frc::AngleMean<1, 3>(0), frc::AngleResidual<3>(2), - frc::AngleResidual<1>(0), frc::AngleAdd<3>(2), nominalDt), + : m_observer( + [](const Eigen::Vector& x, + const Eigen::Vector& u) { return u; }, + [](const Eigen::Vector& x, + const Eigen::Vector& u) { return x.block<1, 1>(2, 0); }, + stateStdDevs, localMeasurementStdDevs, frc::AngleMean<3, 3>(2), + frc::AngleMean<1, 3>(0), frc::AngleResidual<3>(2), + frc::AngleResidual<1>(0), frc::AngleAdd<3>(2), nominalDt), m_kinematics(kinematics), m_nominalDt(nominalDt) { SetVisionMeasurementStdDevs(visionMeasurementStdDevs); // Create vision correction mechanism. - m_visionCorrect = [&](const Eigen::Matrix& u, - const Eigen::Matrix& y) { + m_visionCorrect = [&](const Eigen::Vector& u, + const Eigen::Vector& y) { m_observer.Correct<3>( u, y, - [](const Eigen::Matrix& x, - const Eigen::Matrix&) { return x; }, + [](const Eigen::Vector& x, const Eigen::Vector&) { + return x; + }, m_visionContR, frc::AngleMean<3, 3>(2), frc::AngleResidual<3>(2), frc::AngleResidual<3>(2), frc::AngleAdd<3>(2)); }; @@ -100,11 +100,11 @@ Pose2d frc::MecanumDrivePoseEstimator::UpdateWithTime( Translation2d(chassisSpeeds.vx * 1_s, chassisSpeeds.vy * 1_s) .RotateBy(angle); - auto u = frc::MakeMatrix<3, 1>(fieldRelativeVelocities.X().to(), - fieldRelativeVelocities.Y().to(), - omega.to()); + Eigen::Vector u{fieldRelativeVelocities.X().to(), + fieldRelativeVelocities.Y().to(), + omega.to()}; - auto localY = frc::MakeMatrix<1, 1>(angle.Radians().template to()); + Eigen::Vector localY{angle.Radians().template to()}; m_previousAngle = angle; m_latencyCompensator.AddObserverState(m_observer, u, localY, currentTime); diff --git a/wpimath/src/main/native/cpp/kinematics/MecanumDriveKinematics.cpp b/wpimath/src/main/native/cpp/kinematics/MecanumDriveKinematics.cpp index a89e4f9fed..7f2f75daf4 100644 --- a/wpimath/src/main/native/cpp/kinematics/MecanumDriveKinematics.cpp +++ b/wpimath/src/main/native/cpp/kinematics/MecanumDriveKinematics.cpp @@ -21,31 +21,29 @@ MecanumDriveWheelSpeeds MecanumDriveKinematics::ToWheelSpeeds( m_previousCoR = centerOfRotation; } - Eigen::Vector3d chassisSpeedsVector; - chassisSpeedsVector << chassisSpeeds.vx.to(), - chassisSpeeds.vy.to(), chassisSpeeds.omega.to(); + Eigen::Vector3d chassisSpeedsVector{chassisSpeeds.vx.to(), + chassisSpeeds.vy.to(), + chassisSpeeds.omega.to()}; - Eigen::Matrix wheelsMatrix = + Eigen::Vector wheelsVector = m_inverseKinematics * chassisSpeedsVector; MecanumDriveWheelSpeeds wheelSpeeds; - wheelSpeeds.frontLeft = units::meters_per_second_t{wheelsMatrix(0, 0)}; - wheelSpeeds.frontRight = units::meters_per_second_t{wheelsMatrix(1, 0)}; - wheelSpeeds.rearLeft = units::meters_per_second_t{wheelsMatrix(2, 0)}; - wheelSpeeds.rearRight = units::meters_per_second_t{wheelsMatrix(3, 0)}; + wheelSpeeds.frontLeft = units::meters_per_second_t{wheelsVector(0)}; + wheelSpeeds.frontRight = units::meters_per_second_t{wheelsVector(1)}; + wheelSpeeds.rearLeft = units::meters_per_second_t{wheelsVector(2)}; + wheelSpeeds.rearRight = units::meters_per_second_t{wheelsVector(3)}; return wheelSpeeds; } ChassisSpeeds MecanumDriveKinematics::ToChassisSpeeds( const MecanumDriveWheelSpeeds& wheelSpeeds) const { - Eigen::Matrix wheelSpeedsMatrix; - // clang-format off - wheelSpeedsMatrix << wheelSpeeds.frontLeft.to(), wheelSpeeds.frontRight.to(), - wheelSpeeds.rearLeft.to(), wheelSpeeds.rearRight.to(); - // clang-format on + Eigen::Vector wheelSpeedsVector{ + wheelSpeeds.frontLeft.to(), wheelSpeeds.frontRight.to(), + wheelSpeeds.rearLeft.to(), wheelSpeeds.rearRight.to()}; Eigen::Vector3d chassisSpeedsVector = - m_forwardKinematics.solve(wheelSpeedsMatrix); + m_forwardKinematics.solve(wheelSpeedsVector); return {units::meters_per_second_t{chassisSpeedsVector(0)}, // NOLINT units::meters_per_second_t{chassisSpeedsVector(1)}, @@ -56,10 +54,9 @@ void MecanumDriveKinematics::SetInverseKinematics(Translation2d fl, Translation2d fr, Translation2d rl, Translation2d rr) const { - // clang-format off - m_inverseKinematics << 1, -1, (-(fl.X() + fl.Y())).template to(), - 1, 1, (fr.X() - fr.Y()).template to(), - 1, 1, (rl.X() - rl.Y()).template to(), - 1, -1, (-(rr.X() + rr.Y())).template to(); - // clang-format on + m_inverseKinematics = Eigen::Matrix{ + {1, -1, (-(fl.X() + fl.Y())).template to()}, + {1, 1, (fr.X() - fr.Y()).template to()}, + {1, 1, (rl.X() - rl.Y()).template to()}, + {1, -1, (-(rr.X() + rr.Y())).template to()}}; } diff --git a/wpimath/src/main/native/include/frc/StateSpaceUtil.h b/wpimath/src/main/native/include/frc/StateSpaceUtil.h index 064fac381c..2d41915169 100644 --- a/wpimath/src/main/native/include/frc/StateSpaceUtil.h +++ b/wpimath/src/main/native/include/frc/StateSpaceUtil.h @@ -10,6 +10,7 @@ #include #include +#include #include "Eigen/Core" #include "Eigen/Eigenvalues" @@ -60,7 +61,7 @@ void WhiteNoiseVectorImpl(Matrix& result, T elem, Ts... elems) { template bool IsStabilizableImpl(const Eigen::Matrix& A, const Eigen::Matrix& B) { - Eigen::EigenSolver> es(A); + Eigen::EigenSolver> es{A}; for (int i = 0; i < States; ++i) { if (es.eigenvalues()[i].real() * es.eigenvalues()[i].real() + @@ -94,10 +95,13 @@ bool IsStabilizableImpl(const Eigen::Matrix& A, * * @param elems An array of elements in the matrix. * @return A matrix containing the given elements. + * @deprecated Use Eigen::Matrix or Eigen::Vector initializer list constructor. */ template ...>>> +WPI_DEPRECATED( + "Use Eigen::Matrix or Eigen::Vector initializer list constructor") Eigen::Matrix MakeMatrix(Ts... elems) { static_assert( sizeof...(elems) == Rows * Cols, @@ -212,12 +216,12 @@ Eigen::Matrix MakeWhiteNoiseVector(Ts... stdDevs) { * @return White noise vector. */ template -Eigen::Matrix MakeWhiteNoiseVector( +Eigen::Vector MakeWhiteNoiseVector( const std::array& stdDevs) { std::random_device rd; std::mt19937 gen{rd()}; - Eigen::Matrix result; + Eigen::Vector result; for (int i = 0; i < N; ++i) { // Passing a standard deviation of 0.0 to std::normal_distribution is // undefined behavior @@ -239,7 +243,7 @@ Eigen::Matrix MakeWhiteNoiseVector( * @return The vector. */ WPILIB_DLLEXPORT -Eigen::Matrix PoseTo3dVector(const Pose2d& pose); +Eigen::Vector PoseTo3dVector(const Pose2d& pose); /** * Converts a Pose2d into a vector of [x, y, std::cos(theta), std::sin(theta)]. @@ -249,7 +253,7 @@ Eigen::Matrix PoseTo3dVector(const Pose2d& pose); * @return The vector. */ WPILIB_DLLEXPORT -Eigen::Matrix PoseTo4dVector(const Pose2d& pose); +Eigen::Vector PoseTo4dVector(const Pose2d& pose); /** * Returns true if (A, B) is a stabilizable pair. @@ -287,7 +291,7 @@ WPILIB_DLLEXPORT bool IsStabilizable<2, 1>( * @return The vector. */ WPILIB_DLLEXPORT -Eigen::Matrix PoseToVector(const Pose2d& pose); +Eigen::Vector PoseToVector(const Pose2d& pose); /** * Clamps input vector between system's minimum and maximum allowable input. @@ -296,11 +300,11 @@ Eigen::Matrix PoseToVector(const Pose2d& pose); * @return Clamped input vector. */ template -Eigen::Matrix ClampInputMaxMagnitude( - const Eigen::Matrix& u, - const Eigen::Matrix& umin, - const Eigen::Matrix& umax) { - Eigen::Matrix result; +Eigen::Vector ClampInputMaxMagnitude( + const Eigen::Vector& u, + const Eigen::Vector& umin, + const Eigen::Vector& umax) { + Eigen::Vector result; for (int i = 0; i < Inputs; ++i) { result(i) = std::clamp(u(i), umin(i), umax(i)); } @@ -317,8 +321,8 @@ Eigen::Matrix ClampInputMaxMagnitude( * @return The normalizedInput */ template -Eigen::Matrix NormalizeInputVector( - const Eigen::Matrix& u, double maxMagnitude) { +Eigen::Vector NormalizeInputVector( + const Eigen::Vector& u, double maxMagnitude) { double maxValue = u.template lpNorm(); if (maxValue > maxMagnitude) { diff --git a/wpimath/src/main/native/include/frc/controller/ControlAffinePlantInversionFeedforward.h b/wpimath/src/main/native/include/frc/controller/ControlAffinePlantInversionFeedforward.h index 50970284c1..1d60b86789 100644 --- a/wpimath/src/main/native/include/frc/controller/ControlAffinePlantInversionFeedforward.h +++ b/wpimath/src/main/native/include/frc/controller/ControlAffinePlantInversionFeedforward.h @@ -47,15 +47,15 @@ class ControlAffinePlantInversionFeedforward { * @param dt The timestep between calls of calculate(). */ ControlAffinePlantInversionFeedforward( - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&, + const Eigen::Vector&)> f, units::second_t dt) : m_dt(dt), m_f(f) { m_B = NumericalJacobianU( - f, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); + f, Eigen::Vector::Zero(), + Eigen::Vector::Zero()); Reset(); } @@ -70,14 +70,14 @@ class ControlAffinePlantInversionFeedforward { * @param dt The timestep between calls of calculate(). */ ControlAffinePlantInversionFeedforward( - std::function( - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&)> f, const Eigen::Matrix& B, units::second_t dt) : m_B(B), m_dt(dt) { - m_f = [=](const Eigen::Matrix& x, - const Eigen::Matrix& u) - -> Eigen::Matrix { return f(x); }; + m_f = [=](const Eigen::Vector& x, + const Eigen::Vector& u) + -> Eigen::Vector { return f(x); }; Reset(); } @@ -92,7 +92,7 @@ class ControlAffinePlantInversionFeedforward { * * @return The calculated feedforward. */ - const Eigen::Matrix& Uff() const { return m_uff; } + const Eigen::Vector& Uff() const { return m_uff; } /** * Returns an element of the previously calculated feedforward. @@ -108,7 +108,7 @@ class ControlAffinePlantInversionFeedforward { * * @return The current reference vector. */ - const Eigen::Matrix& R() const { return m_r; } + const Eigen::Vector& R() const { return m_r; } /** * Returns an element of the reference vector r. @@ -124,7 +124,7 @@ class ControlAffinePlantInversionFeedforward { * * @param initialState The initial state vector. */ - void Reset(const Eigen::Matrix& initialState) { + void Reset(const Eigen::Vector& initialState) { m_r = initialState; m_uff.setZero(); } @@ -142,16 +142,16 @@ class ControlAffinePlantInversionFeedforward { * future reference. This uses the internally stored "current" * reference. * - * If this method is used the initial state of the system is the one - * set using Reset(const Eigen::Matrix&). - * If the initial state is not set it defaults to a zero vector. + * If this method is used the initial state of the system is the one set using + * Reset(const Eigen::Vector&). If the initial state is not + * set it defaults to a zero vector. * * @param nextR The reference state of the future timestep (k + dt). * * @return The calculated feedforward. */ - Eigen::Matrix Calculate( - const Eigen::Matrix& nextR) { + Eigen::Vector Calculate( + const Eigen::Vector& nextR) { return Calculate(m_r, nextR); } @@ -163,13 +163,13 @@ class ControlAffinePlantInversionFeedforward { * * @return The calculated feedforward. */ - Eigen::Matrix Calculate( - const Eigen::Matrix& r, - const Eigen::Matrix& nextR) { - Eigen::Matrix rDot = (nextR - r) / m_dt.to(); + Eigen::Vector Calculate( + const Eigen::Vector& r, + const Eigen::Vector& nextR) { + Eigen::Vector rDot = (nextR - r) / m_dt.to(); m_uff = m_B.householderQr().solve( - rDot - m_f(r, Eigen::Matrix::Zero())); + rDot - m_f(r, Eigen::Vector::Zero())); m_r = nextR; return m_uff; @@ -183,16 +183,16 @@ class ControlAffinePlantInversionFeedforward { /** * The model dynamics. */ - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> m_f; // Current reference - Eigen::Matrix m_r; + Eigen::Vector m_r; // Computed feedforward - Eigen::Matrix m_uff; + Eigen::Vector m_uff; }; } // namespace frc diff --git a/wpimath/src/main/native/include/frc/controller/LinearPlantInversionFeedforward.h b/wpimath/src/main/native/include/frc/controller/LinearPlantInversionFeedforward.h index be25a72738..cb4f907d1b 100644 --- a/wpimath/src/main/native/include/frc/controller/LinearPlantInversionFeedforward.h +++ b/wpimath/src/main/native/include/frc/controller/LinearPlantInversionFeedforward.h @@ -59,7 +59,7 @@ class LinearPlantInversionFeedforward { * * @return The calculated feedforward. */ - const Eigen::Matrix& Uff() const { return m_uff; } + const Eigen::Vector& Uff() const { return m_uff; } /** * Returns an element of the previously calculated feedforward. @@ -75,7 +75,7 @@ class LinearPlantInversionFeedforward { * * @return The current reference vector. */ - const Eigen::Matrix& R() const { return m_r; } + const Eigen::Vector& R() const { return m_r; } /** * Returns an element of the reference vector r. @@ -91,7 +91,7 @@ class LinearPlantInversionFeedforward { * * @param initialState The initial state vector. */ - void Reset(const Eigen::Matrix& initialState) { + void Reset(const Eigen::Vector& initialState) { m_r = initialState; m_uff.setZero(); } @@ -109,16 +109,16 @@ class LinearPlantInversionFeedforward { * future reference. This uses the internally stored "current" * reference. * - * If this method is used the initial state of the system is the one - * set using Reset(const Eigen::Matrix&). - * If the initial state is not set it defaults to a zero vector. + * If this method is used the initial state of the system is the one set using + * Reset(const Eigen::Vector&). If the initial state is not + * set it defaults to a zero vector. * * @param nextR The reference state of the future timestep (k + dt). * * @return The calculated feedforward. */ - Eigen::Matrix Calculate( - const Eigen::Matrix& nextR) { + Eigen::Vector Calculate( + const Eigen::Vector& nextR) { return Calculate(m_r, nextR); // NOLINT } @@ -130,9 +130,9 @@ class LinearPlantInversionFeedforward { * * @return The calculated feedforward. */ - Eigen::Matrix Calculate( - const Eigen::Matrix& r, - const Eigen::Matrix& nextR) { + Eigen::Vector Calculate( + const Eigen::Vector& r, + const Eigen::Vector& nextR) { m_uff = m_B.householderQr().solve(nextR - (m_A * r)); m_r = nextR; return m_uff; @@ -145,10 +145,10 @@ class LinearPlantInversionFeedforward { units::second_t m_dt; // Current reference - Eigen::Matrix m_r; + Eigen::Vector m_r; // Computed feedforward - Eigen::Matrix m_uff; + Eigen::Vector m_uff; }; } // namespace frc diff --git a/wpimath/src/main/native/include/frc/controller/LinearQuadraticRegulator.h b/wpimath/src/main/native/include/frc/controller/LinearQuadraticRegulator.h index 424af044d7..c324702b81 100644 --- a/wpimath/src/main/native/include/frc/controller/LinearQuadraticRegulator.h +++ b/wpimath/src/main/native/include/frc/controller/LinearQuadraticRegulator.h @@ -146,7 +146,7 @@ class LinearQuadraticRegulatorImpl { * * @return The reference vector. */ - const Eigen::Matrix& R() const { return m_r; } + const Eigen::Vector& R() const { return m_r; } /** * Returns an element of the reference vector r. @@ -162,7 +162,7 @@ class LinearQuadraticRegulatorImpl { * * @return The control input. */ - const Eigen::Matrix& U() const { return m_u; } + const Eigen::Vector& U() const { return m_u; } /** * Returns an element of the control input vector u. @@ -186,8 +186,8 @@ class LinearQuadraticRegulatorImpl { * * @param x The current state x. */ - Eigen::Matrix Calculate( - const Eigen::Matrix& x) { + Eigen::Vector Calculate( + const Eigen::Vector& x) { m_u = m_K * (m_r - x); return m_u; } @@ -198,9 +198,9 @@ class LinearQuadraticRegulatorImpl { * @param x The current state x. * @param nextR The next reference vector r. */ - Eigen::Matrix Calculate( - const Eigen::Matrix& x, - const Eigen::Matrix& nextR) { + Eigen::Vector Calculate( + const Eigen::Vector& x, + const Eigen::Vector& nextR) { m_r = nextR; return Calculate(x); } @@ -233,10 +233,10 @@ class LinearQuadraticRegulatorImpl { private: // Current reference - Eigen::Matrix m_r; + Eigen::Vector m_r; // Computed controller output - Eigen::Matrix m_u; + Eigen::Vector m_u; // Controller gain Eigen::Matrix m_K; diff --git a/wpimath/src/main/native/include/frc/controller/SimpleMotorFeedforward.h b/wpimath/src/main/native/include/frc/controller/SimpleMotorFeedforward.h index da125de18a..a00d343081 100644 --- a/wpimath/src/main/native/include/frc/controller/SimpleMotorFeedforward.h +++ b/wpimath/src/main/native/include/frc/controller/SimpleMotorFeedforward.h @@ -70,11 +70,8 @@ class SimpleMotorFeedforward { auto plant = LinearSystemId::IdentifyVelocitySystem(kV, kA); LinearPlantInversionFeedforward<1, 1> feedforward{plant, dt}; - Eigen::Matrix r; - r << currentVelocity.template to(); - - Eigen::Matrix nextR; - nextR << nextVelocity.template to(); + Eigen::Vector r{currentVelocity.template to()}; + Eigen::Vector nextR{nextVelocity.template to()}; return kS * wpi::sgn(currentVelocity.template to()) + units::volt_t{feedforward.Calculate(r, nextR)(0)}; diff --git a/wpimath/src/main/native/include/frc/estimator/AngleStatistics.h b/wpimath/src/main/native/include/frc/estimator/AngleStatistics.h index 9b4a958f27..30d2b41ae3 100644 --- a/wpimath/src/main/native/include/frc/estimator/AngleStatistics.h +++ b/wpimath/src/main/native/include/frc/estimator/AngleStatistics.h @@ -20,10 +20,10 @@ namespace frc { * @param angleStateIdx The row containing angles to be normalized. */ template -Eigen::Matrix AngleResidual( - const Eigen::Matrix& a, - const Eigen::Matrix& b, int angleStateIdx) { - Eigen::Matrix ret = a - b; +Eigen::Vector AngleResidual( + const Eigen::Vector& a, + const Eigen::Vector& b, int angleStateIdx) { + Eigen::Vector ret = a - b; ret[angleStateIdx] = AngleModulus(units::radian_t{ret[angleStateIdx]}).to(); return ret; @@ -36,9 +36,8 @@ Eigen::Matrix AngleResidual( * @param angleStateIdx The row containing angles to be normalized. */ template -std::function< - Eigen::Matrix(const Eigen::Matrix&, - const Eigen::Matrix&)> +std::function( + const Eigen::Vector&, const Eigen::Vector&)> AngleResidual(int angleStateIdx) { return [=](auto a, auto b) { return AngleResidual(a, b, angleStateIdx); @@ -54,10 +53,10 @@ AngleResidual(int angleStateIdx) { * @param angleStateIdx The row containing angles to be normalized. */ template -Eigen::Matrix AngleAdd( - const Eigen::Matrix& a, - const Eigen::Matrix& b, int angleStateIdx) { - Eigen::Matrix ret = a + b; +Eigen::Vector AngleAdd(const Eigen::Vector& a, + const Eigen::Vector& b, + int angleStateIdx) { + Eigen::Vector ret = a + b; ret[angleStateIdx] = InputModulus(ret[angleStateIdx], -wpi::numbers::pi, wpi::numbers::pi); return ret; @@ -70,9 +69,8 @@ Eigen::Matrix AngleAdd( * @param angleStateIdx The row containing angles to be normalized. */ template -std::function< - Eigen::Matrix(const Eigen::Matrix&, - const Eigen::Matrix&)> +std::function( + const Eigen::Vector&, const Eigen::Vector&)> AngleAdd(int angleStateIdx) { return [=](auto a, auto b) { return AngleAdd(a, b, angleStateIdx); }; } @@ -86,9 +84,9 @@ AngleAdd(int angleStateIdx) { * @param angleStateIdx The row containing the angles. */ template -Eigen::Matrix AngleMean( +Eigen::Vector AngleMean( const Eigen::Matrix& sigmas, - const Eigen::Matrix& Wm, int angleStatesIdx) { + const Eigen::Vector& Wm, int angleStatesIdx) { double sumSin = sigmas.row(angleStatesIdx) .unaryExpr([](auto it) { return std::sin(it); }) .sum(); @@ -96,7 +94,7 @@ Eigen::Matrix AngleMean( .unaryExpr([](auto it) { return std::cos(it); }) .sum(); - Eigen::Matrix ret = sigmas * Wm; + Eigen::Vector ret = sigmas * Wm; ret[angleStatesIdx] = std::atan2(sumSin, sumCos); return ret; } @@ -108,9 +106,9 @@ Eigen::Matrix AngleMean( * @param angleStateIdx The row containing the angles. */ template -std::function( +std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> AngleMean(int angleStateIdx) { return [=](auto sigmas, auto Wm) { return AngleMean(sigmas, Wm, angleStateIdx); diff --git a/wpimath/src/main/native/include/frc/estimator/DifferentialDrivePoseEstimator.h b/wpimath/src/main/native/include/frc/estimator/DifferentialDrivePoseEstimator.h index e59b162e64..4c875b0803 100644 --- a/wpimath/src/main/native/include/frc/estimator/DifferentialDrivePoseEstimator.h +++ b/wpimath/src/main/native/include/frc/estimator/DifferentialDrivePoseEstimator.h @@ -209,8 +209,8 @@ class WPILIB_DLLEXPORT DifferentialDrivePoseEstimator { UnscentedKalmanFilter<5, 3, 3> m_observer; KalmanFilterLatencyCompensator<5, 3, 3, UnscentedKalmanFilter<5, 3, 3>> m_latencyCompensator; - std::function& u, - const Eigen::Matrix& y)> + std::function& u, + const Eigen::Vector& y)> m_visionCorrect; Eigen::Matrix m_visionContR; @@ -223,13 +223,13 @@ class WPILIB_DLLEXPORT DifferentialDrivePoseEstimator { template static wpi::array StdDevMatrixToArray( - const Eigen::Matrix& stdDevs); + const Eigen::Vector& stdDevs); - static Eigen::Matrix F(const Eigen::Matrix& x, - const Eigen::Matrix& u); - static Eigen::Matrix FillStateVector( - const Pose2d& pose, units::meter_t leftDistance, - units::meter_t rightDistance); + static Eigen::Vector F(const Eigen::Vector& x, + const Eigen::Vector& u); + static Eigen::Vector FillStateVector(const Pose2d& pose, + units::meter_t leftDistance, + units::meter_t rightDistance); }; } // namespace frc diff --git a/wpimath/src/main/native/include/frc/estimator/ExtendedKalmanFilter.h b/wpimath/src/main/native/include/frc/estimator/ExtendedKalmanFilter.h index 26a8fd4370..985f2c14d9 100644 --- a/wpimath/src/main/native/include/frc/estimator/ExtendedKalmanFilter.h +++ b/wpimath/src/main/native/include/frc/estimator/ExtendedKalmanFilter.h @@ -33,13 +33,13 @@ class ExtendedKalmanFilter { * @param measurementStdDevs Standard deviations of measurements. * @param dt Nominal discretization timestep. */ - ExtendedKalmanFilter(std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + ExtendedKalmanFilter(std::function( + const Eigen::Vector&, + const Eigen::Vector&)> f, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const wpi::array& stateStdDevs, const wpi::array& measurementStdDevs, @@ -47,10 +47,10 @@ class ExtendedKalmanFilter { : m_f(f), m_h(h) { m_contQ = MakeCovMatrix(stateStdDevs); m_contR = MakeCovMatrix(measurementStdDevs); - m_residualFuncY = [](auto a, auto b) -> Eigen::Matrix { + m_residualFuncY = [](auto a, auto b) -> Eigen::Vector { return a - b; }; - m_addFuncX = [](auto a, auto b) -> Eigen::Matrix { + m_addFuncX = [](auto a, auto b) -> Eigen::Vector { return a + b; }; m_dt = dt; @@ -59,10 +59,10 @@ class ExtendedKalmanFilter { Eigen::Matrix contA = NumericalJacobianX( - m_f, m_xHat, Eigen::Matrix::Zero()); + m_f, m_xHat, Eigen::Vector::Zero()); Eigen::Matrix C = NumericalJacobianX( - m_h, m_xHat, Eigen::Matrix::Zero()); + m_h, m_xHat, Eigen::Vector::Zero()); Eigen::Matrix discA; Eigen::Matrix discQ; @@ -97,23 +97,23 @@ class ExtendedKalmanFilter { * @param addFuncX A function that adds two state vectors. * @param dt Nominal discretization timestep. */ - ExtendedKalmanFilter(std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + ExtendedKalmanFilter(std::function( + const Eigen::Vector&, + const Eigen::Vector&)> f, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const wpi::array& stateStdDevs, const wpi::array& measurementStdDevs, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> residualFuncY, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> addFuncX, units::second_t dt) : m_f(f), m_h(h), m_residualFuncY(residualFuncY), m_addFuncX(addFuncX) { @@ -125,10 +125,10 @@ class ExtendedKalmanFilter { Eigen::Matrix contA = NumericalJacobianX( - m_f, m_xHat, Eigen::Matrix::Zero()); + m_f, m_xHat, Eigen::Vector::Zero()); Eigen::Matrix C = NumericalJacobianX( - m_h, m_xHat, Eigen::Matrix::Zero()); + m_h, m_xHat, Eigen::Vector::Zero()); Eigen::Matrix discA; Eigen::Matrix discQ; @@ -172,7 +172,7 @@ class ExtendedKalmanFilter { /** * Returns the state estimate x-hat. */ - const Eigen::Matrix& Xhat() const { return m_xHat; } + const Eigen::Vector& Xhat() const { return m_xHat; } /** * Returns an element of the state estimate x-hat. @@ -186,7 +186,7 @@ class ExtendedKalmanFilter { * * @param xHat The state estimate x-hat. */ - void SetXhat(const Eigen::Matrix& xHat) { m_xHat = xHat; } + void SetXhat(const Eigen::Vector& xHat) { m_xHat = xHat; } /** * Set an element of the initial state estimate x-hat. @@ -210,7 +210,7 @@ class ExtendedKalmanFilter { * @param u New control input from controller. * @param dt Timestep for prediction. */ - void Predict(const Eigen::Matrix& u, units::second_t dt) { + void Predict(const Eigen::Vector& u, units::second_t dt) { // Find continuous A Eigen::Matrix contA = NumericalJacobianX(m_f, m_xHat, u); @@ -234,23 +234,23 @@ class ExtendedKalmanFilter { * @param u Same control input used in the predict step. * @param y Measurement vector. */ - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y) { + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y) { Correct(u, y, m_h, m_contR, m_residualFuncY, m_addFuncX); } template - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y, + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const Eigen::Matrix& R) { - auto residualFuncY = [](auto a, auto b) -> Eigen::Matrix { + auto residualFuncY = [](auto a, auto b) -> Eigen::Vector { return a - b; }; - auto addFuncX = [](auto a, auto b) -> Eigen::Matrix { + auto addFuncX = [](auto a, auto b) -> Eigen::Vector { return a + b; }; Correct(u, y, h, R, residualFuncY, addFuncX); @@ -273,20 +273,20 @@ class ExtendedKalmanFilter { * @param addFuncX A function that adds two state vectors. */ template - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y, + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const Eigen::Matrix& R, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> residualFuncY, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix)> + std::function( + const Eigen::Vector&, + const Eigen::Vector)> addFuncX) { const Eigen::Matrix C = NumericalJacobianX(h, m_xHat, u); @@ -317,23 +317,23 @@ class ExtendedKalmanFilter { } private: - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> m_f; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> m_h; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix)> + std::function( + const Eigen::Vector&, + const Eigen::Vector)> m_residualFuncY; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix)> + std::function( + const Eigen::Vector&, + const Eigen::Vector)> m_addFuncX; - Eigen::Matrix m_xHat; + Eigen::Vector m_xHat; Eigen::Matrix m_P; Eigen::Matrix m_contQ; Eigen::Matrix m_contR; diff --git a/wpimath/src/main/native/include/frc/estimator/KalmanFilter.h b/wpimath/src/main/native/include/frc/estimator/KalmanFilter.h index 341e43d9bf..363753e5a3 100644 --- a/wpimath/src/main/native/include/frc/estimator/KalmanFilter.h +++ b/wpimath/src/main/native/include/frc/estimator/KalmanFilter.h @@ -118,7 +118,7 @@ class KalmanFilterImpl { /** * Returns the state estimate x-hat. */ - const Eigen::Matrix& Xhat() const { return m_xHat; } + const Eigen::Vector& Xhat() const { return m_xHat; } /** * Returns an element of the state estimate x-hat. @@ -132,7 +132,7 @@ class KalmanFilterImpl { * * @param xHat The state estimate x-hat. */ - void SetXhat(const Eigen::Matrix& xHat) { m_xHat = xHat; } + void SetXhat(const Eigen::Vector& xHat) { m_xHat = xHat; } /** * Set an element of the initial state estimate x-hat. @@ -153,7 +153,7 @@ class KalmanFilterImpl { * @param u New control input from controller. * @param dt Timestep for prediction. */ - void Predict(const Eigen::Matrix& u, units::second_t dt) { + void Predict(const Eigen::Vector& u, units::second_t dt) { m_xHat = m_plant->CalculateX(m_xHat, u, dt); } @@ -163,8 +163,8 @@ class KalmanFilterImpl { * @param u Same control input used in the last predict step. * @param y Measurement vector. */ - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y) { + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y) { // x̂ₖ₊₁⁺ = x̂ₖ₊₁⁻ + K(y − (Cx̂ₖ₊₁⁻ + Duₖ₊₁)) m_xHat += m_K * (y - (m_plant->C() * m_xHat + m_plant->D() * u)); } @@ -180,7 +180,7 @@ class KalmanFilterImpl { /** * The state estimate. */ - Eigen::Matrix m_xHat; + Eigen::Vector m_xHat; }; } // namespace detail diff --git a/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h b/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h index f7e5588c8b..aabb8ec800 100644 --- a/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h +++ b/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h @@ -20,14 +20,14 @@ template class KalmanFilterLatencyCompensator { public: struct ObserverSnapshot { - Eigen::Matrix xHat; + Eigen::Vector xHat; Eigen::Matrix errorCovariances; - Eigen::Matrix inputs; - Eigen::Matrix localMeasurements; + Eigen::Vector inputs; + Eigen::Vector localMeasurements; ObserverSnapshot(const KalmanFilterType& observer, - const Eigen::Matrix& u, - const Eigen::Matrix& localY) + const Eigen::Vector& u, + const Eigen::Vector& localY) : xHat(observer.Xhat()), errorCovariances(observer.P()), inputs(u), @@ -48,8 +48,8 @@ class KalmanFilterLatencyCompensator { * @param timestamp The timesnap of the state. */ void AddObserverState(const KalmanFilterType& observer, - Eigen::Matrix u, - Eigen::Matrix localY, + Eigen::Vector u, + Eigen::Vector localY, units::second_t timestamp) { // Add the new state into the vector. m_pastObserverSnapshots.emplace_back(timestamp, @@ -75,9 +75,9 @@ class KalmanFilterLatencyCompensator { template void ApplyPastGlobalMeasurement( KalmanFilterType* observer, units::second_t nominalDt, - Eigen::Matrix y, - std::function& u, - const Eigen::Matrix& y)> + Eigen::Vector y, + std::function& u, + const Eigen::Vector& y)> globalMeasurementCorrect, units::second_t timestamp) { if (m_pastObserverSnapshots.size() == 0) { diff --git a/wpimath/src/main/native/include/frc/estimator/MecanumDrivePoseEstimator.h b/wpimath/src/main/native/include/frc/estimator/MecanumDrivePoseEstimator.h index fc58a6acfb..40d7e28436 100644 --- a/wpimath/src/main/native/include/frc/estimator/MecanumDrivePoseEstimator.h +++ b/wpimath/src/main/native/include/frc/estimator/MecanumDrivePoseEstimator.h @@ -205,8 +205,8 @@ class WPILIB_DLLEXPORT MecanumDrivePoseEstimator { MecanumDriveKinematics m_kinematics; KalmanFilterLatencyCompensator<3, 3, 1, UnscentedKalmanFilter<3, 3, 1>> m_latencyCompensator; - std::function& u, - const Eigen::Matrix& y)> + std::function& u, + const Eigen::Vector& y)> m_visionCorrect; Eigen::Matrix3d m_visionContR; @@ -219,7 +219,7 @@ class WPILIB_DLLEXPORT MecanumDrivePoseEstimator { template static wpi::array StdDevMatrixToArray( - const Eigen::Matrix& vector) { + const Eigen::Vector& vector) { wpi::array array; for (size_t i = 0; i < Dim; ++i) { array[i] = vector(i); diff --git a/wpimath/src/main/native/include/frc/estimator/MerweScaledSigmaPoints.h b/wpimath/src/main/native/include/frc/estimator/MerweScaledSigmaPoints.h index 543f7a9af0..b521ed1f38 100644 --- a/wpimath/src/main/native/include/frc/estimator/MerweScaledSigmaPoints.h +++ b/wpimath/src/main/native/include/frc/estimator/MerweScaledSigmaPoints.h @@ -63,7 +63,7 @@ class MerweScaledSigmaPoints { * */ Eigen::Matrix SigmaPoints( - const Eigen::Matrix& x, + const Eigen::Vector& x, const Eigen::Matrix& P) { double lambda = std::pow(m_alpha, 2) * (States + m_kappa) - States; Eigen::Matrix U = @@ -84,7 +84,7 @@ class MerweScaledSigmaPoints { /** * Returns the weight for each sigma point for the mean. */ - const Eigen::Matrix& Wm() const { return m_Wm; } + const Eigen::Vector& Wm() const { return m_Wm; } /** * Returns an element of the weight for each sigma point for the mean. @@ -96,7 +96,7 @@ class MerweScaledSigmaPoints { /** * Returns the weight for each sigma point for the covariance. */ - const Eigen::Matrix& Wc() const { return m_Wc; } + const Eigen::Vector& Wc() const { return m_Wc; } /** * Returns an element of the weight for each sigma point for the covariance. @@ -106,8 +106,8 @@ class MerweScaledSigmaPoints { double Wc(int i) const { return m_Wc(i, 0); } private: - Eigen::Matrix m_Wm; - Eigen::Matrix m_Wc; + Eigen::Vector m_Wm; + Eigen::Vector m_Wc; double m_alpha; int m_kappa; @@ -120,8 +120,8 @@ class MerweScaledSigmaPoints { double lambda = std::pow(m_alpha, 2) * (States + m_kappa) - States; double c = 0.5 / (States + lambda); - m_Wm = Eigen::Matrix::Constant(c); - m_Wc = Eigen::Matrix::Constant(c); + m_Wm = Eigen::Vector::Constant(c); + m_Wc = Eigen::Vector::Constant(c); m_Wm(0) = lambda / (States + lambda); m_Wc(0) = lambda / (States + lambda) + (1 - std::pow(m_alpha, 2) + beta); diff --git a/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h b/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h index d4a1c3121f..67c955b3a4 100644 --- a/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h +++ b/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h @@ -80,10 +80,10 @@ class SwerveDrivePoseEstimator { const wpi::array& localMeasurementStdDevs, const wpi::array& visionMeasurementStdDevs, units::second_t nominalDt = 0.02_s) - : m_observer([](const Eigen::Matrix& x, - const Eigen::Matrix& u) { return u; }, - [](const Eigen::Matrix& x, - const Eigen::Matrix& u) { + : m_observer([](const Eigen::Vector& x, + const Eigen::Vector& u) { return u; }, + [](const Eigen::Vector& x, + const Eigen::Vector& u) { return x.block<1, 1>(2, 0); }, stateStdDevs, localMeasurementStdDevs, @@ -95,12 +95,12 @@ class SwerveDrivePoseEstimator { SetVisionMeasurementStdDevs(visionMeasurementStdDevs); // Create correction mechanism for vision measurements. - m_visionCorrect = [&](const Eigen::Matrix& u, - const Eigen::Matrix& y) { + m_visionCorrect = [&](const Eigen::Vector& u, + const Eigen::Vector& y) { m_observer.Correct<3>( u, y, - [](const Eigen::Matrix& x, - const Eigen::Matrix& u) { return x; }, + [](const Eigen::Vector& x, + const Eigen::Vector& u) { return x; }, m_visionContR, frc::AngleMean<3, 3>(2), frc::AngleResidual<3>(2), frc::AngleResidual<3>(2), frc::AngleAdd<3>(2)); }; @@ -269,12 +269,11 @@ class SwerveDrivePoseEstimator { Translation2d(chassisSpeeds.vx * 1_s, chassisSpeeds.vy * 1_s) .RotateBy(angle); - auto u = - frc::MakeMatrix<3, 1>(fieldRelativeSpeeds.X().template to(), - fieldRelativeSpeeds.Y().template to(), - omega.template to()); + Eigen::Vector u{fieldRelativeSpeeds.X().template to(), + fieldRelativeSpeeds.Y().template to(), + omega.template to()}; - auto localY = frc::MakeMatrix<1, 1>(angle.Radians().template to()); + Eigen::Vector localY{angle.Radians().template to()}; m_previousAngle = angle; m_latencyCompensator.AddObserverState(m_observer, u, localY, currentTime); @@ -290,8 +289,8 @@ class SwerveDrivePoseEstimator { SwerveDriveKinematics& m_kinematics; KalmanFilterLatencyCompensator<3, 3, 1, UnscentedKalmanFilter<3, 3, 1>> m_latencyCompensator; - std::function& u, - const Eigen::Matrix& y)> + std::function& u, + const Eigen::Vector& y)> m_visionCorrect; Eigen::Matrix3d m_visionContR; @@ -304,7 +303,7 @@ class SwerveDrivePoseEstimator { template static wpi::array StdDevMatrixToArray( - const Eigen::Matrix& vector) { + const Eigen::Vector& vector) { wpi::array array; for (size_t i = 0; i < Dim; ++i) { array[i] = vector(i); diff --git a/wpimath/src/main/native/include/frc/estimator/UnscentedKalmanFilter.h b/wpimath/src/main/native/include/frc/estimator/UnscentedKalmanFilter.h index 75a11a60dd..53972a8193 100644 --- a/wpimath/src/main/native/include/frc/estimator/UnscentedKalmanFilter.h +++ b/wpimath/src/main/native/include/frc/estimator/UnscentedKalmanFilter.h @@ -34,13 +34,13 @@ class UnscentedKalmanFilter { * @param measurementStdDevs Standard deviations of measurements. * @param dt Nominal discretization timestep. */ - UnscentedKalmanFilter(std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + UnscentedKalmanFilter(std::function( + const Eigen::Vector&, + const Eigen::Vector&)> f, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const wpi::array& stateStdDevs, const wpi::array& measurementStdDevs, @@ -48,20 +48,19 @@ class UnscentedKalmanFilter { : m_f(f), m_h(h) { m_contQ = MakeCovMatrix(stateStdDevs); m_contR = MakeCovMatrix(measurementStdDevs); - m_meanFuncX = [](auto sigmas, auto Wm) -> Eigen::Matrix { + m_meanFuncX = [](auto sigmas, auto Wm) -> Eigen::Vector { return sigmas * Wm; }; - m_meanFuncY = [](auto sigmas, - auto Wc) -> Eigen::Matrix { + m_meanFuncY = [](auto sigmas, auto Wc) -> Eigen::Vector { return sigmas * Wc; }; - m_residualFuncX = [](auto a, auto b) -> Eigen::Matrix { + m_residualFuncX = [](auto a, auto b) -> Eigen::Vector { return a - b; }; - m_residualFuncY = [](auto a, auto b) -> Eigen::Matrix { + m_residualFuncY = [](auto a, auto b) -> Eigen::Vector { return a - b; }; - m_addFuncX = [](auto a, auto b) -> Eigen::Matrix { + m_addFuncX = [](auto a, auto b) -> Eigen::Vector { return a + b; }; m_dt = dt; @@ -94,35 +93,35 @@ class UnscentedKalmanFilter { * @param dt Nominal discretization timestep. */ UnscentedKalmanFilter( - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&, + const Eigen::Vector&)> f, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&, + const Eigen::Vector&)> h, const wpi::array& stateStdDevs, const wpi::array& measurementStdDevs, - std::function( + std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> meanFuncX, - std::function( + std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> meanFuncY, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&, + const Eigen::Vector&)> residualFuncX, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&, + const Eigen::Vector&)> residualFuncY, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&, + const Eigen::Vector&)> addFuncX, units::second_t dt) : m_f(f), @@ -162,7 +161,7 @@ class UnscentedKalmanFilter { /** * Returns the state estimate x-hat. */ - const Eigen::Matrix& Xhat() const { return m_xHat; } + const Eigen::Vector& Xhat() const { return m_xHat; } /** * Returns an element of the state estimate x-hat. @@ -176,7 +175,7 @@ class UnscentedKalmanFilter { * * @param xHat The state estimate x-hat. */ - void SetXhat(const Eigen::Matrix& xHat) { m_xHat = xHat; } + void SetXhat(const Eigen::Vector& xHat) { m_xHat = xHat; } /** * Set an element of the initial state estimate x-hat. @@ -201,7 +200,7 @@ class UnscentedKalmanFilter { * @param u New control input from controller. * @param dt Timestep for prediction. */ - void Predict(const Eigen::Matrix& u, units::second_t dt) { + void Predict(const Eigen::Vector& u, units::second_t dt) { m_dt = dt; // Discretize Q before projecting mean and covariance forward @@ -215,8 +214,7 @@ class UnscentedKalmanFilter { m_pts.SigmaPoints(m_xHat, m_P); for (int i = 0; i < m_pts.NumSigmas(); ++i) { - Eigen::Matrix x = - sigmas.template block(0, i); + Eigen::Vector x = sigmas.template block(0, i); m_sigmasF.template block(0, i) = RK4(m_f, x, u, dt); } @@ -234,8 +232,8 @@ class UnscentedKalmanFilter { * @param u Same control input used in the predict step. * @param y Measurement vector. */ - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y) { + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y) { Correct(u, y, m_h, m_contR, m_meanFuncY, m_residualFuncY, m_residualFuncX, m_addFuncX); } @@ -254,25 +252,23 @@ class UnscentedKalmanFilter { * @param R Measurement noise covariance matrix (continuous-time). */ template - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y, + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const Eigen::Matrix& R) { - auto meanFuncY = [](auto sigmas, - auto Wc) -> Eigen::Matrix { + auto meanFuncY = [](auto sigmas, auto Wc) -> Eigen::Vector { return sigmas * Wc; }; - auto residualFuncX = [](auto a, - auto b) -> Eigen::Matrix { + auto residualFuncX = [](auto a, auto b) -> Eigen::Vector { return a - b; }; - auto residualFuncY = [](auto a, auto b) -> Eigen::Matrix { + auto residualFuncY = [](auto a, auto b) -> Eigen::Vector { return a - b; }; - auto addFuncX = [](auto a, auto b) -> Eigen::Matrix { + auto addFuncX = [](auto a, auto b) -> Eigen::Vector { return a + b; }; Correct(u, y, h, R, meanFuncY, residualFuncY, residualFuncX, @@ -300,28 +296,28 @@ class UnscentedKalmanFilter { * @param addFuncX A function that adds two state vectors. */ template - void Correct(const Eigen::Matrix& u, - const Eigen::Matrix& y, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + void Correct(const Eigen::Vector& u, + const Eigen::Vector& y, + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> h, const Eigen::Matrix& R, - std::function( + std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> meanFuncY, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> residualFuncY, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> residualFuncX, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix)> + std::function( + const Eigen::Vector&, + const Eigen::Vector)> addFuncX) { const Eigen::Matrix discR = DiscretizeR(R, m_dt); @@ -367,35 +363,35 @@ class UnscentedKalmanFilter { } private: - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> m_f; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> m_h; - std::function( + std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> m_meanFuncX; - std::function( + std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> m_meanFuncY; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> m_residualFuncX; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix)> + std::function( + const Eigen::Vector&, + const Eigen::Vector)> m_residualFuncY; - std::function( - const Eigen::Matrix&, - const Eigen::Matrix)> + std::function( + const Eigen::Vector&, + const Eigen::Vector)> m_addFuncX; - Eigen::Matrix m_xHat; + Eigen::Vector m_xHat; Eigen::Matrix m_P; Eigen::Matrix m_contQ; Eigen::Matrix m_contR; diff --git a/wpimath/src/main/native/include/frc/estimator/UnscentedTransform.h b/wpimath/src/main/native/include/frc/estimator/UnscentedTransform.h index 3e4592d2a8..b0b86f3d21 100644 --- a/wpimath/src/main/native/include/frc/estimator/UnscentedTransform.h +++ b/wpimath/src/main/native/include/frc/estimator/UnscentedTransform.h @@ -27,24 +27,23 @@ namespace frc { * passing through the transform. */ template -std::tuple, - Eigen::Matrix> +std::tuple, Eigen::Matrix> UnscentedTransform(const Eigen::Matrix& sigmas, - const Eigen::Matrix& Wm, - const Eigen::Matrix& Wc, - std::function( + const Eigen::Vector& Wm, + const Eigen::Vector& Wc, + std::function( const Eigen::Matrix&, - const Eigen::Matrix&)> + const Eigen::Vector&)> meanFunc, - std::function( - const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&, + const Eigen::Vector&)> residualFunc) { // New mean is usually just the sum of the sigmas * weight: // n // dot = Σ W[k] Xᵢ[k] // k=1 - Eigen::Matrix x = meanFunc(sigmas, Wm); + Eigen::Vector x = meanFunc(sigmas, Wm); // New covariance is the sum of the outer product of the residuals times the // weights diff --git a/wpimath/src/main/native/include/frc/filter/LinearFilter.h b/wpimath/src/main/native/include/frc/filter/LinearFilter.h index e5b6f1db3e..b6ea33a817 100644 --- a/wpimath/src/main/native/include/frc/filter/LinearFilter.h +++ b/wpimath/src/main/native/include/frc/filter/LinearFilter.h @@ -219,12 +219,12 @@ class LinearFilter { } // Fill in Kronecker deltas: https://en.wikipedia.org/wiki/Kronecker_delta - Eigen::Matrix d; + Eigen::Vector d; for (int i = 0; i < Samples; ++i) { d(i) = (i == Derivative) ? Factorial(Derivative) : 0.0; } - Eigen::Matrix a = + Eigen::Vector a = S.householderQr().solve(d) / std::pow(period.to(), Derivative); // Reverse gains list diff --git a/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc b/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc index 374db562d7..8601adf097 100644 --- a/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc +++ b/wpimath/src/main/native/include/frc/kinematics/SwerveDriveKinematics.inc @@ -24,27 +24,26 @@ SwerveDriveKinematics::ToSwerveModuleStates( if (centerOfRotation != m_previousCoR) { for (size_t i = 0; i < NumModules; i++) { // clang-format off - m_inverseKinematics.template block<2, 3>(i * 2, 0) << - 1, 0, (-m_modules[i].Y() + centerOfRotation.Y()).template to(), - 0, 1, (+m_modules[i].X() - centerOfRotation.X()).template to(); + m_inverseKinematics.template block<2, 3>(i * 2, 0) = + Eigen::Matrix{ + {1, 0, (-m_modules[i].Y() + centerOfRotation.Y()).template to()}, + {0, 1, (+m_modules[i].X() - centerOfRotation.X()).template to()}}; // clang-format on } m_previousCoR = centerOfRotation; } - Eigen::Vector3d chassisSpeedsVector; - chassisSpeedsVector << chassisSpeeds.vx.to(), - chassisSpeeds.vy.to(), chassisSpeeds.omega.to(); + Eigen::Vector3d chassisSpeedsVector{chassisSpeeds.vx.to(), + chassisSpeeds.vy.to(), + chassisSpeeds.omega.to()}; Eigen::Matrix moduleStatesMatrix = m_inverseKinematics * chassisSpeedsVector; wpi::array moduleStates{wpi::empty_array}; for (size_t i = 0; i < NumModules; i++) { - units::meters_per_second_t x = - units::meters_per_second_t{moduleStatesMatrix(i * 2, 0)}; - units::meters_per_second_t y = - units::meters_per_second_t{moduleStatesMatrix(i * 2 + 1, 0)}; + units::meters_per_second_t x{moduleStatesMatrix(i * 2, 0)}; + units::meters_per_second_t y{moduleStatesMatrix(i * 2 + 1, 0)}; auto speed = units::math::hypot(x, y); Rotation2d rotation{x.to(), y.to()}; @@ -73,12 +72,12 @@ ChassisSpeeds SwerveDriveKinematics::ToChassisSpeeds( wpi::array moduleStates) const { Eigen::Matrix moduleStatesMatrix; - for (size_t i = 0; i < NumModules; i++) { + for (size_t i = 0; i < NumModules; ++i) { SwerveModuleState module = moduleStates[i]; - moduleStatesMatrix.row(i * 2) - << module.speed.to() * module.angle.Cos(); - moduleStatesMatrix.row(i * 2 + 1) - << module.speed.to() * module.angle.Sin(); + moduleStatesMatrix(i * 2, 0) = + module.speed.to() * module.angle.Cos(); + moduleStatesMatrix(i * 2 + 1, 0) = + module.speed.to() * module.angle.Sin(); } Eigen::Vector3d chassisSpeedsVector = diff --git a/wpimath/src/main/native/include/frc/spline/CubicHermiteSpline.h b/wpimath/src/main/native/include/frc/spline/CubicHermiteSpline.h index cfad20c3d5..8126349d8a 100644 --- a/wpimath/src/main/native/include/frc/spline/CubicHermiteSpline.h +++ b/wpimath/src/main/native/include/frc/spline/CubicHermiteSpline.h @@ -74,13 +74,10 @@ class WPILIB_DLLEXPORT CubicHermiteSpline : public Spline<3> { // [ a1 ] = [ 0 1 0 0 ][ P(i+1) ] // [ a0 ] = [ 1 0 0 0 ][ P'(i+1) ] - // clang-format off - static auto basis = (Eigen::Matrix() << - +2.0, +1.0, -2.0, +1.0, - -3.0, -2.0, +3.0, -1.0, - +0.0, +1.0, +0.0, +0.0, - +1.0, +0.0, +0.0, +0.0).finished(); - // clang-format on + static const Eigen::Matrix basis{{+2.0, +1.0, -2.0, +1.0}, + {-3.0, -2.0, +3.0, -1.0}, + {+0.0, +1.0, +0.0, +0.0}, + {+1.0, +0.0, +0.0, +0.0}}; return basis; } @@ -95,9 +92,8 @@ class WPILIB_DLLEXPORT CubicHermiteSpline : public Spline<3> { */ static Eigen::Vector4d ControlVectorFromArrays( wpi::array initialVector, wpi::array finalVector) { - return (Eigen::Vector4d() << initialVector[0], initialVector[1], - finalVector[0], finalVector[1]) - .finished(); + return Eigen::Vector4d{initialVector[0], initialVector[1], finalVector[0], + finalVector[1]}; } }; } // namespace frc diff --git a/wpimath/src/main/native/include/frc/spline/QuinticHermiteSpline.h b/wpimath/src/main/native/include/frc/spline/QuinticHermiteSpline.h index 04efecde3a..5ba3e2a18f 100644 --- a/wpimath/src/main/native/include/frc/spline/QuinticHermiteSpline.h +++ b/wpimath/src/main/native/include/frc/spline/QuinticHermiteSpline.h @@ -81,15 +81,13 @@ class WPILIB_DLLEXPORT QuinticHermiteSpline : public Spline<5> { // [ a1 ] = [ 0.0 1.0 0.0 0.0 0.0 0.0 ][ P'(i+1) ] // [ a0 ] = [ 1.0 0.0 0.0 0.0 0.0 0.0 ][ P''(i+1) ] - // clang-format off - static const auto basis = (Eigen::Matrix() << - -06.0, -03.0, -00.5, +06.0, -03.0, +00.5, - +15.0, +08.0, +01.5, -15.0, +07.0, -01.0, - -10.0, -06.0, -01.5, +10.0, -04.0, +00.5, - +00.0, +00.0, +00.5, +00.0, +00.0, +00.0, - +00.0, +01.0, +00.0, +00.0, +00.0, +00.0, - +01.0, +00.0, +00.0, +00.0, +00.0, +00.0).finished(); - // clang-format on + static const Eigen::Matrix basis{ + {-06.0, -03.0, -00.5, +06.0, -03.0, +00.5}, + {+15.0, +08.0, +01.5, -15.0, +07.0, -01.0}, + {-10.0, -06.0, -01.5, +10.0, -04.0, +00.5}, + {+00.0, +00.0, +00.5, +00.0, +00.0, +00.0}, + {+00.0, +01.0, +00.0, +00.0, +00.0, +00.0}, + {+01.0, +00.0, +00.0, +00.0, +00.0, +00.0}}; return basis; } @@ -102,11 +100,11 @@ class WPILIB_DLLEXPORT QuinticHermiteSpline : public Spline<5> { * * @return The control vector matrix for a dimension. */ - static Eigen::Matrix ControlVectorFromArrays( + static Eigen::Vector ControlVectorFromArrays( wpi::array initialVector, wpi::array finalVector) { - return (Eigen::Matrix() << initialVector[0], initialVector[1], - initialVector[2], finalVector[0], finalVector[1], finalVector[2]) - .finished(); + return Eigen::Vector{initialVector[0], initialVector[1], + initialVector[2], finalVector[0], + finalVector[1], finalVector[2]}; } }; } // namespace frc diff --git a/wpimath/src/main/native/include/frc/spline/Spline.h b/wpimath/src/main/native/include/frc/spline/Spline.h index a04564ac4d..615dffd939 100644 --- a/wpimath/src/main/native/include/frc/spline/Spline.h +++ b/wpimath/src/main/native/include/frc/spline/Spline.h @@ -55,7 +55,7 @@ class Spline { * @return The pose and curvature at that point. */ PoseWithCurvature GetPoint(double t) const { - Eigen::Matrix polynomialBases; + Eigen::Vector polynomialBases; // Populate the polynomial bases for (int i = 0; i <= Degree; i++) { @@ -64,7 +64,7 @@ class Spline { // This simply multiplies by the coefficients. We need to divide out t some // n number of times where n is the derivative we want to take. - Eigen::Matrix combined = Coefficients() * polynomialBases; + Eigen::Vector combined = Coefficients() * polynomialBases; double dx, dy, ddx, ddy; @@ -109,9 +109,8 @@ class Spline { * @return The vector. */ static Eigen::Vector2d ToVector(const Translation2d& translation) { - return (Eigen::Vector2d() << translation.X().to(), - translation.Y().to()) - .finished(); + return Eigen::Vector2d{translation.X().to(), + translation.Y().to()}; } /** diff --git a/wpimath/src/main/native/include/frc/system/LinearSystem.h b/wpimath/src/main/native/include/frc/system/LinearSystem.h index 23ef462bd9..8b160a2997 100644 --- a/wpimath/src/main/native/include/frc/system/LinearSystem.h +++ b/wpimath/src/main/native/include/frc/system/LinearSystem.h @@ -110,10 +110,9 @@ class LinearSystem { * @param u The control input. * @param dt Timestep for model update. */ - Eigen::Matrix CalculateX( - const Eigen::Matrix& x, - const Eigen::Matrix& clampedU, - units::second_t dt) const { + Eigen::Vector CalculateX( + const Eigen::Vector& x, + const Eigen::Vector& clampedU, units::second_t dt) const { Eigen::Matrix discA; Eigen::Matrix discB; DiscretizeAB(m_A, m_B, dt, &discA, &discB); @@ -130,9 +129,9 @@ class LinearSystem { * @param x The current state. * @param clampedU The control input. */ - Eigen::Matrix CalculateY( - const Eigen::Matrix& x, - const Eigen::Matrix& clampedU) const { + Eigen::Vector CalculateY( + const Eigen::Vector& x, + const Eigen::Vector& clampedU) const { return m_C * x + m_D * clampedU; } diff --git a/wpimath/src/main/native/include/frc/system/LinearSystemLoop.h b/wpimath/src/main/native/include/frc/system/LinearSystemLoop.h index a6ec2a7e39..9c5a01be18 100644 --- a/wpimath/src/main/native/include/frc/system/LinearSystemLoop.h +++ b/wpimath/src/main/native/include/frc/system/LinearSystemLoop.h @@ -48,7 +48,7 @@ class LinearSystemLoop { units::volt_t maxVoltage, units::second_t dt) : LinearSystemLoop( plant, controller, observer, - [=](Eigen::Matrix u) { + [=](const Eigen::Vector& u) { return frc::NormalizeInputVector( u, maxVoltage.template to()); }, @@ -69,8 +69,8 @@ class LinearSystemLoop { LinearSystemLoop(LinearSystem& plant, LinearQuadraticRegulator& controller, KalmanFilter& observer, - std::function( - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&)> clampFunction, units::second_t dt) : LinearSystemLoop( @@ -94,7 +94,7 @@ class LinearSystemLoop { const LinearPlantInversionFeedforward& feedforward, KalmanFilter& observer, units::volt_t maxVoltage) : LinearSystemLoop(controller, feedforward, observer, - [=](Eigen::Matrix u) { + [=](const Eigen::Vector& u) { return frc::NormalizeInputVector( u, maxVoltage.template to()); }) {} @@ -113,8 +113,8 @@ class LinearSystemLoop { LinearQuadraticRegulator& controller, const LinearPlantInversionFeedforward& feedforward, KalmanFilter& observer, - std::function( - const Eigen::Matrix&)> + std::function< + Eigen::Vector(const Eigen::Vector&)> clampFunction) : m_controller(&controller), m_feedforward(feedforward), @@ -130,7 +130,7 @@ class LinearSystemLoop { /** * Returns the observer's state estimate x-hat. */ - const Eigen::Matrix& Xhat() const { + const Eigen::Vector& Xhat() const { return m_observer->Xhat(); } @@ -144,7 +144,7 @@ class LinearSystemLoop { /** * Returns the controller's next reference r. */ - const Eigen::Matrix& NextR() const { return m_nextR; } + const Eigen::Vector& NextR() const { return m_nextR; } /** * Returns an element of the controller's next reference r. @@ -156,7 +156,7 @@ class LinearSystemLoop { /** * Returns the controller's calculated control input u. */ - Eigen::Matrix U() const { + Eigen::Vector U() const { return ClampInput(m_controller->U() + m_feedforward.Uff()); } @@ -172,7 +172,7 @@ class LinearSystemLoop { * * @param xHat The initial state estimate x-hat. */ - void SetXhat(const Eigen::Matrix& xHat) { + void SetXhat(const Eigen::Vector& xHat) { m_observer->SetXhat(xHat); } @@ -189,9 +189,7 @@ class LinearSystemLoop { * * @param nextR Next reference. */ - void SetNextR(const Eigen::Matrix& nextR) { - m_nextR = nextR; - } + void SetNextR(const Eigen::Vector& nextR) { m_nextR = nextR; } /** * Return the controller used internally. @@ -223,7 +221,7 @@ class LinearSystemLoop { * * @param initialState The initial state. */ - void Reset(Eigen::Matrix initialState) { + void Reset(const Eigen::Vector& initialState) { m_nextR.setZero(); m_controller->Reset(); m_feedforward.Reset(initialState); @@ -233,7 +231,7 @@ class LinearSystemLoop { /** * Returns difference between reference r and current state x-hat. */ - const Eigen::Matrix Error() const { + Eigen::Vector Error() const { return m_controller->R() - m_observer->Xhat(); } @@ -242,7 +240,7 @@ class LinearSystemLoop { * * @param y Measurement vector. */ - void Correct(const Eigen::Matrix& y) { + void Correct(const Eigen::Vector& y) { m_observer->Correct(U(), y); } @@ -256,7 +254,7 @@ class LinearSystemLoop { * @param dt Timestep for model update. */ void Predict(units::second_t dt) { - Eigen::Matrix u = + Eigen::Vector u = ClampInput(m_controller->Calculate(m_observer->Xhat(), m_nextR) + m_feedforward.Calculate(m_nextR)); m_observer->Predict(u, dt); @@ -268,8 +266,8 @@ class LinearSystemLoop { * @param u Input vector to clamp. * @return Clamped input vector. */ - Eigen::Matrix ClampInput( - const Eigen::Matrix& u) const { + Eigen::Vector ClampInput( + const Eigen::Vector& u) const { return m_clampFunc(u); } @@ -281,12 +279,12 @@ class LinearSystemLoop { /** * Clamping function. */ - std::function( - const Eigen::Matrix&)> + std::function( + const Eigen::Vector&)> m_clampFunc; // Reference to go to in the next cycle (used by feedforward controller). - Eigen::Matrix m_nextR; + Eigen::Vector m_nextR; // These are accessible from non-templated subclasses. static constexpr int kStates = States; diff --git a/wpimath/src/main/native/include/frc/system/NumericalJacobian.h b/wpimath/src/main/native/include/frc/system/NumericalJacobian.h index 560e708391..702a3b815f 100644 --- a/wpimath/src/main/native/include/frc/system/NumericalJacobian.h +++ b/wpimath/src/main/native/include/frc/system/NumericalJacobian.h @@ -17,16 +17,16 @@ namespace frc { * @param x Vector argument. */ template -auto NumericalJacobian(F&& f, const Eigen::Matrix& x) { +auto NumericalJacobian(F&& f, const Eigen::Vector& x) { constexpr double kEpsilon = 1e-5; Eigen::Matrix result; result.setZero(); // It's more expensive, but +- epsilon will be more accurate for (int i = 0; i < Cols; ++i) { - Eigen::Matrix dX_plus = x; + Eigen::Vector dX_plus = x; dX_plus(i) += kEpsilon; - Eigen::Matrix dX_minus = x; + Eigen::Vector dX_minus = x; dX_minus(i) -= kEpsilon; result.col(i) = (f(dX_plus) - f(dX_minus)) / (kEpsilon * 2.0); } @@ -47,11 +47,12 @@ auto NumericalJacobian(F&& f, const Eigen::Matrix& x) { * @param u Input vector. */ template -auto NumericalJacobianX(F&& f, const Eigen::Matrix& x, - const Eigen::Matrix& u, +auto NumericalJacobianX(F&& f, const Eigen::Vector& x, + const Eigen::Vector& u, Args&&... args) { return NumericalJacobian( - [&](Eigen::Matrix x) { return f(x, u, args...); }, x); + [&](const Eigen::Vector& x) { return f(x, u, args...); }, + x); } /** @@ -67,11 +68,12 @@ auto NumericalJacobianX(F&& f, const Eigen::Matrix& x, * @param u Input vector. */ template -auto NumericalJacobianU(F&& f, const Eigen::Matrix& x, - const Eigen::Matrix& u, +auto NumericalJacobianU(F&& f, const Eigen::Vector& x, + const Eigen::Vector& u, Args&&... args) { return NumericalJacobian( - [&](Eigen::Matrix u) { return f(x, u, args...); }, u); + [&](const Eigen::Vector& u) { return f(x, u, args...); }, + u); } } // namespace frc diff --git a/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h b/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h index 3f8c1973e7..714857f6b0 100644 --- a/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h +++ b/wpimath/src/main/native/include/frc/system/plant/LinearSystemId.h @@ -43,15 +43,15 @@ class WPILIB_DLLEXPORT LinearSystemId { static LinearSystem<2, 1, 1> ElevatorSystem(DCMotor motor, units::kilogram_t m, units::meter_t r, double G) { - Eigen::Matrix A = frc::MakeMatrix<2, 2>( - 0.0, 1.0, 0.0, - (-std::pow(G, 2) * motor.Kt / - (motor.R * units::math::pow<2>(r) * m * motor.Kv)) - .to()); - Eigen::Matrix B = frc::MakeMatrix<2, 1>( - 0.0, (G * motor.Kt / (motor.R * r * m)).to()); - Eigen::Matrix C = frc::MakeMatrix<1, 2>(1.0, 0.0); - Eigen::Matrix D = frc::MakeMatrix<1, 1>(0.0); + Eigen::Matrix A{ + {0.0, 1.0}, + {0.0, (-std::pow(G, 2) * motor.Kt / + (motor.R * units::math::pow<2>(r) * m * motor.Kv)) + .to()}}; + Eigen::Matrix B{ + 0.0, (G * motor.Kt / (motor.R * r * m)).to()}; + Eigen::Matrix C{1.0, 0.0}; + Eigen::Matrix D{0.0}; return LinearSystem<2, 1, 1>(A, B, C, D); } @@ -69,13 +69,14 @@ class WPILIB_DLLEXPORT LinearSystemId { */ static LinearSystem<2, 1, 1> SingleJointedArmSystem( DCMotor motor, units::kilogram_square_meter_t J, double G) { - Eigen::Matrix A = frc::MakeMatrix<2, 2>( - 0.0, 1.0, 0.0, - (-std::pow(G, 2) * motor.Kt / (motor.Kv * motor.R * J)).to()); - Eigen::Matrix B = - frc::MakeMatrix<2, 1>(0.0, (G * motor.Kt / (motor.R * J)).to()); - Eigen::Matrix C = frc::MakeMatrix<1, 2>(1.0, 0.0); - Eigen::Matrix D = frc::MakeMatrix<1, 1>(0.0); + Eigen::Matrix A{ + {0.0, 1.0}, + {0.0, + (-std::pow(G, 2) * motor.Kt / (motor.Kv * motor.R * J)).to()}}; + Eigen::Matrix B{0.0, + (G * motor.Kt / (motor.R * J)).to()}; + Eigen::Matrix C{1.0, 0.0}; + Eigen::Matrix D{0.0}; return LinearSystem<2, 1, 1>(A, B, C, D); } @@ -106,12 +107,11 @@ class WPILIB_DLLEXPORT LinearSystemId { static LinearSystem<1, 1, 1> IdentifyVelocitySystem( decltype(1_V / Velocity_t(1)) kV, decltype(1_V / Acceleration_t(1)) kA) { - Eigen::Matrix A = frc::MakeMatrix<1, 1>( - -kV.template to() / kA.template to()); - Eigen::Matrix B = - frc::MakeMatrix<1, 1>(1.0 / kA.template to()); - Eigen::Matrix C = frc::MakeMatrix<1, 1>(1.0); - Eigen::Matrix D = frc::MakeMatrix<1, 1>(0.0); + Eigen::Matrix A{-kV.template to() / + kA.template to()}; + Eigen::Matrix B{1.0 / kA.template to()}; + Eigen::Matrix C{1.0}; + Eigen::Matrix D{0.0}; return LinearSystem<1, 1, 1>(A, B, C, D); } @@ -142,12 +142,12 @@ class WPILIB_DLLEXPORT LinearSystemId { static LinearSystem<2, 1, 1> IdentifyPositionSystem( decltype(1_V / Velocity_t(1)) kV, decltype(1_V / Acceleration_t(1)) kA) { - Eigen::Matrix A = frc::MakeMatrix<2, 2>( - 0.0, 1.0, 0.0, -kV.template to() / kA.template to()); - Eigen::Matrix B = - frc::MakeMatrix<2, 1>(0.0, 1.0 / kA.template to()); - Eigen::Matrix C = frc::MakeMatrix<1, 2>(1.0, 0.0); - Eigen::Matrix D = frc::MakeMatrix<1, 1>(0.0); + Eigen::Matrix A{ + {0.0, 1.0}, + {0.0, -kV.template to() / kA.template to()}}; + Eigen::Matrix B{0.0, 1.0 / kA.template to()}; + Eigen::Matrix C{1.0, 0.0}; + Eigen::Matrix D{0.0}; return LinearSystem<2, 1, 1>(A, B, C, D); } @@ -177,10 +177,12 @@ class WPILIB_DLLEXPORT LinearSystemId { double B1 = 1.0 / kAlinear.to() + 1.0 / kAangular.to(); double B2 = 1.0 / kAlinear.to() - 1.0 / kAangular.to(); - Eigen::Matrix A = 0.5 * frc::MakeMatrix<2, 2>(A1, A2, A2, A1); - Eigen::Matrix B = 0.5 * frc::MakeMatrix<2, 2>(B1, B2, B2, B1); - Eigen::Matrix C = frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 1.0); - Eigen::Matrix D = frc::MakeMatrix<2, 2>(0.0, 0.0, 0.0, 0.0); + Eigen::Matrix A = + 0.5 * Eigen::Matrix{{A1, A2}, {A2, A1}}; + Eigen::Matrix B = + 0.5 * Eigen::Matrix{{B1, B2}, {B2, B1}}; + Eigen::Matrix C{{1.0, 0.0}, {0.0, 1.0}}; + Eigen::Matrix D{{0.0, 0.0}, {0.0, 0.0}}; return LinearSystem<2, 2, 2>(A, B, C, D); } @@ -236,12 +238,11 @@ class WPILIB_DLLEXPORT LinearSystemId { static LinearSystem<1, 1, 1> FlywheelSystem(DCMotor motor, units::kilogram_square_meter_t J, double G) { - auto A = frc::MakeMatrix<1, 1>( - (-std::pow(G, 2) * motor.Kt / (motor.Kv * motor.R * J)).to()); - Eigen::Matrix B = - frc::MakeMatrix<1, 1>((G * motor.Kt / (motor.R * J)).to()); - Eigen::Matrix C = frc::MakeMatrix<1, 1>(1.0); - Eigen::Matrix D = frc::MakeMatrix<1, 1>(0.0); + Eigen::Matrix A{ + (-std::pow(G, 2) * motor.Kt / (motor.Kv * motor.R * J)).to()}; + Eigen::Matrix B{(G * motor.Kt / (motor.R * J)).to()}; + Eigen::Matrix C{1.0}; + Eigen::Matrix D{0.0}; return LinearSystem<1, 1, 1>(A, B, C, D); } @@ -267,18 +268,18 @@ class WPILIB_DLLEXPORT LinearSystemId { (motor.Kv * motor.R * units::math::pow<2>(r)); auto C2 = G * motor.Kt / (motor.R * r); - Eigen::Matrix A = frc::MakeMatrix<2, 2>( - ((1 / m + units::math::pow<2>(rb) / J) * C1).to(), - ((1 / m - units::math::pow<2>(rb) / J) * C1).to(), - ((1 / m - units::math::pow<2>(rb) / J) * C1).to(), - ((1 / m + units::math::pow<2>(rb) / J) * C1).to()); - Eigen::Matrix B = frc::MakeMatrix<2, 2>( - ((1 / m + units::math::pow<2>(rb) / J) * C2).to(), - ((1 / m - units::math::pow<2>(rb) / J) * C2).to(), - ((1 / m - units::math::pow<2>(rb) / J) * C2).to(), - ((1 / m + units::math::pow<2>(rb) / J) * C2).to()); - Eigen::Matrix C = frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 1.0); - Eigen::Matrix D = frc::MakeMatrix<2, 2>(0.0, 0.0, 0.0, 0.0); + Eigen::Matrix A{ + {((1 / m + units::math::pow<2>(rb) / J) * C1).to(), + ((1 / m - units::math::pow<2>(rb) / J) * C1).to()}, + {((1 / m - units::math::pow<2>(rb) / J) * C1).to(), + ((1 / m + units::math::pow<2>(rb) / J) * C1).to()}}; + Eigen::Matrix B{ + {((1 / m + units::math::pow<2>(rb) / J) * C2).to(), + ((1 / m - units::math::pow<2>(rb) / J) * C2).to()}, + {((1 / m - units::math::pow<2>(rb) / J) * C2).to(), + ((1 / m + units::math::pow<2>(rb) / J) * C2).to()}}; + Eigen::Matrix C{{1.0, 0.0}, {0.0, 1.0}}; + Eigen::Matrix D{{0.0, 0.0}, {0.0, 0.0}}; return LinearSystem<2, 2, 2>(A, B, C, D); } diff --git a/wpimath/src/test/native/cpp/EigenTest.cpp b/wpimath/src/test/native/cpp/EigenTest.cpp index 1ae700532a..7b433552b7 100644 --- a/wpimath/src/test/native/cpp/EigenTest.cpp +++ b/wpimath/src/test/native/cpp/EigenTest.cpp @@ -7,48 +7,40 @@ #include "gtest/gtest.h" TEST(EigenTest, MultiplicationTest) { - Eigen::Matrix m1; - m1 << 2, 1, 0, 1; - - Eigen::Matrix m2; - m2 << 3, 0, 0, 2.5; + Eigen::Matrix m1{{2, 1}, {0, 1}}; + Eigen::Matrix m2{{3, 0}, {0, 2.5}}; const auto result = m1 * m2; - Eigen::Matrix expectedResult; - expectedResult << 6.0, 2.5, 0.0, 2.5; + Eigen::Matrix expectedResult{{6.0, 2.5}, {0.0, 2.5}}; EXPECT_TRUE(expectedResult.isApprox(result)); - Eigen::Matrix m3; - m3 << 1.0, 3.0, 0.5, 2.0, 4.3, 1.2; - - Eigen::Matrix m4; - m4 << 3.0, 1.5, 2.0, 4.5, 2.3, 1.0, 1.6, 3.1, 5.2, 2.1, 2.0, 1.0; + Eigen::Matrix m3{{1.0, 3.0, 0.5}, {2.0, 4.3, 1.2}}; + Eigen::Matrix m4{ + {3.0, 1.5, 2.0, 4.5}, {2.3, 1.0, 1.6, 3.1}, {5.2, 2.1, 2.0, 1.0}}; const auto result2 = m3 * m4; - Eigen::Matrix expectedResult2; - expectedResult2 << 12.5, 5.55, 7.8, 14.3, 22.13, 9.82, 13.28, 23.53; + Eigen::Matrix expectedResult2{{12.5, 5.55, 7.8, 14.3}, + {22.13, 9.82, 13.28, 23.53}}; EXPECT_TRUE(expectedResult2.isApprox(result2)); } TEST(EigenTest, TransposeTest) { - Eigen::Matrix vec; - vec << 1, 2, 3; + Eigen::Vector vec{1, 2, 3}; const auto transpose = vec.transpose(); - Eigen::Matrix expectedTranspose; - expectedTranspose << 1, 2, 3; + Eigen::RowVector expectedTranspose{1, 2, 3}; EXPECT_TRUE(expectedTranspose.isApprox(transpose)); } TEST(EigenTest, InverseTest) { - Eigen::Matrix mat; - mat << 1.0, 3.0, 2.0, 5.0, 2.0, 1.5, 0.0, 1.3, 2.5; + Eigen::Matrix mat{ + {1.0, 3.0, 2.0}, {5.0, 2.0, 1.5}, {0.0, 1.3, 2.5}}; const auto inverse = mat.inverse(); const auto identity = Eigen::MatrixXd::Identity(3, 3); diff --git a/wpimath/src/test/native/cpp/FormatterTest.cpp b/wpimath/src/test/native/cpp/FormatterTest.cpp index 644ebef44f..cd7ef5cbe4 100644 --- a/wpimath/src/test/native/cpp/FormatterTest.cpp +++ b/wpimath/src/test/native/cpp/FormatterTest.cpp @@ -10,8 +10,7 @@ #include "units/velocity.h" TEST(FormatterTest, Eigen) { - Eigen::Matrix A; - A << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0; + Eigen::Matrix A{{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}}; EXPECT_EQ( " 1.000000 2.000000\n" " 3.000000 4.000000\n" diff --git a/wpimath/src/test/native/cpp/StateSpaceTest.cpp b/wpimath/src/test/native/cpp/StateSpaceTest.cpp index cd8b083ba3..c6e2241b55 100644 --- a/wpimath/src/test/native/cpp/StateSpaceTest.cpp +++ b/wpimath/src/test/native/cpp/StateSpaceTest.cpp @@ -45,8 +45,8 @@ class StateSpace : public testing::Test { void Update(const LinearSystem<2, 1, 1>& plant, LinearSystemLoop<2, 1, 1>& loop, double noise) { - Eigen::Matrix y = plant.CalculateY(loop.Xhat(), loop.U()) + - Eigen::Matrix(noise); + Eigen::Vector y = + plant.CalculateY(loop.Xhat(), loop.U()) + Eigen::Vector{noise}; loop.Correct(y); loop.Predict(kDt); } @@ -55,8 +55,7 @@ TEST_F(StateSpace, CorrectPredictLoop) { std::default_random_engine generator; std::normal_distribution dist{0.0, kPositionStddev}; - Eigen::Matrix references; - references << 2.0, 0.0; + Eigen::Vector references{2.0, 0.0}; loop.SetNextR(references); for (int i = 0; i < 1000; i++) { diff --git a/wpimath/src/test/native/cpp/StateSpaceUtilTest.cpp b/wpimath/src/test/native/cpp/StateSpaceUtilTest.cpp index 89d7c402cd..c1984255cd 100644 --- a/wpimath/src/test/native/cpp/StateSpaceUtilTest.cpp +++ b/wpimath/src/test/native/cpp/StateSpaceUtilTest.cpp @@ -12,12 +12,12 @@ TEST(StateSpaceUtilTest, MakeMatrix) { // Column vector - Eigen::Matrix mat1 = frc::MakeMatrix<2, 1>(1.0, 2.0); + Eigen::Vector mat1 = frc::MakeMatrix<2, 1>(1.0, 2.0); EXPECT_NEAR(mat1(0), 1.0, 1e-3); EXPECT_NEAR(mat1(1), 2.0, 1e-3); // Row vector - Eigen::Matrix mat2 = frc::MakeMatrix<1, 2>(1.0, 2.0); + Eigen::RowVector mat2 = frc::MakeMatrix<1, 2>(1.0, 2.0); EXPECT_NEAR(mat2(0), 1.0, 1e-3); EXPECT_NEAR(mat2(1), 2.0, 1e-3); @@ -102,44 +102,42 @@ TEST(StateSpaceUtilTest, CovArray) { } TEST(StateSpaceUtilTest, WhiteNoiseVectorParameterPack) { - Eigen::Matrix vec = frc::MakeWhiteNoiseVector(2.0, 3.0); + Eigen::Vector vec = frc::MakeWhiteNoiseVector(2.0, 3.0); static_cast(vec); } TEST(StateSpaceUtilTest, WhiteNoiseVectorArray) { - Eigen::Matrix vec = frc::MakeWhiteNoiseVector<2>({2.0, 3.0}); + Eigen::Vector vec = frc::MakeWhiteNoiseVector<2>({2.0, 3.0}); static_cast(vec); } TEST(StateSpaceUtilTest, IsStabilizable) { - Eigen::Matrix A; - Eigen::Matrix B; - B << 0, 1; + Eigen::Matrix B{0, 1}; // We separate the result of IsStabilizable from the assertion because // templates break gtest. // First eigenvalue is uncontrollable and unstable. // Second eigenvalue is controllable and stable. - A << 1.2, 0, 0, 0.5; - bool ret = frc::IsStabilizable<2, 1>(A, B); + Eigen::Matrix A1{{1.2, 0}, {0, 0.5}}; + bool ret = frc::IsStabilizable<2, 1>(A1, B); EXPECT_FALSE(ret); // First eigenvalue is uncontrollable and marginally stable. // Second eigenvalue is controllable and stable. - A << 1, 0, 0, 0.5; - ret = frc::IsStabilizable<2, 1>(A, B); + Eigen::Matrix A2{{1, 0}, {0, 0.5}}; + ret = frc::IsStabilizable<2, 1>(A2, B); EXPECT_FALSE(ret); // First eigenvalue is uncontrollable and stable. // Second eigenvalue is controllable and stable. - A << 0.2, 0, 0, 0.5; - ret = frc::IsStabilizable<2, 1>(A, B); + Eigen::Matrix A3{{0.2, 0}, {0, 0.5}}; + ret = frc::IsStabilizable<2, 1>(A3, B); EXPECT_TRUE(ret); // First eigenvalue is uncontrollable and stable. // Second eigenvalue is controllable and unstable. - A << 0.2, 0, 0, 1.2; - ret = frc::IsStabilizable<2, 1>(A, B); + Eigen::Matrix A4{{0.2, 0}, {0, 1.2}}; + ret = frc::IsStabilizable<2, 1>(A4, B); EXPECT_TRUE(ret); } diff --git a/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp b/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp index e3560603ec..354ed18637 100644 --- a/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp +++ b/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp @@ -7,61 +7,46 @@ #include #include "Eigen/Core" -#include "frc/StateSpaceUtil.h" #include "frc/controller/ControlAffinePlantInversionFeedforward.h" #include "units/time.h" namespace frc { -Eigen::Matrix Dynamics(const Eigen::Matrix& x, - const Eigen::Matrix& u) { - Eigen::Matrix result; - - result = (frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 1.0) * x) + - (frc::MakeMatrix<2, 1>(0.0, 1.0) * u); - - return result; +Eigen::Vector Dynamics(const Eigen::Vector& x, + const Eigen::Vector& u) { + return Eigen::Matrix{{1.0, 0.0}, {0.0, 1.0}} * x + + Eigen::Matrix{0.0, 1.0} * u; } -Eigen::Matrix StateDynamics( - const Eigen::Matrix& x) { - Eigen::Matrix result; - - result = (frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 1.0) * x); - - return result; +Eigen::Vector StateDynamics(const Eigen::Vector& x) { + return Eigen::Matrix{{1.0, 0.0}, {0.0, 1.0}} * x; } TEST(ControlAffinePlantInversionFeedforwardTest, Calculate) { - std::function(const Eigen::Matrix&, - const Eigen::Matrix&)> + std::function(const Eigen::Vector&, + const Eigen::Vector&)> modelDynamics = [](auto& x, auto& u) { return Dynamics(x, u); }; frc::ControlAffinePlantInversionFeedforward<2, 1> feedforward{ - modelDynamics, units::second_t(0.02)}; + modelDynamics, units::second_t{0.02}}; - Eigen::Matrix r; - r << 2, 2; - Eigen::Matrix nextR; - nextR << 3, 3; + Eigen::Vector r{2, 2}; + Eigen::Vector nextR{3, 3}; EXPECT_NEAR(48, feedforward.Calculate(r, nextR)(0, 0), 1e-6); } TEST(ControlAffinePlantInversionFeedforwardTest, CalculateState) { - std::function(const Eigen::Matrix&)> + std::function(const Eigen::Vector&)> modelDynamics = [](auto& x) { return StateDynamics(x); }; - Eigen::Matrix B; - B << 0, 1; + Eigen::Matrix B{0, 1}; frc::ControlAffinePlantInversionFeedforward<2, 1> feedforward{ modelDynamics, B, units::second_t(0.02)}; - Eigen::Matrix r; - r << 2, 2; - Eigen::Matrix nextR; - nextR << 3, 3; + Eigen::Vector r{2, 2}; + Eigen::Vector nextR{3, 3}; EXPECT_NEAR(48, feedforward.Calculate(r, nextR)(0, 0), 1e-6); } diff --git a/wpimath/src/test/native/cpp/controller/LinearPlantInversionFeedforwardTest.cpp b/wpimath/src/test/native/cpp/controller/LinearPlantInversionFeedforwardTest.cpp index a9d1dd4b69..6e61706ff0 100644 --- a/wpimath/src/test/native/cpp/controller/LinearPlantInversionFeedforwardTest.cpp +++ b/wpimath/src/test/native/cpp/controller/LinearPlantInversionFeedforwardTest.cpp @@ -13,19 +13,14 @@ namespace frc { TEST(LinearPlantInversionFeedforwardTest, Calculate) { - Eigen::Matrix A; - A << 1, 0, 0, 1; - - Eigen::Matrix B; - B << 0, 1; + Eigen::Matrix A{{1, 0}, {0, 1}}; + Eigen::Matrix B{0, 1}; frc::LinearPlantInversionFeedforward<2, 1> feedforward{A, B, units::second_t(0.02)}; - Eigen::Matrix r; - r << 2, 2; - Eigen::Matrix nextR; - nextR << 3, 3; + Eigen::Vector r{2, 2}; + Eigen::Vector nextR{3, 3}; EXPECT_NEAR(47.502599, feedforward.Calculate(r, nextR)(0, 0), 0.002); } diff --git a/wpimath/src/test/native/cpp/controller/SimpleMotorFeedforwardTest.cpp b/wpimath/src/test/native/cpp/controller/SimpleMotorFeedforwardTest.cpp index c178ddbb4c..29a789e370 100644 --- a/wpimath/src/test/native/cpp/controller/SimpleMotorFeedforwardTest.cpp +++ b/wpimath/src/test/native/cpp/controller/SimpleMotorFeedforwardTest.cpp @@ -21,21 +21,16 @@ TEST(SimpleMotorFeedforwardTest, Calculate) { double Ka = 0.6; auto dt = 0.02_s; - Eigen::Matrix A; - A << -Kv / Ka; - - Eigen::Matrix B; - B << 1.0 / Ka; + Eigen::Matrix A{-Kv / Ka}; + Eigen::Matrix B{1.0 / Ka}; frc::LinearPlantInversionFeedforward<1, 1> plantInversion{A, B, dt}; frc::SimpleMotorFeedforward simpleMotor{ units::volt_t{Ks}, units::volt_t{Kv} / 1_mps, units::volt_t{Ka} / 1_mps_sq}; - Eigen::Matrix r; - r << 2; - Eigen::Matrix nextR; - nextR << 3; + Eigen::Vector r{2.0}; + Eigen::Vector nextR{3.0}; EXPECT_NEAR(37.524995834325161 + Ks, simpleMotor.Calculate(2_mps, 3_mps, dt).to(), 0.002); diff --git a/wpimath/src/test/native/cpp/estimator/AngleStatisticsTest.cpp b/wpimath/src/test/native/cpp/estimator/AngleStatisticsTest.cpp index bd1e30b6d4..5b25a74939 100644 --- a/wpimath/src/test/native/cpp/estimator/AngleStatisticsTest.cpp +++ b/wpimath/src/test/native/cpp/estimator/AngleStatisticsTest.cpp @@ -10,11 +10,12 @@ #include "frc/estimator/AngleStatistics.h" TEST(AngleStatisticsTest, TestMean) { - Eigen::Matrix sigmas; - sigmas << 1, 1.2, 0, 359 * wpi::numbers::pi / 180, 3 * wpi::numbers::pi / 180, - 0, 1, 2, 0; + Eigen::Matrix sigmas{ + {1, 1.2, 0}, + {359 * wpi::numbers::pi / 180, 3 * wpi::numbers::pi / 180, 0}, + {1, 2, 0}}; // Weights need to produce the mean of the sigmas - Eigen::Vector3d weights{}; + Eigen::Vector3d weights; weights.fill(1.0 / sigmas.cols()); EXPECT_TRUE(Eigen::Vector3d(0.7333333, 0.01163323, 1) @@ -22,16 +23,16 @@ TEST(AngleStatisticsTest, TestMean) { } TEST(AngleStatisticsTest, TestResidual) { - Eigen::Vector3d a(1, 1 * wpi::numbers::pi / 180, 2); - Eigen::Vector3d b(1, 359 * wpi::numbers::pi / 180, 1); + Eigen::Vector3d a{1, 1 * wpi::numbers::pi / 180, 2}; + Eigen::Vector3d b{1, 359 * wpi::numbers::pi / 180, 1}; EXPECT_TRUE(frc::AngleResidual<3>(a, b, 1).isApprox( - Eigen::Vector3d(0, 2 * wpi::numbers::pi / 180, 1))); + Eigen::Vector3d{0, 2 * wpi::numbers::pi / 180, 1})); } TEST(AngleStatisticsTest, TestAdd) { - Eigen::Vector3d a(1, 1 * wpi::numbers::pi / 180, 2); - Eigen::Vector3d b(1, 359 * wpi::numbers::pi / 180, 1); + Eigen::Vector3d a{1, 1 * wpi::numbers::pi / 180, 2}; + Eigen::Vector3d b{1, 359 * wpi::numbers::pi / 180, 1}; - EXPECT_TRUE(frc::AngleAdd<3>(a, b, 1).isApprox(Eigen::Vector3d(2, 0, 3))); + EXPECT_TRUE(frc::AngleAdd<3>(a, b, 1).isApprox(Eigen::Vector3d{2, 0, 3})); } diff --git a/wpimath/src/test/native/cpp/estimator/ExtendedKalmanFilterTest.cpp b/wpimath/src/test/native/cpp/estimator/ExtendedKalmanFilterTest.cpp index f1fbf7d7b4..830895521e 100644 --- a/wpimath/src/test/native/cpp/estimator/ExtendedKalmanFilterTest.cpp +++ b/wpimath/src/test/native/cpp/estimator/ExtendedKalmanFilterTest.cpp @@ -18,8 +18,8 @@ namespace { -Eigen::Matrix Dynamics(const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector Dynamics(const Eigen::Vector& x, + const Eigen::Vector& u) { auto motors = frc::DCMotor::CIM(2); // constexpr double Glow = 15.32; // Low gear ratio @@ -40,36 +40,26 @@ Eigen::Matrix Dynamics(const Eigen::Matrix& x, units::volt_t Vl{u(0)}; units::volt_t Vr{u(1)}; - Eigen::Matrix result; auto v = 0.5 * (vl + vr); - result(0) = v.to() * std::cos(x(2)); - result(1) = v.to() * std::sin(x(2)); - result(2) = ((vr - vl) / (2.0 * rb)).to(); - result(3) = + return Eigen::Vector{ + v.to() * std::cos(x(2)), v.to() * std::sin(x(2)), + ((vr - vl) / (2.0 * rb)).to(), k1.to() * ((C1 * vl).to() + (C2 * Vl).to()) + - k2.to() * ((C1 * vr).to() + (C2 * Vr).to()); - result(4) = + k2.to() * ((C1 * vr).to() + (C2 * Vr).to()), k2.to() * ((C1 * vl).to() + (C2 * Vl).to()) + - k1.to() * ((C1 * vr).to() + (C2 * Vr).to()); - return result; + k1.to() * ((C1 * vr).to() + (C2 * Vr).to())}; } -Eigen::Matrix LocalMeasurementModel( - const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector LocalMeasurementModel( + const Eigen::Vector& x, const Eigen::Vector& u) { static_cast(u); - Eigen::Matrix y; - y << x(2), x(3), x(4); - return y; + return Eigen::Vector{x(2), x(3), x(4)}; } -Eigen::Matrix GlobalMeasurementModel( - const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector GlobalMeasurementModel( + const Eigen::Vector& x, const Eigen::Vector& u) { static_cast(u); - Eigen::Matrix y; - y << x(0), x(1), x(2), x(3), x(4); - return y; + return Eigen::Vector{x(0), x(1), x(2), x(3), x(4)}; } } // namespace @@ -81,8 +71,7 @@ TEST(ExtendedKalmanFilterTest, Init) { {0.5, 0.5, 10.0, 1.0, 1.0}, {0.0001, 0.01, 0.01}, dt}; - Eigen::Matrix u; - u << 12.0, 12.0; + Eigen::Vector u{12.0, 12.0}; observer.Predict(u, dt); auto localY = LocalMeasurementModel(observer.Xhat(), u); @@ -109,19 +98,17 @@ TEST(ExtendedKalmanFilterTest, Convergence) { auto trajectory = frc::TrajectoryGenerator::GenerateTrajectory( waypoints, {8.8_mps, 0.1_mps_sq}); - Eigen::Matrix r = Eigen::Matrix::Zero(); + Eigen::Vector r = Eigen::Vector::Zero(); + Eigen::Vector u = Eigen::Vector::Zero(); - Eigen::Matrix nextR; - Eigen::Matrix u = Eigen::Matrix::Zero(); + auto B = frc::NumericalJacobianU<5, 5, 2>(Dynamics, + Eigen::Vector::Zero(), + Eigen::Vector::Zero()); - auto B = frc::NumericalJacobianU<5, 5, 2>( - Dynamics, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); - - observer.SetXhat(frc::MakeMatrix<5, 1>( + observer.SetXhat(Eigen::Vector{ trajectory.InitialPose().Translation().X().to(), trajectory.InitialPose().Translation().Y().to(), - trajectory.InitialPose().Rotation().Radians().to(), 0.0, 0.0)); + trajectory.InitialPose().Rotation().Radians().to(), 0.0, 0.0}); auto totalTime = trajectory.TotalTime(); for (size_t i = 0; i < (totalTime / dt).to(); ++i) { @@ -131,19 +118,18 @@ TEST(ExtendedKalmanFilterTest, Convergence) { units::meters_per_second_t vr = ref.velocity * (1 + (ref.curvature * rb).to()); - nextR(0) = ref.pose.Translation().X().to(); - nextR(1) = ref.pose.Translation().Y().to(); - nextR(2) = ref.pose.Rotation().Radians().to(); - nextR(3) = vl.to(); - nextR(4) = vr.to(); + Eigen::Vector nextR{ref.pose.Translation().X().to(), + ref.pose.Translation().Y().to(), + ref.pose.Rotation().Radians().to(), + vl.to(), vr.to()}; auto localY = - LocalMeasurementModel(nextR, Eigen::Matrix::Zero()); + LocalMeasurementModel(nextR, Eigen::Vector::Zero()); observer.Correct(u, localY + frc::MakeWhiteNoiseVector(0.0001, 0.5, 0.5)); - Eigen::Matrix rdot = (nextR - r) / dt.to(); - u = B.householderQr().solve( - rdot - Dynamics(r, Eigen::Matrix::Zero())); + Eigen::Vector rdot = (nextR - r) / dt.to(); + u = B.householderQr().solve(rdot - + Dynamics(r, Eigen::Vector::Zero())); observer.Predict(u, dt); diff --git a/wpimath/src/test/native/cpp/estimator/MerweScaledSigmaPointsTest.cpp b/wpimath/src/test/native/cpp/estimator/MerweScaledSigmaPointsTest.cpp index 8420d52530..244270fb35 100644 --- a/wpimath/src/test/native/cpp/estimator/MerweScaledSigmaPointsTest.cpp +++ b/wpimath/src/test/native/cpp/estimator/MerweScaledSigmaPointsTest.cpp @@ -4,32 +4,33 @@ #include -#include "frc/StateSpaceUtil.h" #include "frc/estimator/MerweScaledSigmaPoints.h" namespace drake::math { namespace { TEST(MerweScaledSigmaPointsTest, TestZeroMean) { frc::MerweScaledSigmaPoints<2> sigmaPoints; - auto points = - sigmaPoints.SigmaPoints(frc::MakeMatrix<2, 1>(0.0, 0.0), - frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 1.0)); + auto points = sigmaPoints.SigmaPoints( + Eigen::Vector{0.0, 0.0}, + Eigen::Matrix{{1.0, 0.0}, {0.0, 1.0}}); EXPECT_TRUE( - (points - frc::MakeMatrix<2, 5>(0.0, 0.00173205, 0.0, -0.00173205, 0.0, - 0.0, 0.0, 0.00173205, 0.0, -0.00173205)) + (points - + Eigen::Matrix{{0.0, 0.00173205, 0.0, -0.00173205, 0.0}, + {0.0, 0.0, 0.00173205, 0.0, -0.00173205}}) .norm() < 1e-3); } TEST(MerweScaledSigmaPointsTest, TestNonzeroMean) { frc::MerweScaledSigmaPoints<2> sigmaPoints; - auto points = - sigmaPoints.SigmaPoints(frc::MakeMatrix<2, 1>(1.0, 2.0), - frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 10.0)); + auto points = sigmaPoints.SigmaPoints( + Eigen::Vector{1.0, 2.0}, + Eigen::Matrix{{1.0, 0.0}, {0.0, 10.0}}); EXPECT_TRUE( - (points - frc::MakeMatrix<2, 5>(1.0, 1.00173205, 1.0, 0.998268, 1.0, 2.0, - 2.0, 2.00548, 2.0, 1.99452)) + (points - + Eigen::Matrix{{1.0, 1.00173205, 1.0, 0.998268, 1.0}, + {2.0, 2.0, 2.00548, 2.0, 1.99452}}) .norm() < 1e-3); } } // namespace diff --git a/wpimath/src/test/native/cpp/estimator/UnscentedKalmanFilterTest.cpp b/wpimath/src/test/native/cpp/estimator/UnscentedKalmanFilterTest.cpp index a659baede2..8c9afc10bb 100644 --- a/wpimath/src/test/native/cpp/estimator/UnscentedKalmanFilterTest.cpp +++ b/wpimath/src/test/native/cpp/estimator/UnscentedKalmanFilterTest.cpp @@ -20,8 +20,8 @@ namespace { -Eigen::Matrix Dynamics(const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector Dynamics(const Eigen::Vector& x, + const Eigen::Vector& u) { auto motors = frc::DCMotor::CIM(2); // constexpr double Glow = 15.32; // Low gear ratio @@ -42,49 +42,38 @@ Eigen::Matrix Dynamics(const Eigen::Matrix& x, units::volt_t Vl{u(0)}; units::volt_t Vr{u(1)}; - Eigen::Matrix result; auto v = 0.5 * (vl + vr); - result(0) = v.to() * std::cos(x(2)); - result(1) = v.to() * std::sin(x(2)); - result(2) = ((vr - vl) / (2.0 * rb)).to(); - result(3) = + return Eigen::Vector{ + v.to() * std::cos(x(2)), v.to() * std::sin(x(2)), + ((vr - vl) / (2.0 * rb)).to(), k1.to() * ((C1 * vl).to() + (C2 * Vl).to()) + - k2.to() * ((C1 * vr).to() + (C2 * Vr).to()); - result(4) = + k2.to() * ((C1 * vr).to() + (C2 * Vr).to()), k2.to() * ((C1 * vl).to() + (C2 * Vl).to()) + - k1.to() * ((C1 * vr).to() + (C2 * Vr).to()); - return result; + k1.to() * ((C1 * vr).to() + (C2 * Vr).to())}; } -Eigen::Matrix LocalMeasurementModel( - const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector LocalMeasurementModel( + const Eigen::Vector& x, const Eigen::Vector& u) { static_cast(u); - Eigen::Matrix y; - y << x(2), x(3), x(4); - return y; + return Eigen::Vector{x(2), x(3), x(4)}; } -Eigen::Matrix GlobalMeasurementModel( - const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector GlobalMeasurementModel( + const Eigen::Vector& x, const Eigen::Vector& u) { static_cast(u); - Eigen::Matrix y; - y << x(0), x(1), x(2), x(3), x(4); - return y; + return Eigen::Vector{x(0), x(1), x(2), x(3), x(4)}; } } // namespace TEST(UnscentedKalmanFilterTest, Init) { - constexpr auto dt = 0.00505_s; + constexpr auto dt = 5_ms; frc::UnscentedKalmanFilter<5, 2, 3> observer{Dynamics, LocalMeasurementModel, {0.5, 0.5, 10.0, 1.0, 1.0}, {0.0001, 0.01, 0.01}, dt}; - Eigen::Matrix u; - u << 12.0, 12.0; + Eigen::Vector u{12.0, 12.0}; observer.Predict(u, dt); auto localY = LocalMeasurementModel(observer.Xhat(), u); @@ -98,7 +87,7 @@ TEST(UnscentedKalmanFilterTest, Init) { } TEST(UnscentedKalmanFilterTest, Convergence) { - constexpr auto dt = 0.00505_s; + constexpr auto dt = 5_ms; constexpr auto rb = 0.8382_m / 2.0; // Robot radius frc::UnscentedKalmanFilter<5, 2, 3> observer{Dynamics, @@ -113,19 +102,17 @@ TEST(UnscentedKalmanFilterTest, Convergence) { auto trajectory = frc::TrajectoryGenerator::GenerateTrajectory( waypoints, {8.8_mps, 0.1_mps_sq}); - Eigen::Matrix r = Eigen::Matrix::Zero(); + Eigen::Vector r = Eigen::Vector::Zero(); + Eigen::Vector u = Eigen::Vector::Zero(); - Eigen::Matrix nextR; - Eigen::Matrix u = Eigen::Matrix::Zero(); + auto B = frc::NumericalJacobianU<5, 5, 2>(Dynamics, + Eigen::Vector::Zero(), + Eigen::Vector::Zero()); - auto B = frc::NumericalJacobianU<5, 5, 2>( - Dynamics, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); - - observer.SetXhat(frc::MakeMatrix<5, 1>( + observer.SetXhat(Eigen::Vector{ trajectory.InitialPose().Translation().X().to(), trajectory.InitialPose().Translation().Y().to(), - trajectory.InitialPose().Rotation().Radians().to(), 0.0, 0.0)); + trajectory.InitialPose().Rotation().Radians().to(), 0.0, 0.0}); auto trueXhat = observer.Xhat(); @@ -137,19 +124,18 @@ TEST(UnscentedKalmanFilterTest, Convergence) { units::meters_per_second_t vr = ref.velocity * (1 + (ref.curvature * rb).to()); - nextR(0) = ref.pose.Translation().X().to(); - nextR(1) = ref.pose.Translation().Y().to(); - nextR(2) = ref.pose.Rotation().Radians().to(); - nextR(3) = vl.to(); - nextR(4) = vr.to(); + Eigen::Vector nextR{ref.pose.Translation().X().to(), + ref.pose.Translation().Y().to(), + ref.pose.Rotation().Radians().to(), + vl.to(), vr.to()}; auto localY = - LocalMeasurementModel(trueXhat, Eigen::Matrix::Zero()); + LocalMeasurementModel(trueXhat, Eigen::Vector::Zero()); observer.Correct(u, localY + frc::MakeWhiteNoiseVector(0.0001, 0.5, 0.5)); - Eigen::Matrix rdot = (nextR - r) / dt.to(); - u = B.householderQr().solve( - rdot - Dynamics(r, Eigen::Matrix::Zero())); + Eigen::Vector rdot = (nextR - r) / dt.to(); + u = B.householderQr().solve(rdot - + Dynamics(r, Eigen::Vector::Zero())); observer.Predict(u, dt); diff --git a/wpimath/src/test/native/cpp/system/DiscretizationTest.cpp b/wpimath/src/test/native/cpp/system/DiscretizationTest.cpp index 55862d476a..e24517d4ca 100644 --- a/wpimath/src/test/native/cpp/system/DiscretizationTest.cpp +++ b/wpimath/src/test/native/cpp/system/DiscretizationTest.cpp @@ -15,20 +15,17 @@ // Check that for a simple second-order system that we can easily analyze // analytically, TEST(DiscretizationTest, DiscretizeA) { - Eigen::Matrix contA; - contA << 0, 1, 0, 0; + Eigen::Matrix contA{{0, 1}, {0, 0}}; - Eigen::Matrix x0; - x0 << 1, 1; + Eigen::Vector x0{1, 1}; Eigen::Matrix discA; frc::DiscretizeA<2>(contA, 1_s, &discA); - Eigen::Matrix x1Discrete = discA * x0; + Eigen::Vector x1Discrete = discA * x0; // We now have pos = vel = 1 and accel = 0, which should give us: - Eigen::Matrix x1Truth; - x1Truth(0) = 1.0 * x0(0) + 1.0 * x0(1); - x1Truth(1) = 0.0 * x0(0) + 1.0 * x0(1); + Eigen::Vector x1Truth{1.0 * x0(0) + 1.0 * x0(1), + 0.0 * x0(0) + 1.0 * x0(1)}; EXPECT_EQ(x1Truth, x1Discrete); } @@ -36,26 +33,20 @@ TEST(DiscretizationTest, DiscretizeA) { // Check that for a simple second-order system that we can easily analyze // analytically, TEST(DiscretizationTest, DiscretizeAB) { - Eigen::Matrix contA; - contA << 0, 1, 0, 0; + Eigen::Matrix contA{{0, 1}, {0, 0}}; + Eigen::Matrix contB{0, 1}; - Eigen::Matrix contB; - contB << 0, 1; - - Eigen::Matrix x0; - x0 << 1, 1; - Eigen::Matrix u; - u << 1; + Eigen::Vector x0{1, 1}; + Eigen::Vector u{1}; Eigen::Matrix discA; Eigen::Matrix discB; frc::DiscretizeAB<2, 1>(contA, contB, 1_s, &discA, &discB); - Eigen::Matrix x1Discrete = discA * x0 + discB * u; + Eigen::Vector x1Discrete = discA * x0 + discB * u; // We now have pos = vel = accel = 1, which should give us: - Eigen::Matrix x1Truth; - x1Truth(0) = 1.0 * x0(0) + 1.0 * x0(1) + 0.5 * u(0); - x1Truth(1) = 0.0 * x0(0) + 1.0 * x0(1) + 1.0 * u(0); + Eigen::Vector x1Truth{1.0 * x0(0) + 1.0 * x0(1) + 0.5 * u(0), + 0.0 * x0(0) + 1.0 * x0(1) + 1.0 * u(0)}; EXPECT_EQ(x1Truth, x1Discrete); } @@ -64,11 +55,8 @@ TEST(DiscretizationTest, DiscretizeAB) { // Test that the discrete approximation of Q ≈ ∫ e^(Aτ) Q e^(Aᵀτ) dτ // 0 TEST(DiscretizationTest, DiscretizeSlowModelAQ) { - Eigen::Matrix contA; - contA << 0, 1, 0, 0; - - Eigen::Matrix contQ; - contQ << 1, 0, 0, 1; + Eigen::Matrix contA{{0, 1}, {0, 0}}; + Eigen::Matrix contQ{{1, 0}, {0, 1}}; constexpr auto dt = 1_s; @@ -97,11 +85,8 @@ TEST(DiscretizationTest, DiscretizeSlowModelAQ) { // Test that the discrete approximation of Q ≈ ∫ e^(Aτ) Q e^(Aᵀτ) dτ // 0 TEST(DiscretizationTest, DiscretizeFastModelAQ) { - Eigen::Matrix contA; - contA << 0, 1, 0, -1406.29; - - Eigen::Matrix contQ; - contQ << 0.0025, 0, 0, 1; + Eigen::Matrix contA{{0, 1}, {0, -1406.29}}; + Eigen::Matrix contQ{{0.0025, 0}, {0, 1}}; constexpr auto dt = 5_ms; @@ -128,11 +113,8 @@ TEST(DiscretizationTest, DiscretizeFastModelAQ) { // Test that the Taylor series discretization produces nearly identical results. TEST(DiscretizationTest, DiscretizeSlowModelAQTaylor) { - Eigen::Matrix contA; - contA << 0, 1, 0, 0; - - Eigen::Matrix contQ; - contQ << 1, 0, 0, 1; + Eigen::Matrix contA{{0, 1}, {0, 0}}; + Eigen::Matrix contQ{{1, 0}, {0, 1}}; constexpr auto dt = 1_s; @@ -141,7 +123,7 @@ TEST(DiscretizationTest, DiscretizeSlowModelAQTaylor) { Eigen::Matrix discATaylor; // Continuous Q should be positive semidefinite - Eigen::SelfAdjointEigenSolver esCont(contQ); + Eigen::SelfAdjointEigenSolver esCont{contQ}; for (int i = 0; i < contQ.rows(); ++i) { EXPECT_GE(esCont.eigenvalues()[i], 0); } @@ -167,7 +149,7 @@ TEST(DiscretizationTest, DiscretizeSlowModelAQTaylor) { EXPECT_LT((discA - discATaylor).norm(), 1e-10); // Discrete Q should be positive semidefinite - Eigen::SelfAdjointEigenSolver esDisc(discQTaylor); + Eigen::SelfAdjointEigenSolver esDisc{discQTaylor}; for (int i = 0; i < discQTaylor.rows(); ++i) { EXPECT_GE(esDisc.eigenvalues()[i], 0); } @@ -175,11 +157,8 @@ TEST(DiscretizationTest, DiscretizeSlowModelAQTaylor) { // Test that the Taylor series discretization produces nearly identical results. TEST(DiscretizationTest, DiscretizeFastModelAQTaylor) { - Eigen::Matrix contA; - contA << 0, 1, 0, -1500; - - Eigen::Matrix contQ; - contQ << 0.0025, 0, 0, 1; + Eigen::Matrix contA{{0, 1}, {0, -1500}}; + Eigen::Matrix contQ{{0.0025, 0}, {0, 1}}; constexpr auto dt = 5_ms; @@ -222,11 +201,8 @@ TEST(DiscretizationTest, DiscretizeFastModelAQTaylor) { // Test that DiscretizeR() works TEST(DiscretizationTest, DiscretizeR) { - Eigen::Matrix contR; - contR << 2.0, 0.0, 0.0, 1.0; - - Eigen::Matrix discRTruth; - discRTruth << 4.0, 0.0, 0.0, 2.0; + Eigen::Matrix contR{{2.0, 0.0}, {0.0, 1.0}}; + Eigen::Matrix discRTruth{{4.0, 0.0}, {0.0, 2.0}}; Eigen::Matrix discR = frc::DiscretizeR<2>(contR, 500_ms); diff --git a/wpimath/src/test/native/cpp/system/LinearSystemIDTest.cpp b/wpimath/src/test/native/cpp/system/LinearSystemIDTest.cpp index 3949c60648..1fa12c2575 100644 --- a/wpimath/src/test/native/cpp/system/LinearSystemIDTest.cpp +++ b/wpimath/src/test/native/cpp/system/LinearSystemIDTest.cpp @@ -7,7 +7,6 @@ #include #include -#include "frc/StateSpaceUtil.h" #include "frc/system/plant/LinearSystemId.h" #include "units/length.h" #include "units/mass.h" @@ -17,32 +16,37 @@ TEST(LinearSystemIDTest, IdentifyDrivetrainVelocitySystem) { frc::DCMotor::NEO(4), 70_kg, 0.05_m, 0.4_m, 6.0_kg_sq_m, 6.0); ASSERT_TRUE(model.A().isApprox( - frc::MakeMatrix<2, 2>(-10.14132, 3.06598, 3.06598, -10.14132), 0.001)); + Eigen::Matrix{{-10.14132, 3.06598}, {3.06598, -10.14132}}, + 0.001)); ASSERT_TRUE(model.B().isApprox( - frc::MakeMatrix<2, 2>(4.2590, -1.28762, -1.2876, 4.2590), 0.001)); - ASSERT_TRUE( - model.C().isApprox(frc::MakeMatrix<2, 2>(1.0, 0.0, 0.0, 1.0), 0.001)); - ASSERT_TRUE( - model.D().isApprox(frc::MakeMatrix<2, 2>(0.0, 0.0, 0.0, 0.0), 0.001)); + Eigen::Matrix{{4.2590, -1.28762}, {-1.2876, 4.2590}}, + 0.001)); + ASSERT_TRUE(model.C().isApprox( + Eigen::Matrix{{1.0, 0.0}, {0.0, 1.0}}, 0.001)); + ASSERT_TRUE(model.D().isApprox( + Eigen::Matrix{{0.0, 0.0}, {0.0, 0.0}}, 0.001)); } TEST(LinearSystemIDTest, ElevatorSystem) { auto model = frc::LinearSystemId::ElevatorSystem(frc::DCMotor::NEO(2), 5_kg, 0.05_m, 12); ASSERT_TRUE(model.A().isApprox( - frc::MakeMatrix<2, 2>(0.0, 1.0, 0.0, -99.05473), 0.001)); - ASSERT_TRUE(model.B().isApprox(frc::MakeMatrix<2, 1>(0.0, 20.8), 0.001)); - ASSERT_TRUE(model.C().isApprox(frc::MakeMatrix<1, 2>(1.0, 0.0), 0.001)); - ASSERT_TRUE(model.D().isApprox(frc::MakeMatrix<1, 1>(0.0), 0.001)); + Eigen::Matrix{{0.0, 1.0}, {0.0, -99.05473}}, 0.001)); + ASSERT_TRUE( + model.B().isApprox(Eigen::Matrix{0.0, 20.8}, 0.001)); + ASSERT_TRUE(model.C().isApprox(Eigen::Matrix{1.0, 0.0}, 0.001)); + ASSERT_TRUE(model.D().isApprox(Eigen::Matrix{0.0}, 0.001)); } TEST(LinearSystemIDTest, FlywheelSystem) { auto model = frc::LinearSystemId::FlywheelSystem(frc::DCMotor::NEO(2), 0.00032_kg_sq_m, 1.0); - ASSERT_TRUE(model.A().isApprox(frc::MakeMatrix<1, 1>(-26.87032), 0.001)); - ASSERT_TRUE(model.B().isApprox(frc::MakeMatrix<1, 1>(1354.166667), 0.001)); - ASSERT_TRUE(model.C().isApprox(frc::MakeMatrix<1, 1>(1.0), 0.001)); - ASSERT_TRUE(model.D().isApprox(frc::MakeMatrix<1, 1>(0.0), 0.001)); + ASSERT_TRUE( + model.A().isApprox(Eigen::Matrix{-26.87032}, 0.001)); + ASSERT_TRUE( + model.B().isApprox(Eigen::Matrix{1354.166667}, 0.001)); + ASSERT_TRUE(model.C().isApprox(Eigen::Matrix{1.0}, 0.001)); + ASSERT_TRUE(model.D().isApprox(Eigen::Matrix{0.0}, 0.001)); } TEST(LinearSystemIDTest, IdentifyPositionSystem) { @@ -53,9 +57,10 @@ TEST(LinearSystemIDTest, IdentifyPositionSystem) { auto model = frc::LinearSystemId::IdentifyPositionSystem( kv * 1_V / 1_mps, ka * 1_V / 1_mps_sq); - ASSERT_TRUE(model.A().isApprox(frc::MakeMatrix<2, 2>(0.0, 1.0, 0.0, -kv / ka), - 0.001)); - ASSERT_TRUE(model.B().isApprox(frc::MakeMatrix<2, 1>(0.0, 1.0 / ka), 0.001)); + ASSERT_TRUE(model.A().isApprox( + Eigen::Matrix{{0.0, 1.0}, {0.0, -kv / ka}}, 0.001)); + ASSERT_TRUE( + model.B().isApprox(Eigen::Matrix{0.0, 1.0 / ka}, 0.001)); } TEST(LinearSystemIDTest, IdentifyVelocitySystem) { @@ -67,6 +72,6 @@ TEST(LinearSystemIDTest, IdentifyVelocitySystem) { auto model = frc::LinearSystemId::IdentifyVelocitySystem( kv * 1_V / 1_mps, ka * 1_V / 1_mps_sq); - ASSERT_TRUE(model.A().isApprox(frc::MakeMatrix<1, 1>(-kv / ka), 0.001)); - ASSERT_TRUE(model.B().isApprox(frc::MakeMatrix<1, 1>(1.0 / ka), 0.001)); + ASSERT_TRUE(model.A().isApprox(Eigen::Matrix{-kv / ka}, 0.001)); + ASSERT_TRUE(model.B().isApprox(Eigen::Matrix{1.0 / ka}, 0.001)); } diff --git a/wpimath/src/test/native/cpp/system/NumericalIntegrationTest.cpp b/wpimath/src/test/native/cpp/system/NumericalIntegrationTest.cpp index b644ddc25f..fd9c039ca0 100644 --- a/wpimath/src/test/native/cpp/system/NumericalIntegrationTest.cpp +++ b/wpimath/src/test/native/cpp/system/NumericalIntegrationTest.cpp @@ -10,14 +10,11 @@ // Tests that integrating dx/dt = e^x works. TEST(NumericalIntegrationTest, Exponential) { - Eigen::Matrix y0; - y0(0) = 0.0; + Eigen::Vector y0{0.0}; - Eigen::Matrix y1 = frc::RK4( - [](Eigen::Matrix x) { - Eigen::Matrix y; - y(0) = std::exp(x(0)); - return y; + Eigen::Vector y1 = frc::RK4( + [](const Eigen::Vector& x) { + return Eigen::Vector{std::exp(x(0))}; }, y0, 0.1_s); EXPECT_NEAR(y1(0), std::exp(0.1) - std::exp(0), 1e-3); @@ -25,45 +22,36 @@ TEST(NumericalIntegrationTest, Exponential) { // Tests that integrating dx/dt = e^x works when we provide a U. TEST(NumericalIntegrationTest, ExponentialWithU) { - Eigen::Matrix y0; - y0(0) = 0.0; + Eigen::Vector y0{0.0}; - Eigen::Matrix y1 = frc::RK4( - [](Eigen::Matrix x, Eigen::Matrix u) { - Eigen::Matrix y; - y(0) = std::exp(u(0) * x(0)); - return y; + Eigen::Vector y1 = frc::RK4( + [](const Eigen::Vector& x, const Eigen::Vector& u) { + return Eigen::Vector{std::exp(u(0) * x(0))}; }, - y0, (Eigen::Matrix() << 1.0).finished(), 0.1_s); + y0, Eigen::Vector{1.0}, 0.1_s); EXPECT_NEAR(y1(0), std::exp(0.1) - std::exp(0), 1e-3); } // Tests that integrating dx/dt = e^x works with RKF45. TEST(NumericalIntegrationTest, ExponentialRKF45) { - Eigen::Matrix y0; - y0(0) = 0.0; + Eigen::Vector y0{0.0}; - Eigen::Matrix y1 = frc::RKF45( - [](Eigen::Matrix x, Eigen::Matrix u) { - Eigen::Matrix y; - y(0) = std::exp(x(0)); - return y; + Eigen::Vector y1 = frc::RKF45( + [](const Eigen::Vector& x, const Eigen::Vector& u) { + return Eigen::Vector{std::exp(x(0))}; }, - y0, (Eigen::Matrix() << 0.0).finished(), 0.1_s); + y0, Eigen::Vector{0.0}, 0.1_s); EXPECT_NEAR(y1(0), std::exp(0.1) - std::exp(0), 1e-3); } // Tests that integrating dx/dt = e^x works with RKDP TEST(NumericalIntegrationTest, ExponentialRKDP) { - Eigen::Matrix y0; - y0(0) = 0.0; + Eigen::Vector y0{0.0}; - Eigen::Matrix y1 = frc::RKDP( - [](Eigen::Matrix x, Eigen::Matrix u) { - Eigen::Matrix y; - y(0) = std::exp(x(0)); - return y; + Eigen::Vector y1 = frc::RKDP( + [](const Eigen::Vector& x, const Eigen::Vector& u) { + return Eigen::Vector{std::exp(x(0))}; }, - y0, (Eigen::Matrix() << 0.0).finished(), 0.1_s); + y0, Eigen::Vector{0.0}, 0.1_s); EXPECT_NEAR(y1(0), std::exp(0.1) - std::exp(0), 1e-3); } diff --git a/wpimath/src/test/native/cpp/system/NumericalJacobianTest.cpp b/wpimath/src/test/native/cpp/system/NumericalJacobianTest.cpp index 66661aaef5..4e64825e12 100644 --- a/wpimath/src/test/native/cpp/system/NumericalJacobianTest.cpp +++ b/wpimath/src/test/native/cpp/system/NumericalJacobianTest.cpp @@ -6,60 +6,53 @@ #include "frc/system/NumericalJacobian.h" -Eigen::Matrix A = (Eigen::Matrix() << 1, 2, 4, 1, 5, - 2, 3, 4, 5, 1, 3, 2, 1, 1, 3, 7) - .finished(); - -Eigen::Matrix B = - (Eigen::Matrix() << 1, 1, 2, 1, 3, 2, 3, 7).finished(); +Eigen::Matrix A{ + {1, 2, 4, 1}, {5, 2, 3, 4}, {5, 1, 3, 2}, {1, 1, 3, 7}}; +Eigen::Matrix B{{1, 1}, {2, 1}, {3, 2}, {3, 7}}; // Function from which to recover A and B -Eigen::Matrix AxBuFn(const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector AxBuFn(const Eigen::Vector& x, + const Eigen::Vector& u) { return A * x + B * u; } // Test that we can recover A from AxBuFn() pretty accurately TEST(NumericalJacobianTest, Ax) { - Eigen::Matrix newA = frc::NumericalJacobianX<4, 4, 2>( - AxBuFn, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); + Eigen::Matrix newA = + frc::NumericalJacobianX<4, 4, 2>(AxBuFn, Eigen::Vector::Zero(), + Eigen::Vector::Zero()); EXPECT_TRUE(newA.isApprox(A)); } // Test that we can recover B from AxBuFn() pretty accurately TEST(NumericalJacobianTest, Bu) { - Eigen::Matrix newB = frc::NumericalJacobianU<4, 4, 2>( - AxBuFn, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); + Eigen::Matrix newB = + frc::NumericalJacobianU<4, 4, 2>(AxBuFn, Eigen::Vector::Zero(), + Eigen::Vector::Zero()); EXPECT_TRUE(newB.isApprox(B)); } -Eigen::Matrix C = - (Eigen::Matrix() << 1, 2, 4, 1, 5, 2, 3, 4, 5, 1, 3, 2) - .finished(); - -Eigen::Matrix D = - (Eigen::Matrix() << 1, 1, 2, 1, 3, 2).finished(); +Eigen::Matrix C{{1, 2, 4, 1}, {5, 2, 3, 4}, {5, 1, 3, 2}}; +Eigen::Matrix D{{1, 1}, {2, 1}, {3, 2}}; // Function from which to recover C and D -Eigen::Matrix CxDuFn(const Eigen::Matrix& x, - const Eigen::Matrix& u) { +Eigen::Vector CxDuFn(const Eigen::Vector& x, + const Eigen::Vector& u) { return C * x + D * u; } // Test that we can recover C from CxDuFn() pretty accurately TEST(NumericalJacobianTest, Cx) { - Eigen::Matrix newC = frc::NumericalJacobianX<3, 4, 2>( - CxDuFn, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); + Eigen::Matrix newC = + frc::NumericalJacobianX<3, 4, 2>(CxDuFn, Eigen::Vector::Zero(), + Eigen::Vector::Zero()); EXPECT_TRUE(newC.isApprox(C)); } // Test that we can recover D from CxDuFn() pretty accurately TEST(NumericalJacobianTest, Du) { - Eigen::Matrix newD = frc::NumericalJacobianU<3, 4, 2>( - CxDuFn, Eigen::Matrix::Zero(), - Eigen::Matrix::Zero()); + Eigen::Matrix newD = + frc::NumericalJacobianU<3, 4, 2>(CxDuFn, Eigen::Vector::Zero(), + Eigen::Vector::Zero()); EXPECT_TRUE(newD.isApprox(D)); } diff --git a/wpimath/src/test/native/cpp/system/RungeKuttaTimeVaryingTest.cpp b/wpimath/src/test/native/cpp/system/RungeKuttaTimeVaryingTest.cpp index 334712901c..8a7217618f 100644 --- a/wpimath/src/test/native/cpp/system/RungeKuttaTimeVaryingTest.cpp +++ b/wpimath/src/test/native/cpp/system/RungeKuttaTimeVaryingTest.cpp @@ -9,10 +9,9 @@ #include "frc/system/RungeKuttaTimeVarying.h" namespace { -Eigen::Matrix RungeKuttaTimeVaryingSolution(double t) { - return (Eigen::Matrix() - << 12.0 * std::exp(t) / (std::pow(std::exp(t) + 1.0, 2.0))) - .finished(); +Eigen::Vector RungeKuttaTimeVaryingSolution(double t) { + return Eigen::Vector{12.0 * std::exp(t) / + (std::pow(std::exp(t) + 1.0, 2.0))}; } } // namespace @@ -24,13 +23,12 @@ Eigen::Matrix RungeKuttaTimeVaryingSolution(double t) { // // x(t) = 12 * e^t / ((e^t + 1)^2) TEST(RungeKuttaTimeVaryingTest, RungeKuttaTimeVarying) { - Eigen::Matrix y0 = RungeKuttaTimeVaryingSolution(5.0); + Eigen::Vector y0 = RungeKuttaTimeVaryingSolution(5.0); - Eigen::Matrix y1 = frc::RungeKuttaTimeVarying( - [](units::second_t t, Eigen::Matrix x) { - return (Eigen::Matrix() - << x(0) * (2.0 / (std::exp(t.to()) + 1.0) - 1.0)) - .finished(); + Eigen::Vector y1 = frc::RungeKuttaTimeVarying( + [](units::second_t t, const Eigen::Vector& x) { + return Eigen::Vector{ + x(0) * (2.0 / (std::exp(t.to()) + 1.0) - 1.0)}; }, 5_s, y0, 1_s); EXPECT_NEAR(y1(0), RungeKuttaTimeVaryingSolution(6.0)(0), 1e-3);