Message Boards Message Boards

Either SystemModelLinearize or TransferFunctionModel does not work for this model

Posted 11 months ago

Hello all,

I'm interested in calculating transfer functions of a complex mechanical system. The model is constructed with System Modeler, and then linearized in Mathematica. The initial conditions of the model are the equilibrium position, around which linearization is made. Then, from the linear state-space equations, the transfer function in frequency domain is calculated.

The problem is that I'm not getting the correct transfer functions. Surprisingly, one of the results that was originally wrong, becomes correct after changing the model in a way that should not have an affect.

Below, the Modelica model is shown, and the notebook for analyzing it is shown further down.

At its bottom lines, the notebook produces the SISO transfer function from f2 to y2, which equals -1 and is a very wrong result. Surprisingly, the correct transfer function is produced after removing the uppermost input components, which physically represents the vertical acceleration of the ground. In order to obtain it, do the following

  1. Disable components prismatic1, accelarate1 and input a (select them with the pointer, right-click, then disable).
  2. Connect component world directly to `spring1.

Execution of the notebook produces a transfer function from f2 to y2 that makes more physical sense.

However, the change does not fix all the problems. There are other SISO transfer function that are still wrong even after removing the upper components. The one from f2 to y3 is an example. It is shown in upper lines of the notebook, and wrongly equals -1 in both versions of the model.

I'm using System Modeler 13.2.0 and Mathematica 13.2.

Any help would be highly appreciated.

Cheers,

Fabián

model AccelerationDriver
  inner Modelica.Mechanics.MultiBody.World world(n = {0, 0, -1}, label2 = "z") annotation(Placement(visible = true, transformation(origin = {-71.141, 81.756}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Forces.Spring spring1(c = 12000, s_unstretched = 0.3) annotation(Placement(visible = true, transformation(origin = {-20, 28.814}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Modelica.Mechanics.MultiBody.Parts.Body body1(m = 100, r_0.start = {0, 0, -0.4}, each r_0.fixed = false, each v_0.fixed = true, each a_0.fixed = true) annotation(Placement(visible = true, transformation(origin = {75, 13.724}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Joints.Prismatic prismatic1(n = {0, 0, 1}, useAxisFlange = true) annotation(Placement(visible = true, transformation(origin = {-36.141, 81.756}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.Translational.Sources.Accelerate accelerate1(useSupport = true) annotation(Placement(visible = true, transformation(origin = {-31.141, 118.47}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealInput a annotation(Placement(visible = true, transformation(origin = {-72.5, 116.756}, extent = {{-11.359, -11.359}, {11.359, 11.359}}, rotation = 0), iconTransformation(origin = {-91.812, 2.887}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Forces.Spring spring2(c = 9000, s_unstretched = 0.3) annotation(Placement(visible = true, transformation(origin = {-20, -18.342}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Modelica.Mechanics.MultiBody.Parts.Body body2(m = 100, r_0.start = {0, 0, -0.4}, each r_0.fixed = false, each v_0.fixed = true, each a_0.fixed = true) annotation(Placement(visible = true, transformation(origin = {75, -38.342}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Parts.Body body3(m = 100, r_0.start = {0, 0, -0.4}, each r_0.fixed = false, each v_0.fixed = true, each a_0.fixed = true) annotation(Placement(visible = true, transformation(origin = {70, -78.342}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Forces.Spring spring3(c = 6000, s_unstretched = 0.3) annotation(Placement(visible = true, transformation(origin = {-20, -58.342}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Modelica.Mechanics.MultiBody.Sensors.RelativePosition relativePosition1 annotation(Placement(visible = true, transformation(origin = {16.545, 28.538}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  Modelica.Mechanics.MultiBody.Sensors.RelativePosition relativePosition2 annotation(Placement(visible = true, transformation(origin = {18.223, -9.844}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  Modelica.Mechanics.MultiBody.Sensors.RelativePosition relativePosition3 annotation(Placement(visible = true, transformation(origin = {20, -58.342}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  Modelica.Blocks.Interfaces.RealOutput y3 annotation(Placement(visible = true, transformation(origin = {52.923, -63.342}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {66.667, 38.889}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealOutput y1 annotation(Placement(visible = true, transformation(origin = {48.051, 28.814}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {66.667, -7.94}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealOutput y2 annotation(Placement(visible = true, transformation(origin = {50, -8.342}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {56.667, -25.985}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Forces.Force force1 annotation(Placement(visible = true, transformation(origin = {-56.555, 30.113}, extent = {{10, -10}, {-10, 10}}, rotation = 450)));
  Modelica.Mechanics.MultiBody.Forces.Force force2 annotation(Placement(visible = true, transformation(origin = {-50, -16.01}, extent = {{10, -10}, {-10, 10}}, rotation = 450)));
  Modelica.Mechanics.MultiBody.Forces.Force force3 annotation(Placement(visible = true, transformation(origin = {-52.008, -58.342}, extent = {{10, -10}, {-10, 10}}, rotation = 450)));
  Modelica.Blocks.Interfaces.RealInput f1 annotation(Placement(visible = true, transformation(origin = {-82.5, 35.113}, extent = {{-7.5, -7.5}, {7.5, 7.5}}, rotation = 0), iconTransformation(origin = {-25.118, 2.526}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealInput f2 annotation(Placement(visible = true, transformation(origin = {-78.863, -11.024}, extent = {{-8.863, -8.863}, {8.863, 8.863}}, rotation = 0), iconTransformation(origin = {-17.118, -5.474}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealInput f3 annotation(Placement(visible = true, transformation(origin = {-80.861, -52.368}, extent = {{-9.139, -9.139}, {9.139, 9.139}}, rotation = 0), iconTransformation(origin = {-9.118, -13.474}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Parts.Body body4(m = 100, r_0.start = {0, 0, -0.4}, each r_0.fixed = false, each v_0.fixed = true, each a_0.fixed = true) annotation(Placement(visible = true, transformation(origin = {70, -130}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Forces.Spring spring4(c = 3000, s_unstretched = 0.3) annotation(Placement(visible = true, transformation(origin = {-20, -110}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  Modelica.Mechanics.MultiBody.Sensors.RelativePosition relativePosition4 annotation(Placement(visible = true, transformation(origin = {20, -110}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
  Modelica.Blocks.Interfaces.RealOutput y4 annotation(Placement(visible = true, transformation(origin = {52.923, -115}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {74.667, 30.889}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Mechanics.MultiBody.Forces.Force force4 annotation(Placement(visible = true, transformation(origin = {-52.008, -110}, extent = {{10, -10}, {-10, 10}}, rotation = 450)));
  Modelica.Blocks.Interfaces.RealInput f4 annotation(Placement(visible = true, transformation(origin = {-80.861, -104.026}, extent = {{-9.139, -9.139}, {9.139, 9.139}}, rotation = 0), iconTransformation(origin = {-1.118, -21.474}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
equation
  force1.force[1] = 0;
  force1.force[2] = 0;
  force2.force[1] = 0;
  force2.force[2] = 0;
  force3.force[1] = 0;
  force3.force[2] = 0;
  force4.force[1] = 0;
  force4.force[2] = 0;
  connect(spring1.frame_b, body1.frame_a) annotation(Line(visible = true, origin = {8.333, 15.421}, points = {{-28.333, 3.393}, {-28.333, -1.697}, {56.667, -1.697}}, color = {95, 95, 95}));
  connect(prismatic1.frame_a, world.frame_b) annotation(Line(visible = true, origin = {-53.641, 81.756}, points = {{7.5, 0}, {-7.5, 0}}, color = {95, 95, 95}));
  connect(accelerate1.flange, prismatic1.axis) annotation(Line(visible = true, origin = {-20.391, 103.113}, points = {{-0.75, 15.357}, {4.25, 15.357}, {4.25, -15.357}, {-7.75, -15.357}}, color = {0, 127, 0}));
  connect(accelerate1.support, prismatic1.support) annotation(Line(visible = true, origin = {-35.641, 100.791}, points = {{4.5, 7.679}, {4.5, 2.678}, {-4.5, 2.678}, {-4.5, -13.035}}, color = {0, 127, 0}));
  connect(a, accelerate1.a_ref) annotation(Line(visible = true, origin = {-62.714, 117.899}, points = {{-9.786, -1.143}, {-9.786, 0.571}, {19.573, 0.571}}, color = {0, 0, 127}));
  connect(spring1.frame_b, spring2.frame_a) annotation(Line(visible = true, origin = {-20, 5.236}, points = {{0, 13.578}, {0, -13.578}}, color = {95, 95, 95}));
  connect(body2.frame_a, spring2.frame_b) annotation(Line(visible = true, origin = {8.333, -35.009}, points = {{56.667, -3.333}, {-28.333, -3.333}, {-28.333, 6.667}}, color = {95, 95, 95}));
  connect(spring2.frame_b, spring3.frame_a) annotation(Line(visible = true, origin = {-20, -38.342}, points = {{0, 10}, {0, -10}}, color = {95, 95, 95}));
  connect(spring3.frame_b, body3.frame_a) annotation(Line(visible = true, origin = {6.667, -75.009}, points = {{-26.667, 6.667}, {-26.667, -3.333}, {53.333, -3.333}}, color = {95, 95, 95}));
  connect(spring1.frame_a, relativePosition1.frame_b) annotation(Line(visible = true, origin = {-1.728, 41.245}, points = {{-18.272, -2.431}, {-18.272, 2.569}, {18.272, 2.569}, {18.273, -2.707}}, color = {95, 95, 95}));
  connect(relativePosition1.frame_a, spring1.frame_b) annotation(Line(visible = true, origin = {-1.728, 16.107}, points = {{18.273, 2.431}, {18.272, -2.569}, {-18.272, -2.569}, {-18.272, 2.707}}, color = {95, 95, 95}));
  connect(relativePosition2.frame_b, spring2.frame_a) annotation(Line(visible = true, origin = {-0.888, 0.532}, points = {{19.111, -0.376}, {19.112, 4.625}, {-19.112, 4.625}, {-19.112, -8.874}}, color = {95, 95, 95}));
  connect(relativePosition2.frame_a, spring2.frame_b) annotation(Line(visible = true, origin = {-0.888, -28.717}, points = {{19.111, 8.873}, {19.112, -4.625}, {-19.112, -4.625}, {-19.112, 0.375}}, color = {95, 95, 95}));
  connect(relativePosition3.frame_b, spring3.frame_a) annotation(Line(visible = true, origin = {0, -45.842}, points = {{20, -2.5}, {20, 2.5}, {-20, 2.5}, {-20, -2.5}}, color = {95, 95, 95}));
  connect(relativePosition3.frame_a, spring3.frame_b) annotation(Line(visible = true, origin = {0, -70.842}, points = {{20, 2.5}, {20, -2.5}, {-20, -2.5}, {-20, 2.5}}, color = {95, 95, 95}));
  connect(relativePosition1.r_rel[3], y1) annotation(Line(visible = true, origin = {41.216, 28.63}, points = {{-13.671, -0.092}, {6.835, -0.092}, {6.835, 0.184}}, color = {0, 0, 127}));
  connect(relativePosition2.r_rel[3], y2) annotation(Line(visible = true, origin = {43.074, -9.343}, points = {{-13.851, -0.501}, {6.926, -0.501}, {6.926, 1.001}}, color = {0, 0, 127}));
  connect(relativePosition3.r_rel[3], y3) annotation(Line(visible = true, origin = {45.616, -60.009}, points = {{-14.616, 1.667}, {7.308, 1.667}, {7.307, -3.333}}, color = {0, 0, 127}));
  connect(force1.frame_a, spring1.frame_a) annotation(Line(visible = true, origin = {-38.277, 42.288}, points = {{-18.278, -2.175}, {-18.277, 2.825}, {18.277, 2.825}, {18.277, -3.474}}, color = {95, 95, 95}));
  connect(force1.frame_b, spring1.frame_b) annotation(Line(visible = true, origin = {-38.277, 16.639}, points = {{-18.278, 3.474}, {-18.277, -2.825}, {18.277, -2.825}, {18.277, 2.175}}, color = {95, 95, 95}));
  connect(force2.frame_a, spring2.frame_a) annotation(Line(visible = true, origin = {-35, -4.093}, points = {{-15, -1.917}, {-15, 3.083}, {15, 3.083}, {15, -4.249}}, color = {95, 95, 95}));
  connect(force2.frame_b, spring2.frame_b) annotation(Line(visible = true, origin = {-35, -30.259}, points = {{-15, 4.249}, {-15, -3.083}, {15, -3.083}, {15, 1.917}}, color = {95, 95, 95}));
  connect(force3.frame_a, spring3.frame_a) annotation(Line(visible = true, origin = {-36.004, -45.842}, points = {{-16.004, -2.5}, {-16.004, 2.5}, {16.004, 2.5}, {16.004, -2.5}}, color = {95, 95, 95}));
  connect(force3.frame_b, spring3.frame_b) annotation(Line(visible = true, origin = {-36.004, -70.842}, points = {{-16.004, 2.5}, {-16.004, -2.5}, {16.004, -2.5}, {16.004, 2.5}}, color = {95, 95, 95}));
  connect(f1, force1.force[3]) annotation(Line(visible = true, origin = {-77.852, 35.78}, points = {{-4.648, -0.667}, {-4.648, 0.333}, {9.297, 0.333}}, color = {0, 0, 127}));
  connect(f2, force2.force[3]) annotation(Line(visible = true, origin = {-73.242, -10.348}, points = {{-5.621, -0.676}, {-5.621, 0.338}, {11.242, 0.338}}, color = {0, 0, 127}));
  connect(f3, force3.force[3]) annotation(Line(visible = true, origin = {-75.243, -52.351}, points = {{-5.618, -0.017}, {-5.618, 0.009}, {11.235, 0.009}}, color = {0, 0, 127}));
  connect(prismatic1.frame_b, spring1.frame_a) annotation(Line(visible = true, origin = {-22.047, 67.442}, points = {{-4.094, 14.314}, {2.047, 14.314}, {2.047, -28.628}}, color = {95, 95, 95}));
  connect(spring4.frame_b, body4.frame_a) annotation(Line(visible = true, origin = {6.667, -126.667}, points = {{-26.667, 6.667}, {-26.667, -3.333}, {53.333, -3.333}}, color = {95, 95, 95}));
  connect(relativePosition4.frame_b, spring4.frame_a) annotation(Line(visible = true, origin = {0, -97.5}, points = {{20, -2.5}, {20, 2.5}, {-20, 2.5}, {-20, -2.5}}, color = {95, 95, 95}));
  connect(relativePosition4.frame_a, spring4.frame_b) annotation(Line(visible = true, origin = {0, -122.5}, points = {{20, 2.5}, {20, -2.5}, {-20, -2.5}, {-20, 2.5}}, color = {95, 95, 95}));
  connect(relativePosition4.r_rel[3], y4) annotation(Line(visible = true, origin = {45.616, -111.667}, points = {{-14.616, 1.667}, {7.308, 1.667}, {7.307, -3.333}}, color = {0, 0, 127}));
  connect(force4.frame_a, spring4.frame_a) annotation(Line(visible = true, origin = {-36.004, -97.5}, points = {{-16.004, -2.5}, {-16.004, 2.5}, {16.004, 2.5}, {16.004, -2.5}}, color = {95, 95, 95}));
  connect(force4.frame_b, spring4.frame_b) annotation(Line(visible = true, origin = {-36.004, -122.5}, points = {{-16.004, 2.5}, {-16.004, -2.5}, {16.004, -2.5}, {16.004, 2.5}}, color = {95, 95, 95}));
  connect(f4, force4.force[3]) annotation(Line(visible = true, origin = {-75.243, -104.009}, points = {{-5.618, -0.017}, {-5.618, 0.009}, {11.235, 0.009}}, color = {0, 0, 127}));
  connect(spring3.frame_b, spring4.frame_a) annotation(Line(visible = true, origin = {-20, -84.171}, points = {{0, 15.829}, {0, -15.829}}, color = {95, 95, 95}));
  annotation(experiment(StopTime = 10.0), Diagram(coordinateSystem(extent = {{-90, -150}, {90, 150}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5})), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10}), graphics = {Rectangle(visible = true, lineColor = {0, 114, 195}, fillColor = {255, 255, 255}, extent = {{-100, -100}, {100, 100}}, radius = 25), Text(visible = true, textColor = {64, 64, 64}, extent = {{-150, 110}, {150, 150}}, textString = "%name")}));
end AccelerationDriver;

POSTED BY: Fabián Peña
2 Replies
Posted 11 months ago

Dear Sergio,

Thank you very much for your reply.

Your suggestion of constraining the motion of the springs in the vertical direction using prismatic joints worked out of the box, without having to adjust anything else other than connecting them and defining the direction of motion. Furthermore, in my original model, it also fixed some warnings about the initial conditions. Also, the mathematical expressions of the transfer functions that were correct, were greatly simplified.

Just for the record, the model that I shared was already some sort of minimal example. The original model is part of a package, with classes that favor the usage of many of instances of the same kind, with many inputs and outputs. Somehow, I was not getting an obvious miscalculation when the number of springs was small. The problem began after increasing the number of components. Somehow, the complexity made the problem evident.

Thank you very much again.

Cheers,

Fabián

POSTED BY: Fabián Peña

You can look at the model DocumentationExamples.Control.CameraStabilizer for help here, specially if, and I'm guessing here, but you seem to be interested in the forces all being aligned along the z axis, so introducing them through prismatic constraints would help, as is done in the model I mention above. This model also has input forces, similarly constrained, and it does some initialization of the system, that I think may be affecting your model. And it forces some state selection through stateSelect = StateSelect.always that may be helpful. If this does not work, consider making a smaller minimal model indicating precisely what you expect in the linearization.

POSTED BY: Sergio Vargas
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract