Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register
  • Index
  • » Users
  • » Volvo742
  • » Profile

Posts

Posts

Dec-08-17 21:25:52
Category: Programming

Hi!

You cannot use if-statements like that. Modelica only use IF-satements for choosing constants to variables, not choosing which equation you want to use.

Think mathematically! 

Nobody knows how to do a IF-statement for equations?

Hi!

Let's say that we have those equations:

Code:


// Compute the flow out.
  C2.Q = (A2*v*6)/ve;
// Set the position
  rod.s = s;
// Compute the derivative of position
  v = der(s);
// ODE equation of the cylinder
  M * der(v) = 10 * A1 * C1.P * me + rod.f + 10 * A2 * C2.P * me;

But let's say that I want my code to look like this:


Code:


// Compute the flow out depending on v
if v > 0 then
  C2.Q = (A2*v*6)/ve;
elseif v < 0 then
  C1.Q = (A1*v*6)/ve;
else
  C1.Q = 0;
  C2.Q = 0;
end if;

// Set the position - With saturation
if s > maxL then
  rod.s = maxL;
  s = 0;
elseif s < 0 then
  rod.s = 0;
  s = 0;
else
  rod.s = s;
end if;

// Compute the derivative of position
  v = der(s);
// ODE equation of the cylinder
  M * der(v) = 10 * A1 * C1.P * me + rod.f + 10 * A2 * C2.P * me;

The problem here is that code would result a very bad simulation. It won't probably work. My equation is how I can implement if-elseif-else statement to "change" equation? For example: If the velocity v is greater that 0, then my equation for liquid flow is going to be this. But if the velocity is less that 0, then my equation for liquid flow is going to be this insted.

Do you know how to do?

Found the solution!

Insted of this:

Code:

// ODE equation of the cylinder

  10 * A1 * C1.P * me = M * der(v) + rod.f + 10 * A2 * C2.P * me;

use this:

Code:

// ODE equation of the cylinder

M * der(v) = 10 * A1 * C1.P * me + rod.f + 10 * A2 * C2.P * me;

Hi!

This is my setup:

https://www.openmodelica.org/images/agorapro/attachments/5412/mini_Markering-013.png

It's only the cylinder I have some problems with. The cylinder's code lines are those:

Code:

model Double_acting_cylinder "Hydraulic cylinder"

  // Mass of piston and rod
  parameter Modelica.SIunits.Mass M "Mass of piston and rod";
  // Area of piston cap area
  parameter EasyHydraulics.Setup.AreaUnit A1 "Area cap side";
  // Area of piston rod area
  parameter EasyHydraulics.Setup.AreaUnit A2 "Area rod side";
  // Rod lenght
  parameter Modelica.SIunits.Length L "Length of rod";
  // Volymetric efficiency of cylinder
  parameter EasyHydraulics.Setup.EfficiencyUnit ve(start = 0) "Volymetric efficiency";
  // Mechanic efficiency of cylinder
  parameter EasyHydraulics.Setup.EfficiencyUnit me(start = 0) "Mechanic efficiency";
  // Position of cylinder
  Modelica.SIunits.Position s(start = 0) "Position rod";
  // Velocity of cylinder
  Modelica.SIunits.Position v(start = 0) "Velocity rod";
  // Input of cylinder
  EasyHydraulics.Setup.Connecter C1 annotation(...);
  // Output of cylinder
  EasyHydraulics.Setup.Connecter C2 annotation(...);
  // Connection rod
  Modelica.Mechanics.Translational.Interfaces.Flange_b rod annotation(...);
equation
  // Compute the flow out and in
  C2.Q = C1.Q*A2/A1;
  // Compute the position
  rod.s = s;
  // Compute the derivative of position
  v = der(s);
  // ODE equation of the cylinder
  10 * A1 * C1.P * me = M * der(v) + rod.f + 10 * A2 * C2.P * me;
  annotation(...)
end Double_acting_cylinder;

Below the "equation". I first compute the output flow at the cylinder. Then I sett the rod's  position equal to the rod position s. Then I take the derivative of position s to find the velocity v.

After I have found the velocity v, I simulate the ordinary differential equation:

10*Cap Area * Pressure at Cap side * mechanical efficiency = Mass of (rod + piston)*accleration + force at the rod + 10*Area rod side * pressure at rod side * mechanical efficiency.

Notice that I multiply the areas with 10, because the area's is in cm^2 and not m^2. Hydraulic units.

My question is: Why does this not working? I think it has something to do with the values I sett the position of the rod because the results of position and velocity of the rod look like this:


https://www.openmodelica.org/images/agorapro/attachments/5412/mini_Markering-017.png


Is this right thing to do? Set the position of rod

Code:

rod.s = s;

Then get the force from the spring.

Code:

