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

How to model stops

How to model stops

Hi,
I want to model a stop for a cylinder, so when the piston hits the bottom there will be no further movement.

So I grabbed the sweptVolume model and added a little bit, so that when a certain position is reached a strong spring is kicking in and forces the piston to a hold.

I also found a model of a stop from an old Modelica Library, that sets position and velocity to zero, when the stop is reached. It forces the position and velocity to be state variables. I tried to replicate that in my model, which is currently commented out.

But neither of this ideas had satisfactory results. Now  I am out of ideas, so I will be happy for every new idea of you.

Cylinder Code

Code:

model SweptVolumeWithStop "varying cylindric volume depending on the position of the piston"

  import Modelica.Constants.pi;
  import SI = Modelica.SIunits;
  parameter SI.Area pistonCrossArea "cross sectional area of piston";
  parameter SI.Volume clearance "remaining volume at zero piston stroke";
  SI.Volume V "fluid volume";
  //SI.Velocity v(stateSelect = StateSelect.always) "speed of piston";
  SI.Force F_stop "";
  //SI.Position ps(stateSelect = StateSelect.always) = flange.s;
  //parameter SI.Position smin = Modelica.Constants.small;
  //parameter SI.Position smax = 1;
  parameter SI.ModulusOfElasticity E = 1e6;
  // Mass and energy balance, ports
  extends Modelica.Fluid.Vessels.BaseClasses.PartialLumpedVessel(final fluidVolume = V, heatTransfer(surfaceAreas = {pistonCrossArea + 2 * sqrt(pistonCrossArea * pi) * (flange.s + clearance / pistonCrossArea)}));
  Modelica.Mechanics.Translational.Interfaces.Flange_b flange "translation flange for piston" annotation(Placement(transformation(extent = {{-10, 90}, {10, 110}}, rotation = 0)));
equation
  //assert(flange.s >= 0, "Piston stroke (given by flange.s) must not be smaller than zero!");
  //v = der(flange.s);
  // volume size
  V = clearance + flange.s * pistonCrossArea;
  0 = flange.f + (medium.p - system.p_ambient) * pistonCrossArea + F_stop;
  if flange.s <= clearance / pistonCrossArea then
    F_stop = sqrt(0.5) * pistonCrossArea * E / 7e-3 * abs(flange.s - clearance / pistonCrossArea);
  else
    F_stop = 0;
  end if;
  // energy balances
  Wb_flow = medium.p * pistonCrossArea * (-der(flange.s));
  // definition of port pressures
  for i in 1:nPorts loop
    vessel_ps_static[i] = medium.p;
  end for;
  /*algorithm
                    when initial() then
                      assert(ps > smin or ps >= smin and v >= 0, "Error in initialization of hard stop. (s - L/2) must be >= smin ");
                      assert(ps < smax or ps <= smax and v <= 0, "Error in initialization of hard stop. (s + L/2) must be <= smax ");
                    end when;
                    when not ps < smax then
                      reinit(ps, smax);
                      if not initial() or v > 0 then
                        reinit(v, 0);
                      end if;
                    end when;
                    when not ps > smin then
                      reinit(ps, smin);
                      if not initial() or v < 0 then
                        reinit(v, 0);
                      end if;
                    end when;*/
  annotation(Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100, -100}, {100, 100}}), graphics = {Rectangle(extent = {{-50, 36}, {50, -90}}, lineColor = {0, 0, 255}, pattern = LinePattern.None, lineThickness = 1, fillColor = {170, 213, 255}, fillPattern = FillPattern.Solid), Polygon(points = {{-52, 62}, {-48, 62}, {-48, -30}, {-52, -30}, {-52, 62}}, lineColor = {95, 95, 95}, smooth = Smooth.None, fillColor = {135, 135, 135}, fillPattern = FillPattern.Backward), Polygon(points = {{48, 60}, {52, 60}, {52, -34}, {48, -34}, {48, 60}}, lineColor = {95, 95, 95}, smooth = Smooth.None, fillColor = {135, 135, 135}, fillPattern = FillPattern.Backward), Rectangle(extent = {{-48, 40}, {48, 30}}, lineColor = {95, 95, 95}, fillColor = {135, 135, 135}, fillPattern = FillPattern.Forward), Rectangle(extent = {{-6, 92}, {6, 40}}, lineColor = {95, 95, 95}, fillColor = {135, 135, 135}, fillPattern = FillPattern.Forward), Polygon(points = {{-48, -90}, {48, -90}, {48, 70}, {52, 70}, {52, -94}, {-52, -94}, {-52, 70}, {-48, 70}, {-48, -90}}, lineColor = {95, 95, 95}, smooth = Smooth.None, fillColor = {135, 135, 135}, fillPattern = FillPattern.Backward), Line(visible = use_HeatTransfer, points = {{-100, 0}, {-52, 0}}, smooth = Smooth.None, color = {198, 0, 0})}));
