Eomys/pyleecan

[CO] OP_matrix object

BonneelP opened this issue · 8 comments

Hello all,

We plan to work on WRSM in the near future and we will have an issue with OP_matrix: we would need to add a new column for If (then it would be N0, Id, Iq, If) but for now 4th column is for reference torque and 5th for reference power. Technically 4th column could be power if is_power=True, is_torque=False but I don't think that it works in the code.
There is a "type_OP_matrix" that exist but it is not convenient to always pass both OP_matrix and type_OP_matrix every time (technically we should also pass is_torque and is_power to know if these columns are set). One day we may also need to add temperature column(s) as well. Regarding electrical model we could also need to set Ud, Uq, Id, Iq.

So we plan to introduce an OP_matrix object, I think as a unique class with type_OP_matrix as property but polymorphism on type_OP_matrix could also be used (then it would require to import the correct object type).

Regarding properties:
There is one open question, should we keep the matrix that change size according to is_power, is_torque or should we have a "fixed size matrix" (N0, Id, Iq and sometimes If) and Pem_ref, Tem_ref properties ? I think that self.Pem_ref/Tem_ref would be more convenient for future evolution (and the method would be clearer), we just need to create proper getter/setter.

Regarding methods:
get_OP_list and get_OP(index) that would create the proper OP object according to the contain of the object.
We can also introduce a method get_OP_matrix("Id","Iq", is_unique=True) to find the unique operating points or to return the OP_matrix as before (with the explicit size)
A set_OP_matrix method could also be convenient to set all properties at once in particular if we use self.Pem_ref and self.Tem_ref

For convenience/retro-compatibility, we can introduce a _set_OP_matrix to overwrite the generated method to allow to set VarLoadCurrent.OP_matrix as a ndarray by assuming the most common case type_OP_matrix=Id/Iq, is_torque if shape>3.
For WRSM we would introduce a new type_OP_matrix and adapt the get_OP method.

What do you think about this proposal ?

Best regards,
Pierre

Hello @SebGue,

Do you think you will have time to check this issue ? I will soon start experimenting with one single OP_matrix object and Pem_ref/Tem_ref properties. Anyway I will make sure that everything is retro-compatible and works with getter/setter to ease future changes if needed, so no worry if you don't have time ;)

Best regards,
Pierre

Hello @BonneelP,

I think all your proposals utilize some kind of matrix to store OP data.
Have you also considered to store the data to dedicated properties (e.g. OP_matrix.Id, OP_matrix.Iq, ...). So there is no need to think about matrix sizes. Future properties can be added with full retrocompatibility and OP_matrix.get_data("If", ...) would return requested values if the property exists. If there is no such property it could e.g. return None.

A similar alternative would be single OP's, i.e. OP objects with respective properties. These OP's could then be 'collected' in the new OP_matrix.

I hope I got your point with my answer.

Best regards, Sebastian

Hello Sebastian,

Thank you for your fast answer :)
We didn't thought about OP_matrix.Id and it is indeed interesting. The set_OP_matrix would cut column by column the OP_matrix to set each property. We could introduce a syntax like "set_OP_matrix(OP_matrix, "N0", "Id", "Iq", "Pem")", with set_OP_matrix(OP_matrix) assuming N0, Id, Iq (Tem and Pem according to size).

A small "issue" would be I0, Phi0. Either we have I0, Phi0, Id, Iq as properties which is not ideal. Either we always store Id, Iq (conversion when I0, Phi0 is in argument). Same get_OP_matrix("N0", "I0", "Phi0", is_unique=False) would trigger conversion as well. Double conversion could create some computation noise in the OP but I don't think it should be an issue since we format the OP values when converting to str. Anyway there is only OPdq objects.
With this solution, no need to have "type_OP_matrix" any more which is great :)

If I understood well, your second proposal would be to store directly a list of OP and generate the matrix when needed ? That's also an interesting idea since the purpose of this OP_matrix object is to generate OP objects with get_OP_list. Then set_OP_matrix would still take a ndarray as argument but create all the correct OP according to the other arguments.

Don't know yet which solution I will investigate but both of them are interesting, Thanks again for your help.
Best regards,
Pierre

Regarding Idq vs. I0/phi issue, do you think we could implement @Property decorator somehow? This could solve the issue (at least while getting I0/phi)

... I just realized we already got the 'second proposal' with OPdq (and OP). :-)
We would only need to introduce a kind of list object OP_matrix to store the OPs.

Hello Sebastian,

I had a look on the property decorator and I don't understand how you planned to use it. For me, the class generator do a similar job with:
image

Technically we could have I0, Phi0 properties and manually write the getter/setter to store the results within _Id/_Iq instead of having dedicated _I0 and _Phi0. But I think that normalizing the use of "get/set_OP_matrix("N0", "I0", "Phi0")" would do the same work. So we would always store Id/Iq as we did for the OP but the user will have to adapt the call to get_OP_matrix to get I0/Phi0.

Regarding second solution, even if this solution is more convenient, I prefer to have matrices because list of object takes longer to save/load and OP_matrix can get large.

I will start the implementation today, as I plan to work with getter/setter it shouldn't be to hard to adapt/change the implementation if needed.
Best regards,
Pierre

Hello Pierre,

you are right. I forgot about the internal _set_xyz/_get_xyz methods and the possibility to manually override the generated getter/setter. So I think I'm fine with your solution.

Best regards, Sebastian

OP_matrix object are now implemented in v1.4.0, same for WRSM.