Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EESM: Correction / Introduction of transfer ratios between rotor and stator #234

Merged
merged 6 commits into from
May 17, 2024

Conversation

max-schenke
Copy link
Member

Refers to #233.

@max-schenke
Copy link
Member Author

Could @MpenaLea elaborate on the theory a little bit?

@max-schenke max-schenke requested review from bhk11 and removed request for atra94 April 23, 2024 09:10
@M-Pena
Copy link

M-Pena commented Apr 23, 2024

Could @MpenaLea elaborate on the theory a little bit?

https://github.com/upb-lea/gym-electric-motor/blame/5443a5157f1320a9d3f8852efc37ae9e77bc619c/gym_electric_motor/physical_systems/electric_motors/externally_excited_synchronous_motor.py#L98
#### Parameters taken from DOI: 10.1109/ICELMACH.2014.6960287 (C. D. Nguyen; W. Hofmann)
The source considers a stator-referred model for the rotor variables and parameters, obtained from [D. Schröder, "Elektrische Antriebe, Regelung von Antriebssystemen," Springer-Verlag, 3. Auflage, 2008], where it is stated: "die rotorseitigen Parameter sind auf den Statorkreis umgerechnet;".

A transformation is required to relate the model rotor parameters and variables to their physical counterpart. This transformation is not unique. It can be done, for example, as detailed in [C. Ong, Dynamic Simulation of Electric Machinery: Using MATLAB/SIMULINK. Prentice Hall PTR, 1998, isbn: 9780137237852, p. 267 and following], neglecting the effect of q-axis and damping windings in the rotor. From this transformation, one obtains:

i_F = (2/3)(N_f/N_s) * i_f
u_F = (N_s/N_f) * u_f
Psi_F = (N_s/N_f) * Psi_f
R_F = (3/2)
(N_s/N_f)^2 * R_f
L_F = (3/2)(N_s/N_f)^2 * L_f
L_dF = L_Fd = (3/2)
(N_s/N_f) * L_df

where the parameters and variables with "f" refer to the physical values, and with "F" these are referred to the stator circuit. N_s and N_f are the stator and field winding number of turns, respectively. The system of equations with rotor variables referred to the stator (F) results in a symmetrical coupling between d and F (L_dF = L_Fd), as is currently internally considered in the model. Appropriate transformations based on the above must be applied to have a valid physical interpretation of the results obtained from the model. Alternatively, the differential equations considered can be modified to only consider physical parameters and variables, e.g., as Q. K. Nguyen, et. al. DOI: [10.1109/ICPE.2015.7168165]

Copy link
Collaborator

@XyDrKRulof XyDrKRulof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on what @M-Pena wrote I think the formulas look correct (besides the magic 77). I would request @bhk11 to also have a deeper look at the model_constants matrix as it is quite difficult to dig through it. I just wonder whether parameters such as r_s and l_d do not have to be transformed?

Also, as a general note, I would like to know whether these changes we introduce here can be expected to be in favor for everyone using GEM or if it is only important for this specific motor parameter set? Or in other words: Should we make this transformation optional inside GEM? Couldn't users do the transformation themselves? What is the most common case here - to transform or not to transform?

r_s mOhm 15.55 Stator resistance
r_e mOhm 7.2 Excitation resistance
l_d mH 1.66 Direct axis inductance
l_q mH 0.35 Quadrature axis inductance
l_m mH 1.589 Mutual inductance
l_e mH 1.74 Excitation inductance
p 1 3 Pole pair number
k 1 65.21 Transfer ratio of number of windings (N_s / N_e)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we introduce k as a parameter instead of N_s and N_e? Is that a common approach for EESM simulations?

mp['l_E'] = mp['k'] ** 2 * 3/2 * mp['l_e']

mp['i_k_rs'] = 2 / 3 / mp['k'] # ratio (i_E / i_e)
mp['sigma'] = 1 - mp['l_M'] ** 2 / (mp['l_d'] * mp['l_E']) * 77
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the 77 here stand for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intended to check whether this is caught by any unit tests 😁
Apparently its not...

Forgot to delete afterwards

mp['l_E'] = mp['k'] ** 2 * 3/2 * mp['l_e']

mp['i_k_rs'] = 2 / 3 / mp['k'] # ratio (i_E / i_e)
mp['sigma'] = 1 - mp['l_M'] ** 2 / (mp['l_d'] * mp['l_E']) * 77
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number