end SweptVolumeWithStop;


Code of test environment


Code:

model test_cylinder

  inner Modelica.Fluid.System system annotation(Placement(visible = true, transformation(origin = {72, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Fluid.Sources.Boundary_pT boundary(p = 200000, nPorts = 1, redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater) annotation(Placement(visible = true, transformation(origin = {-70, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Fluid.Pipes.StaticPipe pipe(length = 20, diameter = 0.01, redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater) annotation(Placement(visible = true, transformation(origin = {-28, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  SweptVolumeWithStop sweptvolumewithstop1(pistonCrossArea = 1, clearance = 2e-7, nPorts = 1, use_portsData = false, redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater) annotation(Placement(visible = true, transformation(origin = {30, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.Translational.Components.InitializeFlange initializeflange1(use_s_start = true, use_v_start = false, use_a_start = false) annotation(Placement(visible = true, transformation(origin = {70, 70}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  Modelica.Blocks.Sources.Constant const(k = 1e-3) annotation(Placement(visible = true, transformation(origin = {70, 44}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.Translational.Sources.Force force1 annotation(Placement(visible = true, transformation(origin = {-2, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Sources.Ramp ramp1(height = -3e6, duration = 50) annotation(Placement(visible = true, transformation(origin = {-50, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
  connect(ramp1.y, force1.f) annotation(Line(points = {{-39, 90}, {-14, 90}, {-14, 90}, {-14, 90}}, color = {0, 0, 127}));
  connect(force1.flange, sweptvolumewithstop1.flange) annotation(Line(points = {{8, 90}, {30, 90}, {30, 60}, {30, 60}}, color = {0, 127, 0}));
  connect(const.y, initializeflange1.s_start) annotation(Line(points = {{81, 44}, {94, 44}, {94, 76}, {84, 76}, {84, 76}}, color = {0, 0, 127}));
  connect(initializeflange1.flange, sweptvolumewithstop1.flange) annotation(Line(points = {{60, 70}, {30, 70}, {30, 60}, {30, 60}}, color = {0, 127, 0}));
  connect(pipe.port_b, sweptvolumewithstop1.ports[1]) annotation(Line(points = {{-18, 30}, {30, 30}, {30, 40}, {30, 40}}, color = {0, 127, 255}));
  connect(boundary.ports[1], pipe.port_a) annotation(Line(points = {{-60, 30}, {-38, 30}, {-38, 30}, {-38, 30}}, color = {0, 127, 255}));
  annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), experiment(StartTime = 0, StopTime = 50, Tolerance = 0.0001, Interval = 0.1));
end test_cylinder;

Models of old Modelica Library (I guess)

Code:

model Stop "Sliding mass with hard stop and Stribeck friction"

  extends FrictionBase(s(stateSelect = StateSelect.always));
  Modelica.SIunits.Velocity v(stateSelect = StateSelect.always) "Absolute velocity of flange_a and flange_b";
  Modelica.SIunits.Acceleration a "Absolute acceleration of flange_a and flange_b";
  parameter Modelica.SIunits.Mass m = 1 "mass";
  parameter Real F_prop(final unit = "N/ (m/s)", final min = 0) = 1 "velocity dependent friction";
  parameter Modelica.SIunits.Force F_Coulomb = 5 "constant friction: Coulomb force";
  parameter Modelica.SIunits.Force F_Stribeck = 10 "Stribeck effect";
  parameter Real fexp(final unit = "1/ (m/s)", final min = 0) = 2 "exponential decay";
equation
  // Constant auxiliary variables
  f0 = F_Coulomb + F_Stribeck;
  f0_max = f0 * 1.001;
  free = f0 <= 0 and F_prop <= 0 and s > smin + L / 2 and s < smax - L / 2;
  // Velocity and acceleration of flanges
  v = der(s);
  a = der(v);
  v_relfric = v;
  a_relfric = a;
  // Equilibrium of forces
  0 = flange_a.f + flange_b.f - f - m * der(v);
  // Friction force
  f = if locked then sa else if free then 0 else if startForward then F_prop * v + F_Coulomb + F_Stribeck else if startBackward then F_prop * v - F_Coulomb - F_Stribeck else if pre(mode) == Forward then F_prop * v + F_Coulomb + F_Stribeck * exp(-fexp * abs(v)) else F_prop * v - F_Coulomb - F_Stribeck * exp(-fexp * abs(v));
  // Define events for hard stops and reinitiliaze the state variables velocity v and position s
algorithm
  when initial() then
    assert(s > smin + L / 2 or s >= smin + L / 2 and v >= 0, "Error in initialization of hard stop. (s - L/2) must be >= smin ");
    assert(s < smax - L / 2 or s <= smax - L / 2 and v <= 0, "Error in initialization of hard stop. (s + L/2) must be <= smax ");
  end when;
  when not s < smax - L / 2 then
    reinit(s, smax - L / 2);
    if not initial() or v > 0 then
      reinit(v, 0);
    end if;
  end when;
  when not s > smin + L / 2 then
    reinit(s, smin + L / 2);
    if not initial() or v < 0 then
      reinit(v, 0);
    end if;
  end when;
end Stop;

And the BaseClass of this

Code:

partial model FrictionBase "Base class of Coulomb friction elements"

  extends Modelica.Mechanics.Translational.Interfaces.PartialRigid;
  import SI = Modelica.SIunits;
  parameter SI.Position smax = 25 "right stop for (right end of) sliding mass";
  parameter SI.Position smin = -25 "left stop for (left end of) sliding mass";
  parameter SI.Velocity v_small = 1e-3 "Relative velocity near to zero (see model info text)";
  // Equations to define the following variables have to be defined in subclasses
  SI.Velocity v_relfric "Relative velocity between frictional surfaces";
  SI.Acceleration a_relfric "Relative acceleration between frictional surfaces";
  SI.Force f "Friction force (positive, if directed in opposite direction of v_rel)";
  SI.Force f0 "Friction force for v=0 and forward sliding";
  SI.Force f0_max "Maximum friction force for v=0 and locked";
  Boolean free "true, if frictional element is not active";
  // Equations to define the following variables are given in this class
  Real sa "Path parameter of friction characteristic f = f(a_relfric)";
  Boolean startForward "true, if v_rel=0 and start of forward sliding or v_rel > v_small";
  Boolean startBackward "true, if v_rel=0 and start of backward sliding or v_rel < -v_small";
  Boolean locked "true, if v_rel=0 and not sliding";
  constant Integer Unknown = 3 "Value of mode is not known";
  constant Integer Free = 2 "Element is not active";
  constant Integer Forward = 1 "v_rel > 0 (forward sliding)";
  constant Integer Stuck = 0 "v_rel = 0 (forward sliding, locked or backward sliding)";
  constant Integer Backward = -1 "v_rel < 0 (backward sliding)";
  Integer mode(final min = Backward, final max = Unknown, start = Unknown);
equation
  /* Friction characteristic
             (locked is introduced to help the Modelica translator determining
              the different structural configurations, if for each configuration
              special code shall be generated)
          */
  startForward = pre(mode) == Stuck and (sa > f0_max and s < smax - L / 2 or pre(startForward) and sa > f0 and s < smax - L / 2) or pre(mode) == Backward and v_relfric > v_small or initial() and v_relfric > 0;
  startBackward = pre(mode) == Stuck and (sa < (-f0_max) and s > smin + L / 2 or pre(startBackward) and sa < (-f0) and s > smin + L / 2) or pre(mode) == Forward and v_relfric < (-v_small) or initial() and v_relfric < 0;
  locked = not free and not (pre(mode) == Forward or startForward or pre(mode) == Backward or startBackward);
  a_relfric = if locked then 0 else if free then sa else if startForward then sa - f0 else if startBackward then sa + f0 else if pre(mode) == Forward then sa - f0 else sa + f0;
  /* Friction torque has to be defined in a subclass. Example for a clutch:
               f = if locked then sa else if free then 0 else cgeo*fn*
                        (if startForward  then  Math.tempInterpol1( w_relfric, mue_pos, 2)
                     else if startBackward then -Math.tempInterpol1(-w_relfric, mue_pos, 2)
                     else if pre(mode) == Forward then Math.tempInterpol1(w_relfric, mue_pos, 2)
                     else -Math.tempInterpol1(-w_relfric, mue_pos, 2));
          */
  // finite state machine to determine configuration
  mode = if free then Free else if (pre(mode) == Forward or pre(mode) == Free or startForward) and v_relfric > 0 and s < smax - L / 2 then Forward else if (pre(mode) == Backward or pre(mode) == Free or startBackward) and v_relfric < 0 and s > smin + L / 2 then Backward else Stuck;
end FrictionBase;

Edited by: MProp - Jul-14-15 14:11:24
There are 0 guests and 0 other users also viewing this topic