Message Boards Message Boards

0
|
10615 Views
|
5 Replies
|
4 Total Likes
View groups...
Share
Share this post:

Modeling a preloaded rotational spring in SystemModeler?

I've been trying to model a preloaded rotational spring in SystemModeler for a while now. As far as I understand, there are two ways of constructing this model,

  • By using the components in the Modelica library,
  • By writing the governing equations and creating a custom block.

A translational version of a preloaded spring exists in the Modelica.Mechanics.Translational.Examples.PreLoad directory. As a dirty solution, I can directly use that model and convert the input flange to a rotational flange by using an ideal rolling wheel block, however I don't want this.

I can also modify this model by replacing the translational blocks with their rotational counterparts. However, I'm not sure whether that would work since ElastoGap and ElastoBacklash components are not completely similar.

What I would really like to do was to construct the model by directly writing the governing equations. So I modified the rotational spring model as follows,

model RotationalPreloadedSpring
  extends Modelica.Mechanics.Rotational.Interfaces.PartialCompliantWithRelativeStates;
  parameter Modelica.SIunits.RotationalSpringConstant c(final min = 0, start = 1.0e5) "Spring constant";
  parameter Modelica.SIunits.Angle phi_rel0 = 0 "Unstretched spring angle";
  parameter Modelica.SIunits.Torque Tpre "Preloaded torque";
equation
  phi_rel = if abs(tau) < Tpre then 0 else (tau - sign(tau) * Tpre) / c;
end RotationalPreloadedSpring;

I've constructed the following basic test setup and obtained the following result,

Basic test setup Results of basic setup In this basic setup, the model works properly. The spring acts as a rigid shaft and doesn't rotate until the applied torque exceeds the preloaded torque on the spring, then it rotates by an amount of (Tin - Tpre) / c.

However, when I connect inertia to the ends of this spring model, I get absurd results from the setup;

Test setup with inertia Test results with inertia

The spring switches between its two states violently. The simulation gets slowed and doesn't give anything useful.

I've couldn't managed to make this model work for non-simple cases. I would be really glad if anyone can point out the mistakes I've been doing.

POSTED BY: Kursad Kilinc
5 Replies

Thank you for your suggestions and your models. I've modified the elastoGap model and created a rotary version of it (can be found in the attachments). Like you said, it was pretty easy and straightforward. I got the same results as yours when I simulated the rotary version of your test setup with the rotary elastoGap model.

I've created the double-sided version of the preloaded spring and transformed it into a block. Unstreched spring angles of elastoGapRotary and spring models are written as functions of preload torque and spring constant. This way, desired preload and spring constant values can be inputted in the model parameters section directly.

double-sided preloaded rotary spring

Test setup:

Test setup

Results with positive input torque:

Test results positive input

Results with negative input torque:

Test results with negative input

Attachments:
POSTED BY: Kursad Kilinc

Nice Job! It seems to work exactly as you need and the model is simple (which is always best)!

POSTED BY: Neil Singer

There seems to be some bug in the way that SystemModeler handles pre() in this case. I sent a simple example to the developers to see what they think. I will post more information when I hear back from them.

As an alternative, I recommend you look at the "elastoGap" component and model your shaft in a similar fashion. I recommend a very large spring-damper to model the stop in your shaft combined with a softer spring (the preload) and some inertia. This would be duplicated in both directions. The stop must not be instantaneous or the simulation will likely be too stiff (this is why the large spring/damper is important).

I have attached a model that demonstrates this on a preloaded linear shaft (or plunger). I have an animated version and a non animated version. Both give the same output for the plunger.s (animated) and the mass.s (non animated). The animation helps visualize what is going on. The plunger is preloaded at 1m against its stop by a linear spring. When the external force (the green arrow in the animation) exceeds the preload, the plunger extends. As soon as the force is removed, the plunger returns to its preloaded state.

This approach would likely be more globally stable than the original approach using pre() because Modelica does not do well when there are sudden changes (like hitting a stop or limit). It is best to model them with a some compliance (like elastoGap) to avoid integration problems.

I suggest you take my model and use elastogap as a template to create a rotary version of elastogap. The code in that component is not very complicated. If you create a rotary version of elastogap, you should post it here -- it would be useful for others.

Alternatively, you can use the multibody library to build your preloaded rotary shaft from components (including elastogap) by creating a translational stop at a fixed radius and a rotary spring, an inertia, etc. (less code to write but it could be time consuming)

Regards

Model graphic:

Animated Model

Here is the same model without animation:

non-animated model

Plots of Results from both models:

Plots of results from either model

Attachments:
POSTED BY: Neil Singer

Hello again,

Thank you for your reply. I've modified the equation like you suggested,

model RotationalPreloadedSpring2
  extends Modelica.Mechanics.Rotational.Interfaces.PartialCompliantWithRelativeStates;
  parameter Modelica.SIunits.RotationalSpringConstant c(final min = 0, start = 1.0e5) "Spring constant";
  parameter Modelica.SIunits.Angle phi_rel0 = 0 "Unstretched spring angle";
  parameter Modelica.SIunits.Torque Tpre "Preloaded torque";
equation
  phi_rel = if abs(pre(tau)) < Tpre then 0 else (tau - sign(tau) * Tpre) / c;
end RotationalPreloadedSpring2;

The simulation is now running without a problem. However, the results doesn't seem to be correct,

Modified spring setup

Modified spring results

Also, if I remove the inertia block on the input side of the spring, Simulation Center window gets stuck while optimizing equations.

By the way, the spring should be preloaded in both directions.

Attachments:
POSTED BY: Kursad Kilinc

Kursad,

You can fix your problem by changing the line:

phi_rel = if abs(tau) < Tpre then 0 else (tau - sign(tau) * Tpre) / c; to phi_rel = if abs(pre(tau)) < Tpre then 0 else (tau - sign(tau) * Tpre) / c;

the "pre()" function will break an algebraic loop. You essentially have a "race" condition that is numerically unstable. The pre(tau) function will use the value of tau from an infinitesimal time slice earlier to determine the result of the if condition. Based on this test you will get proper behavior.

By the way, the code for this seems to be a double preloaded shaft -- preloaded in both directions. Is this what you want or should it be only one directional?

Regards

POSTED BY: Neil Singer
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