[ 0, -mp['r_s'] / mp['sigma'], 0, mp['l_M'] * mp['r_E'] / (mp['sigma'] * mp['l_E']) * mp['i_k_rs'], 1 / mp['sigma'], 0, -mp['l_M'] * mp['k'] / (mp['sigma'] * mp['l_E']), 0, mp['l_q'] * mp['p'] / mp['sigma'], 0],
[ 0, 0, -mp['r_s'], 0, 0, 1, 0, -mp['l_d'] * mp['p'], 0, -mp['p'] * mp['l_M'] * mp['i_k_rs']],
[ 0, mp['l_M'] * mp['r_s'] / (mp['sigma'] * mp['l_d']), 0, -mp['r_E'] / mp['sigma'] * mp['i_k_rs'], -mp['l_M'] / (mp['sigma'] * mp['l_d']), 0, mp['k'] / mp['sigma'], 0, -mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d']), 0],
[ mp['p'], 0, 0, 0, 0, 0, 0, 0, 0, 0],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I use the linear model, which Mario provide to us, the matrix should look like:
self._model_constants = np.array([ # omega, i_d, i_q, i_e, u_d, u_q, u_e, omega * i_d, omega * i_q, omega * i_e [ 0, -mp['r_s'] / (mp['sigma'] * mp['l_d']), 0, mp['l_M'] * mp['r_E'] / (mp['sigma'] * mp['l_E'] * mp['l_d']) * mp['i_k_rs'], 1 / (mp['sigma'] * mp['l_d']), 0, -mp['l_M'] * mp['k'] / (mp['sigma'] * mp['l_E'] * mp['l_d']), 0, mp['l_q'] * mp['p'] / (mp['sigma'] * mp['l_d']), 0], [ 0, 0, -mp['r_s'] / (mp['l_q']), 0, 0, 1 / (mp['l_q']), 0, -mp['l_d'] * mp['p'] / (mp['l_q']), 0, -mp['p'] * mp['l_M'] * mp['i_k_rs'] / (mp['l_q'])], [ 0, mp['l_M'] * mp['r_s'] / (mp['sigma'] * mp['l_d'] * mp['l_E']), 0, -mp['r_E'] / (mp['sigma'] * mp['l_E']) * mp['i_k_rs'], -mp['l_M'] / (mp['sigma'] * mp['l_d'] * mp['l_E']), 0, mp['k'] / (mp['sigma'] * mp['l_E']), 0, -mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d'] * mp['l_E']), 0], [ mp['p'], 0, 0, 0, 0, 0, 0, 0, 0, 0], ])
to my opinion.

Copy link

@M-Pena M-Pena May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest changes look correct as far as I can tell, accounting for the modifications done in lines 144-146. In your suggestion, I am missing some parameters in the equations for d(i_e)/dt. That whole matrix row must be divided by mp['i_k_rs']

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would agree. According to my notes, I have written down the equation for di_E/dt.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be correct now:

self._model_constants = np.array([ # omega, i_d, i_q, i_e, u_d, u_q, u_e, omega * i_d, omega * i_q, omega * i_e
[ 0, -mp['r_s'] / (mp['sigma'] * mp['l_d']), 0, mp['l_M'] * mp['r_E'] / (mp['sigma'] * mp['l_E'] * mp['l_d']) * mp['i_k_rs'], 1 / (mp['sigma'] * mp['l_d']), 0, -mp['l_M'] * mp['k'] / (mp['sigma'] * mp['l_E'] * mp['l_d']), 0, mp['l_q'] * mp['p'] / (mp['sigma'] * mp['l_d']), 0],
[ 0, 0, -mp['r_s'] / (mp['l_q']), 0, 0, 1 / (mp['l_q']), 0, -mp['l_d'] * mp['p'] / (mp['l_q']), 0, -mp['p'] * mp['l_M'] * mp['i_k_rs'] / (mp['l_q'])],
[ 0, mp['l_M'] * mp['r_s'] / (mp['sigma'] * mp['l_d'] * mp['l_E'] * mp['i_k_rs']), 0, -mp['r_E'] / (mp['sigma'] * mp['l_E']), -mp['l_M'] / (mp['sigma'] * mp['l_d'] * mp['l_E'] * mp['i_k_rs']), 0, mp['k'] / (mp['sigma'] * mp['l_E'] * mp['i_k_rs']), 0, -mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d'] * mp['l_E'] * mp['i_k_rs']), 0],
[ mp['p'], 0, 0, 0, 0, 0, 0, 0, 0, 0],
])

Copy link
Member

@bhk11 bhk11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check the Jacobian yet. Would you agree to the changes for the _model_constants?

@max-schenke max-schenke changed the base branch from master to nightly April 25, 2024 07:08
@max-schenke max-schenke requested a review from XyDrKRulof May 13, 2024 07:36
@XyDrKRulof
Copy link
Collaborator

I am still somewhat questioning why we introduce the transfer ratio of number of windings instead of the number of windings themselves. Especially because all other motor parameters are actual physical properties. I don't mind as long as the logic is now correct, though.

@XyDrKRulof XyDrKRulof closed this May 13, 2024
@XyDrKRulof
Copy link
Collaborator

Mistakenly closed this pull request. Sorry

@XyDrKRulof XyDrKRulof reopened this May 13, 2024
[ -mp['r_s'] / (mp['l_d'] * mp['sigma']), mp['l_q'] / (mp['sigma'] * mp['l_d']) * omega * mp['p'], mp['l_M'] * mp['r_e'] / (mp['sigma'] * mp['l_d'] * mp['l_E']) * mp['i_k_rs'], 0],
[ -mp['l_d'] / mp['l_q'] * omega * mp['p'], -mp['r_s'] / mp['l_q'], -omega * mp['p'] * mp['l_E'] / mp['l_q'] * mp['i_k_rs'], 0],
[mp['l_M'] * mp['r_s'] / (mp['sigma'] * mp['l_d'] * mp['l_E']), -omega * mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d'] * mp['l_E']), -mp['r_E'] / mp['l_E'] * mp['i_k_rs'], 0],
[ 0, 0, 0, 0],
]),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe lines 198-201 should be replaced with
[ -mp['r_s'] / (mp['l_d'] * mp['sigma']), mp['l_q'] / (mp['sigma'] * mp['l_d']) * omega * mp['p'], mp['l_M'] * mp['r_E'] / (mp['sigma'] * mp['l_d'] * mp['l_E']) * mp['i_k_rs'], 0],
[ -mp['l_d'] / mp['l_q'] * omega * mp['p'], -mp['r_s'] / mp['l_q'], -omega * mp['p'] * mp['l_M'] / mp['l_q'] * mp['i_k_rs'], 0],
[mp['l_M'] * mp['r_s'] / (mp['sigma'] * mp['l_d'] * mp['l_E']* mp['i_k_rs']), -omega * mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d'] * mp['l_E']* mp['i_k_rs']), -mp['r_E'] / (mp['sigma'] * mp['l_E'])], 0],
[ 0, 0, 0, 0],

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the same solution.

-mp['p'] * mp['l_d'] / mp['l_q'] * state[self.I_SD_IDX] - mp['p'] * mp['l_m'] / mp['l_q'] * state[self.I_E_IDX],
-mp['p'],
-mp['p'] * mp['l_d'] / mp['l_q'] * state[self.I_SD_IDX] - mp['p'] * mp['l_M'] / mp['l_q'] * state[self.I_E_IDX] * mp['i_k_rs'],
-mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d'] * mp['l_E']),
Copy link

@M-Pena M-Pena May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction to line 206
-mp['p'] * mp['l_M'] * mp['l_q'] / (mp['sigma'] * mp['l_d'] * mp['l_E'] * mp['i_k_rs']) * state[self.I_SQ_IDX],

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a / mp['sigma'] missing in line 204?

1.5 * mp['p'] * (mp['l_e'] * state[self.I_E_IDX] + (mp['l_d'] - mp['l_q']) * state[self.I_SD_IDX]),
1.5 * mp['p'] * mp['l_e'] * state[self.I_SQ_IDX],
1.5 * mp['p'] * (mp['l_E'] * state[self.I_E_IDX] * mp['i_k_rs'] + (mp['l_d'] - mp['l_q']) * state[self.I_SD_IDX]),
1.5 * mp['p'] * mp['l_E'] * state[self.I_SQ_IDX],
0,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 211 and 212
1.5 * mp['p'] * (mp['l_M'] * state[self.I_E_IDX] * mp['i_k_rs'] + (mp['l_d'] - mp['l_q']) * state[self.I_SD_IDX]),

1.5 * mp['p'] * mp['l_M'] * mp['i_k_rs'] * state[self.I_SQ_IDX],

Copy link
Member

@bhk11 bhk11 May 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This correction looks also fine to me.

Copy link
Member

@bhk11 bhk11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks correct to me.

@max-schenke max-schenke merged commit 4ee85c4 into nightly May 17, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants