Opened 5 years ago

Last modified 5 years ago

#5626 new enhancement

Linearize should be available from the OMEdit GUI

Reported by: casella Owned by: adeas31
Priority: high Milestone: 2.0.0
Component: OMEdit Version:
Keywords: Cc: bernt.lie@…, johti17, arun3688, Andrea.Bartolini

Description

Not only from the API script.

Change History (13)

comment:1 follow-up: Changed 5 years ago by casella

  • Cc bernt.lie@… added

It would also be nice to get the A,B,C,D matrices in a format compatible with popular languages supporting systems and control analysis and design, such as Matlab, Python, and Julia

comment:2 in reply to: ↑ 1 ; follow-up: Changed 5 years ago by Karim.Abdelhak

Replying to casella:

It would also be nice to get the A,B,C,D matrices in a format compatible with popular languages supporting systems and control analysis and design, such as Matlab, Python, and Julia

I guess matlab would not be that hard to do, but it would take some time. Maybe generating another result-file-like .mat file, but that is something that has to be implemented in the backend/simcode.

Can Julia and Python parse .mat files? Maybe .csv could be an alternative.

comment:3 Changed 5 years ago by Christoph Buchner <buchner@…>

Python: Not in the standard library, but for Matlab files <=v7.2, scipy covers this.

In later versions I think .mat files are basically HDF5, so there's h5py and I think even pandas available, all libraries that are easy to get and people active in this space will probably already use.

(NB: I have not personally used this yet, haven't touched Matlab in a long time)

In any case, some "generic" exchange format like csv sounds like a good idea to me in any case.

comment:4 in reply to: ↑ 2 Changed 5 years ago by casella

Replying to Karim.Abdelhak:

Replying to casella:

It would also be nice to get the A,B,C,D matrices in a format compatible with popular languages supporting systems and control analysis and design, such as Matlab, Python, and Julia

What I meant was: getting a text window with code that you could copy and paste directly into a Matlab script, or Python/Julia function.

Currently, the linearize() API function returns something like

  parameter Integer n = 2 "number of states";
  parameter Integer p = 1 "number of inputs";
  parameter Integer q = 1 "number of outputs";

  parameter Real x0[n] = {0, 0};
  parameter Real u0[p] = {0};

  parameter Real A[n, n] = [-1, 0; 1, 0];
  parameter Real B[n, p] = [1; 0];
  parameter Real C[q, n] = [0, 2];
  parameter Real D[q, p] = [0];

For Matlab, you should get

  n = 2 % number of states;
  p = 1 % number of inputs;
  q = 1 % number of outputs;

  x0 = [0, 0]';
  u0 = [0]';

  A = [-1, 0; 1, 0];
  B = [1; 0];
  C = [0, 2];
  D = [0];

I guess modifying the code generation that we have to generate the Modelica code in order to generate the Matlab code is a no brainer: as you can see, you just need to remove some stuff and to change some curly braces into square brackets, and stuff like that.

I guess Python and Julia are pretty much the same, though I am not aware of the exact syntax because I don't use them regularly.

This feature would be useful for teaching, when you have preciously little time and the users are absolute beginners. CSV and MAT files would also be nice, but they are already too complicated to manage.

comment:5 Changed 5 years ago by casella

@bernt, is this what you'd like to have? I usually edit the Modelica code of the linearized model manually to transform it into Matlab code, but I understand this is not really practical for basic teaching.

Last edited 5 years ago by casella (previous) (diff)

comment:6 Changed 5 years ago by Karim.Abdelhak

I opened a PR422 for this. It basically changes the generated file. It is not perfectly done right now, but once its merged we can go from there.

The used flag will be --linearizationDumpLanguage=matlab or whatever we want to make it. Modelica target language is default, as it is now.

comment:7 Changed 5 years ago by casella

Good! Once this is ready, I'll hand it over to Adeel for the GUI access.

comment:8 Changed 5 years ago by Karim.Abdelhak

Right now it prints output like the following:

function [n, p, q, x0, u0, A, B, C, D] = linearmodel_GetLinearModel()
  n = 4; % number of states
  p = 0; % number of inputs
  q = 0; % number of outputs
 
  x0 = {1, -2, 3, -5};
  u0 = zeros(0);
 
  A = [-3, 2, 0, 0; -7, 0, -5, 1; -1, 0, -1, 4; 0, 1, -1, 5];
  B = zeros(n, p);
  C = zeros(q, n);
  D = zeros(q, p);
end

Where linearmodel was the original model. As you can see x0 still has curly brackets, this seems to be something thats generated somewhere deep in the cruntime and i could not find it until now. I will fix that later.

Also it is still generated in a .mo file, which is not very problematic i guess since we want to pass it to the GUI anyways.

As already mentioned the flag to use will be --linearizationDumpLanguage=matlab, for now you can run it from terminal/cmd and check the generated file modelname_linearmodel.mo if the results are what you would expect.

The PR should be merged until monday.

Could someone give me an example code for Python and Julia so that i can add them too?

Last edited 5 years ago by Karim.Abdelhak (previous) (diff)

comment:9 Changed 5 years ago by Karim.Abdelhak

It's merged

comment:10 follow-up: Changed 5 years ago by adrpo

  • Cc johti17 arun3688 added

For Julia, something like this (I also added John and Arun in the cc, maybe they can come up with a better version, where one can impose the types I commented out).

function linearmodel_GetLinearModel()
   local n = 4 #= number of states =#
   local p = 0 #= number of inputs =#
   local q = 0 #= number of outputs =#   
   local x0 # ::Array{Float64,1}(undef, n)
   local u0 # ::Array{Float64,1}(undef, p)
   local A  # ::Array{Float64,2}(undef, n, n)
   local B  # ::Array{Float64,2}(undef, n, p)
   local C  # ::Array{Float64,2}(undef, q, n)
   local D  # ::Array{Float64,2}(undef, q, p)

   x0 = [1.0 -2.0 3.0 -5.0]
   u0 = zeros(0) #= shoulnd't be p here? =#

   A = [-3 2 0 0; -7 0 -5 1; -1 0 -1 4; 0 1 -1 5]
   B = zeros(n, p)
   C = zeros(q, n)
   D = zeros(q, p)
   (x0, u0, A, B, C, D)
 end
julia> include("linearize.jl")
linearmodel_GetLinearModel (generic function with 1 method)

julia> linearmodel_GetLinearModel()
([1.0 -2.0 3.0 -5.0], Float64[], [-3 2 0 0; -7 0 -5 1; -1 0 -1 4; 0 1 -1 5], Array{Float64}(4,0), Array{Float64}(0,4), Array{Float64}(0,0))

comment:11 in reply to: ↑ 10 Changed 5 years ago by Karim.Abdelhak

Replying to adrpo:

For Julia, something like this (I also added John and Arun in the cc, maybe they can come up with a better version, where one can impose the types I commented out).

Thanks, i will wait for the others to comment until i implement something then.

   u0 = zeros(0) #= shoulnd't be p here? =#

Yea i was quite surprised by this too, but i guess those got evaluated since they are structural parameters. The original modelica code looks the same.

comment:12 Changed 5 years ago by anonymous

Hi,

I would only suggest you to add info to the variable when it is declared instead of first declaring
them and then assigning them. That would be arguably more "Julian". Usually the Julia compiler can figure things out (It helps that the function is small). However, sometimes it needs help. The most important thing to think about is to preserve type stability

All the best,

John

comment:13 Changed 5 years ago by casella

  • Cc Andrea.Bartolini added

Andrea, can you please provide the same example using Python syntax?

Note: See TracTickets for help on using tickets.