rod.f

Edit:

The code says:

Code:

  // Velocity of cylinder

  Modelica.SIunits.Position v(start = 0) "Velocity rod"

But it should be

Code:

  // Velocity of cylinder

  Modelica.SIunits.Velocity v(start = 0) "Velocity rod"

The results are the same anyway.

sjoelund.se wrote:


I think you're a bit confused about how Modelica connections work. If your pump is sending 9 l/min from pump.C.Q, then from the cylinder's perspective, cylinder.C1.Q must be -9 l/min (it is receiving 9 l/min from some other component); because connections are zero-sum. If you check for example a simple electrical circuit in the standard library, and connect a constant source of 1V to a 1Ohm resistor, then one port of the resistor will be -1A and the other port will be 1A; but the component will also calculate an internal parameter i which is 1A and is the actual flow through the resistor. You could naturally calculate such a flow for the component itself if you'd like and think that's more natural than "+ is outgoing, - is incoming".

Thank you. That was a good answer on my question. Kirchhoff strömlag.

Hi!

This is my model. It's a pump, hydraulic cylinder and two tanks.

The problem is that if the pump pumps out 9 l/min, then the cylinder is going to observe those flow values as -9 l/min. How can I "by pass" this problem?


https://openmodelica.org/images/agorapro/attachments/5412/mini_Markering-010.png

The code for the pump has those equations

Code:


C1.Q = D * n * ve / 1000;
C2.Q = C1.Q;

The connector C2(input) and C1(output) has two variables: P(pressure) and Q(flow).

The cylinder has those equations

Code:


// Velocity equation of piston
  v = C2.Q * ve / (A2 * 6);
// Compute with area A2 and flow C2.Q
// Input flow equation
  C1.Q = C2.Q * A1 / A2;
// Saturation - Piston position equation
  if v * time > L then
    s = L;
  elseif v * time < 0 then
    s = 0;
  else
    s = v * time;
  end if;
// set position at piston
  piston.s = s;
// ODE equation of the cylinder
  M * der(v) = 10 * A1 * C1.P * me - piston.f - 10 * A2 * C2.P * me;

Where C2 is output and C1 is input.


https://openmodelica.org/images/agorapro/attachments/5412/mini_Markering-011.png

I have attached my library.


1510783475_EasyHydraulics.mo

Leonard wrote:


Hi!

your Connector in the tank model is missing an annotation. If you drag the connector Connecter from the library into the tank model then you can use it as desired.
You can add the input from the connector to a variable like this:

Code:


  EasyHydraulics.Setup.Connecter C
  Modelica.SIunits.Pressure P;
equation
  P = C.P;

Thanks! It working now.

Hi!

I trying to build my own library in OpenModelica. It going to be a hydraulic library. Right know I have build a tank, but no signal cannot connect to it as you see.


https://www.openmodelica.org/images/agorapro/attachments/5412/mini_Tank-symbol.png


My code for this tank is:

Code:

model Tank

  parameter EasyHydraulics.Setup.PressureUnit P;
  EasyHydraulics.Setup.Connecter C;
 
  annotation(
    Diagram(graphics = {Rectangle(origin = {-53, -12}, fillColor = {0, 0, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-7, 32}, {13, -48}}), Rectangle(origin = {0, -49}, fillColor = {0, 8, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-40, 9}, {40, -11}}), Rectangle(origin = {50, -21}, fillColor = {8, 15, 251}, fillPattern = FillPattern.VerticalCylinder, extent = {{10, -39}, {-10, 41}}), Rectangle(origin = {0, 20}, fillColor = {1, 6, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-10, 40}, {10, -22}})}, coordinateSystem(initialScale = 0.1)),
    Icon(graphics = {Rectangle(origin = {-53, -12}, fillColor = {0, 0, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-7, 32}, {13, -48}}), Rectangle(origin = {0, -49}, fillColor = {0, 8, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-40, 9}, {40, -11}}), Rectangle(origin = {50, -21}, fillColor = {8, 15, 251}, fillPattern = FillPattern.VerticalCylinder, extent = {{10, -39}, {-10, 41}}), Rectangle(origin = {0, 20}, fillColor = {1, 6, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-10, 40}, {10, -22}})}, coordinateSystem(initialScale = 0.1)));
end Tank;

If I insert this code

Code:

Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a

    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));

So it would look like this:

Code:

model Tank

  parameter EasyHydraulics.Setup.PressureUnit P;
  EasyHydraulics.Setup.Connecter C;

  Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
 
  annotation(
    Diagram(graphics = {Rectangle(origin = {-53, -12}, fillColor = {0, 0, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-7, 32}, {13, -48}}), Rectangle(origin = {0, -49}, fillColor = {0, 8, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-40, 9}, {40, -11}}), Rectangle(origin = {50, -21}, fillColor = {8, 15, 251}, fillPattern = FillPattern.VerticalCylinder, extent = {{10, -39}, {-10, 41}}), Rectangle(origin = {0, 20}, fillColor = {1, 6, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-10, 40}, {10, -22}})}, coordinateSystem(initialScale = 0.1)),
    Icon(graphics = {Rectangle(origin = {-53, -12}, fillColor = {0, 0, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-7, 32}, {13, -48}}), Rectangle(origin = {0, -49}, fillColor = {0, 8, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-40, 9}, {40, -11}}), Rectangle(origin = {50, -21}, fillColor = {8, 15, 251}, fillPattern = FillPattern.VerticalCylinder, extent = {{10, -39}, {-10, 41}}), Rectangle(origin = {0, 20}, fillColor = {1, 6, 255}, fillPattern = FillPattern.VerticalCylinder, extent = {{-10, 40}, {10, -22}})}, coordinateSystem(initialScale = 0.1)));
end Tank;

The tank will look like this then:


https://www.openmodelica.org/images/agorapro/attachments/5412/mini_Tank-symbol-with-input.png

So my question is: How do I insert a graphical input so it can be connected to a variable?

I have attached my library.
EasyHydraulics.mo

The reason why I'm writing a library is to learn both hydraulics and programming with modelica.

knkc wrote:


This is how you define a port

connector Electrical_port
import Modelica.SIunits.*;
  Voltage v "Potential at the pin" ;
  flow Current i ;
end Electrical_port;

After you've defined a port. drag and drop this port in the resistor model. And you can code a simple resistor model with the equation V = I*R as shown below

model Resistor
import Modelica.SIunits.*;
Voltage v ;
Current i "Current flowing from pin p to pin n";
parameter Resistance R (start=1)
    "Resistance at temperature T_ref";
Electrical_port p annotation(
    Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Electrical_port n annotation(
    Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
  v = p.v - n.v;
  0 = p.i + n.i;
  i = p.i;
  v = R*i;
end Resistor;

Likewise, you can create a similar model for inductor and capacitor. Once the ports are in place you can drag and drop all these classes in a model and connect them as you want and you can run the simulation.

Hope this helps for more information you can refer the link given by adrpo

So I need to use openmodelica SI-units and packages If I want to connect ODE's ? Or else it won't work?

adrpo wrote:


You can see some examples here:
http://spoken-tutorial.org/tutorial-sea … ge=English (also linked from our first www.openmodelica.org) page.

Thank you. But that Indian didin't show compleatly how to develop classes, who contain an ODE,  and then connect them all.

knkc wrote:


To connect classes or models, you should use ports.
- Ports will exchange information between the two classes you've defined based on how you've connected them.
- You can define your own ports or use the ports existing in the Standard library.

Can you show me an exemple?

Let say that you do a RLC-circuit and every component has its own dynamic system.

Nobody knows how to use own made classes into a model?

Hello!

Can someone show me how to connect two differential equation? Let's say I got two classes, mass with the differential equation F = m*a and the other class, spring with the differential equation F = k*x. k = spring stiffness and x = the length. m = mass in Kg and a = acceleration in m/s^2.

So i got two classes. Now I want to connect thoose two in a model so it will become a mass-spring system. How do I do that?

The purpose with this question is that I want to modleing with differential equation from classes into a model.

perost wrote:


Yes, that's one of the main points of using Modelica, that you can create parts and connect them together. There's already a big standard library available that contains all the parts you list, see the Modelica library in OMEdit.

Thank you for your answer.

Is it better to learn codeing or the "drag and drop"-method?

Hello!

This might seems to be a stupid question. But I wonder if I can create e.g a class who contains a differential equation of a resistor v = R*i.

Let's say that i want to model up a circurit of resistors. Can I then add in that class into a model and connect the resistors with each other?

Or is it not easy as it sounds like? Beacuse I want to create a class of an object e.g spring, mass, resistor, cacapitor, damper etc. Then i want to connect those with each other in OpenModelica.

Beacuse in normal cases with paper and pen, i need to create a big state space model with a big matrix, then simulate. But I don't want to create a big state speace model and simulate. I want to create classes of part models and then insert them into the model and simulate. No state space and matrix. Just first order ODE in classes.

Is that possible?

Hello!

I'm new to OpenModelica. I wonder which one i should use when it comes to simulate a model? ODE or DAE?

I'm very used to ODE due to Laplace transform when it comes to frequency analisis and State-space when it comes to more that one input/output e.g complex systems. But I see that a lot of OpenModelica users are using DAE insted of ODE - why? Is the Modelica language better fitt with DAE insted of ODE?

  • Index
  • » Users
  • » Volvo742
  • » Profile
You are here: