Skip to content

Commit 5d9a553

Browse files
[wpilib] DCMotorSim cleanup/enhancement (#7021)
Co-authored-by: Tyler Veness <[email protected]>
1 parent 5acb410 commit 5d9a553

File tree

6 files changed

+244
-68
lines changed

6 files changed

+244
-68
lines changed

wpilibc/src/main/native/cpp/simulation/DCMotorSim.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,30 @@ using namespace frc;
1212
using namespace frc::sim;
1313

1414
DCMotorSim::DCMotorSim(const LinearSystem<2, 1, 2>& plant,
15-
const DCMotor& gearbox, double gearing,
15+
const DCMotor& gearbox,
1616
const std::array<double, 2>& measurementStdDevs)
1717
: LinearSystemSim<2, 1, 2>(plant, measurementStdDevs),
1818
m_gearbox(gearbox),
19-
m_gearing(gearing) {}
20-
21-
DCMotorSim::DCMotorSim(const DCMotor& gearbox, double gearing,
22-
units::kilogram_square_meter_t moi,
23-
const std::array<double, 2>& measurementStdDevs)
24-
: DCMotorSim(LinearSystemId::DCMotorSystem(gearbox, moi, gearing), gearbox,
25-
gearing, measurementStdDevs) {}
19+
// By theorem 6.10.1 of
20+
// https://file.tavsys.net/control/controls-engineering-in-frc.pdf, the
21+
// flywheel state-space model is:
22+
//
23+
// dx/dt = -G²Kₜ/(KᵥRJ)x + (GKₜ)/(RJ)u
24+
// A = -G²Kₜ/(KᵥRJ)
25+
// B = GKₜ/(RJ)
26+
//
27+
// Solve for G.
28+
//
29+
// A/B = -G/Kᵥ
30+
// G = -KᵥA/B
31+
//
32+
// Solve for J.
33+
//
34+
// B = GKₜ/(RJ)
35+
// J = GKₜ/(RB)
36+
m_gearing(-gearbox.Kv.value() * m_plant.A(1, 1) / m_plant.B(1, 0)),
37+
m_j(m_gearing * gearbox.Kt.value() /
38+
(gearbox.R.value() * m_plant.B(1, 0))) {}
2639

2740
void DCMotorSim::SetState(units::radian_t angularPosition,
2841
units::radians_per_second_t angularVelocity) {
@@ -37,6 +50,15 @@ units::radians_per_second_t DCMotorSim::GetAngularVelocity() const {
3750
return units::radians_per_second_t{GetOutput(1)};
3851
}
3952

53+
units::radians_per_second_squared_t DCMotorSim::GetAngularAcceleration() const {
54+
return units::radians_per_second_squared_t{
55+
(m_plant.A() * m_x + m_plant.B() * m_u)(0, 0)};
56+
}
57+
58+
units::newton_meter_t DCMotorSim::GetTorque() const {
59+
return units::newton_meter_t{GetAngularAcceleration().value() * m_j.value()};
60+
}
61+
4062
units::ampere_t DCMotorSim::GetCurrentDraw() const {
4163
// I = V / R - omega / (Kv * R)
4264
// Reductions are greater than 1, so a reduction of 10:1 would mean the motor
@@ -46,6 +68,10 @@ units::ampere_t DCMotorSim::GetCurrentDraw() const {
4668
wpi::sgn(m_u(0));
4769
}
4870

71+
units::volt_t DCMotorSim::GetInputVoltage() const {
72+
return units::volt_t{GetInput(0)};
73+
}
74+
4975
void DCMotorSim::SetInputVoltage(units::volt_t voltage) {
5076
SetInput(Vectord<1>{voltage.value()});
5177
ClampInput(frc::RobotController::GetBatteryVoltage().value());

wpilibc/src/main/native/include/frc/simulation/DCMotorSim.h

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#pragma once
66

77
#include <units/angle.h>
8+
#include <units/angular_acceleration.h>
89
#include <units/angular_velocity.h>
910
#include <units/moment_of_inertia.h>
11+
#include <units/torque.h>
1012

1113
#include "frc/simulation/LinearSystemSim.h"
1214
#include "frc/system/LinearSystem.h"
@@ -27,26 +29,9 @@ class DCMotorSim : public LinearSystemSim<2, 1, 2> {
2729
* radians.
2830
* @param gearbox The type of and number of motors in the DC motor
2931
* gearbox.
30-
* @param gearing The gearing of the DC motor (numbers greater than
31-
* 1 represent reductions).
3232
* @param measurementStdDevs The standard deviation of the measurement noise.
3333
*/
3434
DCMotorSim(const LinearSystem<2, 1, 2>& plant, const DCMotor& gearbox,
35-
double gearing,
36-
const std::array<double, 2>& measurementStdDevs = {0.0, 0.0});
37-
38-
/**
39-
* Creates a simulated DC motor mechanism.
40-
*
41-
* @param gearbox The type of and number of motors in the DC motor
42-
* gearbox.
43-
* @param gearing The gearing of the DC motor (numbers greater than
44-
* 1 represent reductions).
45-
* @param moi The moment of inertia of the DC motor.
46-
* @param measurementStdDevs The standard deviation of the measurement noise.
47-
*/
48-
DCMotorSim(const DCMotor& gearbox, double gearing,
49-
units::kilogram_square_meter_t moi,
5035
const std::array<double, 2>& measurementStdDevs = {0.0, 0.0});
5136

5237
using LinearSystemSim::SetState;
@@ -74,22 +59,59 @@ class DCMotorSim : public LinearSystemSim<2, 1, 2> {
7459
*/
7560
units::radians_per_second_t GetAngularVelocity() const;
7661

62+
/**
63+
* Returns the DC motor acceleration.
64+
*
65+
* @return The DC motor acceleration
66+
*/
67+
units::radians_per_second_squared_t GetAngularAcceleration() const;
68+
69+
/**
70+
* Returns the DC motor torque.
71+
*
72+
* @return The DC motor torque
73+
*/
74+
units::newton_meter_t GetTorque() const;
75+
7776
/**
7877
* Returns the DC motor current draw.
7978
*
8079
* @return The DC motor current draw.
8180
*/
8281
units::ampere_t GetCurrentDraw() const;
8382

83+
/**
84+
* Gets the input voltage for the DC motor.
85+
*
86+
* @return The DC motor input voltage.
87+
*/
88+
units::volt_t GetInputVoltage() const;
89+
8490
/**
8591
* Sets the input voltage for the DC motor.
8692
*
8793
* @param voltage The input voltage.
8894
*/
8995
void SetInputVoltage(units::volt_t voltage);
9096

97+
/**
98+
* Returns the gearbox.
99+
*/
100+
const DCMotor& Gearbox() const { return m_gearbox; }
101+
102+
/**
103+
* Returns the gearing;
104+
*/
105+
double Gearing() const { return m_gearing; }
106+
107+
/**
108+
* Returns the moment of inertia
109+
*/
110+
units::kilogram_square_meter_t J() const { return m_j; }
111+
91112
private:
92113
DCMotor m_gearbox;
93114
double m_gearing;
115+
units::kilogram_square_meter_t m_j;
94116
};
95117
} // namespace frc::sim

wpilibc/src/test/native/cpp/simulation/DCMotorSimTest.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#include "frc/simulation/DCMotorSim.h"
1313
#include "frc/simulation/EncoderSim.h"
1414
#include "frc/simulation/RoboRioSim.h"
15+
#include "frc/system/plant/LinearSystemId.h"
1516

1617
TEST(DCMotorSimTest, VoltageSteadyState) {
1718
frc::DCMotor gearbox = frc::DCMotor::NEO(1);
18-
frc::sim::DCMotorSim sim{gearbox, 1.0,
19-
units::kilogram_square_meter_t{0.0005}};
19+
auto plant = frc::LinearSystemId::DCMotorSystem(
20+
frc::DCMotor::NEO(1), units::kilogram_square_meter_t{0.0005}, 1.0);
21+
frc::sim::DCMotorSim sim{plant, gearbox};
2022

2123
frc::Encoder encoder{0, 1};
2224
frc::sim::EncoderSim encoderSim{encoder};
@@ -60,8 +62,9 @@ TEST(DCMotorSimTest, VoltageSteadyState) {
6062

6163
TEST(DCMotorSimTest, PositionFeedbackControl) {
6264
frc::DCMotor gearbox = frc::DCMotor::NEO(1);
63-
frc::sim::DCMotorSim sim{gearbox, 1.0,
64-
units::kilogram_square_meter_t{0.0005}};
65+
auto plant = frc::LinearSystemId::DCMotorSystem(
66+
frc::DCMotor::NEO(1), units::kilogram_square_meter_t{0.0005}, 1.0);
67+
frc::sim::DCMotorSim sim{plant, gearbox};
6568

6669
frc::PIDController controller{0.04, 0.0, 0.001};
6770

0 commit comments

Comments
 (0)