8#include <Eigen/Eigenvalues>
68 return {
"psi_sd",
"psi_sq",
"psi_dr",
69 "psi_qr",
"mechanical_speed",
"electrical_angle"};
73 Real nominalFrequency,
Int polePairs,
Real statorResistance,
74 Real rotorResistance,
Real statorInductance,
Real rotorInductance,
75 Real mutualInductance,
Real rotorInertia,
Real mechanicalDamping,
76 Real mechanicalTorque,
Real initialElectricalAngle,
77 Bool autoInitializeMechanicalTorque) {
79 if (nominalFrequency <= 0.0)
80 throw std::invalid_argument(
"Nominal frequency must be positive.");
82 throw std::invalid_argument(
"The number of pole pairs must be positive.");
84 if (statorResistance < 0.0)
85 throw std::invalid_argument(
"Stator resistance is invalid.");
86 if (rotorResistance < 0.0)
87 throw std::invalid_argument(
"Rotor resistance is invalid.");
89 if (statorInductance <= 0.0 || rotorInductance <= 0.0 ||
90 mutualInductance <= 0.0)
91 throw std::invalid_argument(
"Motor winding inductances must be positive.");
93 if (statorInductance <= mutualInductance ||
94 rotorInductance <= mutualInductance)
95 throw std::invalid_argument(
96 "Each total winding inductance must exceed its mutual inductance.");
98 if (rotorInertia <= 0.0)
99 throw std::invalid_argument(
"Rotor inertia must be positive.");
100 if (mechanicalDamping < 0.0)
101 throw std::invalid_argument(
"Mechanical damping must be non-negative.");
108 mLm = mutualInductance;
109 mLs = statorInductance;
138 throw std::invalid_argument(
139 "The induction motor inductance matrix is singular.");
148 if (!decomposition.isInvertible())
149 throw std::invalid_argument(
150 "The induction motor inverse inductance matrix is singular.");
155 if (eigenSolver.info() != Eigen::Success ||
156 eigenSolver.eigenvalues().minCoeff() <= 0.0)
157 throw std::invalid_argument(
158 "The induction motor inductance matrix is not positive definite.");
171 Real relativeStep,
Real absoluteStep) {
172 if (relativeStep <= 0.0)
173 throw std::invalid_argument(
174 "Relative finite-difference step must be positive.");
175 if (absoluteStep <= 0.0)
176 throw std::invalid_argument(
177 "Absolute finite-difference step must be positive.");
184 Real electricalAngle)
const {
185 electricalAngle = std::remainder(electricalAngle, 2.0 *
PI);
188 const Real scale = std::sqrt(2.0 / 3.0);
190 transform.row(0) << scale * std::cos(electricalAngle),
191 scale * std::cos(electricalAngle - 2.0 *
PI / 3.0),
192 scale * std::cos(electricalAngle + 2.0 *
PI / 3.0);
194 transform.row(1) << -scale * std::sin(electricalAngle),
195 -scale * std::sin(electricalAngle - 2.0 *
PI / 3.0),
196 -scale * std::sin(electricalAngle + 2.0 *
PI / 3.0);
202 Real electricalAngle)
const {
212 speedMatrix(2, 3) = -electricalSpeed;
213 speedMatrix(3, 2) = electricalSpeed;
221 throw std::invalid_argument(
222 "Induction motor state vector has an invalid dimension.");
224 throw std::invalid_argument(
225 "Induction motor input vector has an invalid dimension.");
234 const Real statorCurrentD = current(0, 0);
235 const Real statorCurrentQ = current(1, 0);
240 windingVoltage(0, 0) = voltageDq(0, 0);
241 windingVoltage(1, 0) = voltageDq(1, 0);
242 windingVoltage(2, 0) = 0.0;
243 windingVoltage(3, 0) = 0.0;
252 const Real electricalTorque =
254 (flux(
PsiSd, 0) * statorCurrentQ - flux(
PsiSq, 0) * statorCurrentD);
275 throw std::invalid_argument(
276 "Induction motor state vector has an invalid dimension.");
281 Matrix statorCurrentDq(2, 1);
282 statorCurrentDq << current(0, 0), current(1, 0);
308 xPlus(column, 0) += step;
309 xMinus(column, 0) -= step;
316 A.col(column) = (fPlus - fMinus) / (2.0 * step);
317 C.col(column) = (gPlus - gMinus) / (2.0 * step);
327 uPlus(column, 0) += step;
328 uMinus(column, 0) -= step;
335 B.col(column) = (fPlus - fMinus) / (2.0 * step);
336 D.col(column) = (gPlus - gMinus) / (2.0 * step);
351 E = stateDerivative -
A * x -
B * u;
352 F = output -
C * x - D * u;
374 Matrix statorCurrentDq(2, 1);
375 statorCurrentDq << current(0, 0), current(1, 0);
377 const Real electricalTorque =
379 (flux(
PsiSd, 0) * current(1, 0) - flux(
PsiSq, 0) * current(0, 0));
381 const Real electricalPower = voltageDq(0, 0) * statorCurrentDq(0, 0) +
382 voltageDq(1, 0) * statorCurrentDq(1, 0);
383 const Real reactivePower = voltageDq(1, 0) * statorCurrentDq(0, 0) -
384 voltageDq(0, 0) * statorCurrentDq(1, 0);
385 const Real mechanicalLoadTorque =
409 throw std::logic_error(
410 "setParameters() must be called before initialization.");
413 const Matrix initialVoltageAbc = initialVoltagePhasor.real();
427 SPDLOG_LOGGER_INFO(
mSLog,
428 "Cold-start initialization: standstill, zero flux.");
436 return stateDerivative;
Real mJacobianRelativeStep
Attribute< Real >::Ptr mSlip
void rebuildMachineMatrices()
Bool mAutoInitializeMechanicalTorque
void evaluateOutput(const Matrix &x, const Matrix &u, Matrix &output) const
static constexpr Int mElectricalStateSize
Real mJacobianAbsoluteStep
static constexpr Int mStateSize
Attribute< Real >::Ptr mMechanicalSpeedPu
Matrix buildSpeedMatrix(Real electricalSpeed) const
Attribute< Real >::Ptr mStatorVoltageMagnitude
Real mInitialElectricalAngle
std::vector< String > getLocalStateNames() const override
Attribute< Real >::Ptr mMechanicalSpeedLog
Attribute< Real >::Ptr mElectricalPower
Matrix mInverseInductanceMatrix
void initializeFromNodesAndTerminals(Real frequency) override
Initializes Component variables according to power flow data stored in Nodes.
Bool updateComponentParameters() override
Attribute< Real >::Ptr mReactivePower
Attribute< Real >::Ptr mStatorCurrentD
void evaluateStateDerivative(const Matrix &x, const Matrix &u, Matrix &stateDerivative) const
Attribute< Real >::Ptr mElectricalAngleLog
Attribute< Real >::Ptr mMechanicalLoadTorque
void setParameters(Real nominalFrequency, Int polePairs, Real statorResistance, Real rotorResistance, Real statorInductance, Real rotorInductance, Real mutualInductance, Real rotorInertia, Real mechanicalDamping, Real mechanicalTorque, Real initialElectricalAngle=0.0, Bool autoInitializeMechanicalTorque=true)
Configure the sixth-order machine.
Real mNominalMechanicalSpeed
Attribute< Real >::Ptr mStatorCurrentMagnitude
Matrix getInterfaceVoltage() const
SSN_InductionMotor(String uid, String name, Logger::Level logLevel=Logger::Level::off)
void updateLogAttributes(const Matrix &u) const override
Update derived attributes used for logging/inspection.
void setMechanicalTorque(Real mechanicalTorque)
Matrix getInterfaceCurrent() const
static constexpr Int mOutputSize
Attribute< Real >::Ptr mStatorVoltageQ
Matrix getStateDerivative() const
void buildStateSpaceModel(const Matrix &x, const Matrix &u, Matrix &A, Matrix &B, Matrix &C, Matrix &D, Matrix &E, Matrix &F) const
Attribute< Real >::Ptr mElectricalTorque
Matrix getInverseParkTransformMatrix(Real electricalAngle) const
Matrix getParkTransformMatrix(Real electricalAngle) const
Attribute< Real >::Ptr mStatorVoltageD
void setNumericalLinearizationParameters(Real relativeStep, Real absoluteStep)
static constexpr Int mInputSize
void calculateNumericalJacobians(const Matrix &x, const Matrix &u, Matrix &A, Matrix &B, Matrix &C, Matrix &D) const
Attribute< Real >::Ptr mStatorCurrentQ
TwoTerminalVTypeVariableSSNComp(String uid, String name, Logger::Level logLevel=Logger::Level::off)
MatrixComp buildInitialInputFromNodes(Real frequency) override final
const Attribute< Matrix >::Ptr mX
void setStateOffset(const Matrix &E)
Matrix calculateHistoryVector() const override final
void setParameters(const Matrix &A, const Matrix &B, const Matrix &C, const Matrix &D)
const Matrix & stateOffset() const
void updateStateSpaceModel() override final
Hook for variable/time-varying SSN components.
void setOutputOffset(const Matrix &F)
const Matrix & outputOffset() const
String uid()
Returns unique id.
AttributeList::Ptr mAttributes
Attribute List.
spdlog::level::level_enum Level
const Attribute< MatrixVar< Real > >::Ptr mIntfCurrent
const Attribute< MatrixVar< Real > >::Ptr mIntfVoltage
bool mParametersSet
Flag indicating that parameters are set via setParameters() function.
Logger::Log mSLog
Component logger.
Eigen::Matrix< Real, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > Matrix
Dense matrix for real numbers.
Eigen::Matrix< Complex, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > MatrixComp
Dense matrix for complex numbers.