# Basic Rotational Components¶

In this section, we’ll show how to create basic components for modeling one-dimensional rotational systems. We’ll build on our discussion of rotational connectors and show how they can be used to define the interfaces for basic rotational components. Finally, we’ll show how those rotational components can then be assembled into a system model that replicates the behavior of the equation-based version of the same system presented in the first chapter.

## Component Models¶

In the first chapter, we considered A Mechanical Example modeled
strictly in terms of equations (*i.e.,* without component models). In
this section, we will start by recreating that system model using
components. To do this, we first have to define models for the
fundamental components we require. These will consist of
models for an inertia, a spring, a damper and a mechanical ground.

As in the previous section, we will first define the component models using verbose formulations and then we will revisit these definitions and attempt to factor out common code to avoid repetition across component models.

### Coordinate Systems¶

The method for creating these models will be very similar to how we previously created component models in the heat transfer and electrical domains. But before we start building component models, we should first discuss one of the complexities associated with mechanical systems, coordinate systems.

In the mechanical domain, the conserved quantity we will be tracking
is momentum. What makes momentum different from the conserved
quantities we’ve already covered, heat and charge, is that it is
directional. Since we are only concerning ourselves with the one
dimensional case here, the consequence of this directionality is that
momentum is a signed quantity (*i.e.,* it can be positive or
negative).

Consider a rotating mass with a moment of inertia, \(J\). If the angular position of the inertia is represented by \(\varphi\), then the angular velocity of the inertia, \(\omega\), is defined as:

Obviously, a positive value of \(\omega\) will result in an increase in \(\varphi\) over time. Furthermore, the angular acceleration of the inertia, \(\alpha\), is defined as:

As with the angular velocity, we can see that a positive value for \(\alpha\) will result in an increase in the angular velocity. Finally, the angular momentum of this rotating inertia is defined as \(J \omega\) and we know from Euler’s laws of motion that (assuming J is a constant):

From this relationship, it is clear that a positive value for the torque, \(\tau\), will increase the amount of momentum stored in the mass.

The point of presenting all these relationships is to underscore the
sign conventions associated with \(\varphi\), \(\omega\),
\(\alpha\) and \(\tau\). They are all tied to the fundamental
definition of what a positive angular position is. **Whatever
direction causes** \(\varphi\) **to increase is the same direction
that corresponds to a positive velocity, a positive acceleration and a
positive torque**.

### Rotational Inertia¶

With this discussion about sign conventions and coordinate systems out of the way, we can start creating our component models. We’ll start with the inertia model:

```
within ModelicaByExample.Components.Rotational.VerboseApproach;
model Inertia "Rotational inertia without inheritance"
parameter Modelica.SIunits.Inertia J;
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
Modelica.SIunits.Angle phi_rel;
Modelica.SIunits.Torque tau;
Modelica.SIunits.AngularVelocity w;
equation
// Variables
phi_rel = flange_a.phi-flange_b.phi;
tau = flange_a.tau;
w = der(flange_a.phi);
// Conserviation of angular momentum (includes storage)
J*der(w) = flange_a.tau + flange_b.tau;
// Kinematic constraint (inertia is rigid)
phi_rel = 0;
annotation ( Icon(graphics={
extent={{-100,90},{100,50}},
```

The `Inertia`

model includes two “flanges”, one on either end. The
significance of these flanges is made clearer from the icon of the
`Inertia`

model:

In other words, the `Inertia`

model includes a flange on either end.
You can think of this model as a shaft with connectors on either end.

Now, the fundamental equation we wish to capture in the `Inertia`

model
is:

```
J*der(w) = flange_a.tau + flange_b.tau;
```

This is basically expressing the fact that the increase in momentum
stored within the inertia is equal to the sum of the torques applied
to the inertia. Recall, from our previous discussions on
Acausal Connections, that the sign convention for flow
variables on connectors (`flange_a.tau`

and `flange_b.tau`

in this
case) is that a positive value represents a flow of the conserved
quantity into the component model. The fact that `flange_a`

and
`flange_b`

have the same sign convention means that the `Inertia`

model is symmetric (*i.e.,* it can be flipped over and it doesn’t
change the behavior).

However, this equation refers to the internal variables `w`

(which
represents \(\omega\)) and `tau`

so we need to include
declarations and definitions for those variables as well.

### Spring Model¶

Next, let us consider the definition of a spring model:

```
within ModelicaByExample.Components.Rotational.VerboseApproach;
model Spring "Rotational spring without inheritance"
parameter Modelica.SIunits.RotationalSpringConstant c;
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
Modelica.SIunits.Angle phi_rel;
Modelica.SIunits.Torque tau;
equation
// Variables
phi_rel = flange_a.phi-flange_b.phi;
tau = flange_a.tau;
// No storage of angular momentum
flange_a.tau + flange_b.tau = 0;
// Hooke's law
tau = c*phi_rel;
end Spring;
```

The icon for our spring model is rendered as:

Like the `Inertia`

model, the `Spring`

model has two connectors,
one on each end. It also defines many of the same internal
variables. Ultimately, the behavior of the spring comes down to this
equation:

```
// Hooke's law
tau = c*phi_rel;
end Spring;
```

In fact, apart from this equation and the parameter `c`

, much of the
content in the `Spring`

model is the same as the content in the
`Inertia`

model.

### Damper Model¶

The `Damper`

model is also very similar to the `Spring`

model.
Again, the main differences are the parameter (`d`

in this case) and
one equation:

```
within ModelicaByExample.Components.Rotational.VerboseApproach;
model Damper "Rotational damper without inheritance"
parameter Modelica.SIunits.RotationalDampingConstant d;
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
Modelica.SIunits.Angle phi_rel;
Modelica.SIunits.Torque tau;
equation
// Variables
phi_rel = flange_a.phi-flange_b.phi;
tau = flange_a.tau;
// No storage of angular momentum
flange_a.tau + flange_b.tau = 0;
// Damping relationship
tau = d*der(phi_rel);
end Damper;
```

The icon for the `Damper`

model is rendered as:

## DRY Component Models¶

We already have models for an inertia, a spring and a damper. The only model we are missing in order to complete our dual spring mass damper system is a model of mechanical ground. But before we complete that model, let’s take a moment to revisit the models we’ve already created with the goal of factoring out the large amount of code shared between these models. As in the previous section, let’s take the time to apply the DRY (Don’t Repeat Yourself) principle.

### Common Code¶

It is worth noting that because the Modelica Standard Library has an
extensive collection of rotational components, it was forced to deal
with this issue of redundant code almost from the start. However, we
will not be using the `partial`

models from the Modelica Standard
Library here simply because they are designed to deal with many other
cases that are not relevant in this context. As a result, it’s
complexity (although necessary) makes it unsuitable pedagogically.

But one thing we will preserve from the Modelica Standard Library is
the need for multiple `partial`

models. This need arises from the
fact that, unlike in our previous discussion of
Electrical Components, our rotational component models share
different amounts of code with each other.

What is common to all of our models is the existence of two flange
connectors, `flange_a`

and `flange_b`

. However, while the
`Inertia`

model has the capacity to store angular momentum, the
`Spring`

and `Damper`

models do not. As a result, the
conservation equations are different among these components.

Let’s start with the elements that are common to all three models.
These are represented by the following `TwoFlange`

model:

```
within ModelicaByExample.Components.Rotational.Interfaces;
partial model TwoFlange
"Definition of a partial rotational component with two flanges"
Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
Modelica.SIunits.Angle phi_rel;
equation
phi_rel = flange_a.phi-flange_b.phi;
end TwoFlange;
```

In addition to defining the two flanges, `flange_a`

and
`flange_b`

, this model also defines the relative angle between these
flanges, *i.e.,* `phi_rel`

. Of course, this model is also marked as
`partial`

since it is missing any description of the component’s
behavior.

We could have all three models inherit from this model. But then we
would still have some redundant equations between our `Spring`

and
`Damper`

model. So we will instead create a slightly more
specialized version of the `TwoFlange`

model to represent compliant
models that do not store momentum:

```
within ModelicaByExample.Components.Rotational.Interfaces;
partial model Compliant "A compliant rotational component"
extends ModelicaByExample.Components.Rotational.Interfaces.TwoFlange;
protected
Modelica.SIunits.Torque tau;
equation
tau = flange_a.tau;
flange_a.tau + flange_b.tau = 0
"Conservation of angular momentum (no storage)";
end Compliant;
```

The `Compliant`

model adds on additional internal variable (to
represent the torque that passes through the component from
`flange_a`

to `flange_b`

) and an equation indicating that no
angular momentum is stored by the component.

With these base classes defined, let us quickly revisit the various component model definitions to see how much more succinct they can be made by using inheritance.

### Rotational Inertia¶

Leveraging the `TwoFlanges`

model, our `Inertia`

model can be
simplified to:

```
within ModelicaByExample.Components.Rotational.Components;
model Inertia "A rotational inertia model"
parameter Modelica.SIunits.Inertia J;
extends ModelicaByExample.Components.Rotational.Interfaces.TwoFlange;
Modelica.SIunits.AngularVelocity w "Angular Velocity"
annotation(Dialog(group="Initialization", showStartAttribute=true));
Modelica.SIunits.Angle phi "Angle"
annotation(Dialog(group="Initialization", showStartAttribute=true));
equation
phi = flange_a.phi;
w = der(flange_a.phi) "velocity of inertia";
phi_rel = 0 "inertia is rigid";
J*der(w) = flange_a.tau + flange_b.tau
"Conservation of angular momentum with storage";
end Inertia;
```

### Spring Model¶

In the same way, inheriting from the `Compliant`

model our
`Spring`

model can be much more compactly represented as:

```
within ModelicaByExample.Components.Rotational.Components;
model Spring "A rotational spring component"
parameter Modelica.SIunits.RotationalSpringConstant c;
extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
tau = c*phi_rel "Hooke's Law";
end Spring;
```

### Damper Model¶

Likewise, the `Damper`

model is similarly simplified:

```
within ModelicaByExample.Components.Rotational.Components;
model Damper "A rotational damper"
parameter Modelica.SIunits.RotationalDampingConstant d;
extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
tau = d*der(phi_rel) "Damping relationship";
end Damper;
```

### Mechanical Ground¶

Finally, we can complete the one model remaining in order to complete our dual spring mass damper system. The mechanical ground model is defined as follows:

```
within ModelicaByExample.Components.Rotational.Components;
model Damper "A rotational damper"
parameter Modelica.SIunits.RotationalDampingConstant d;
extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
tau = d*der(phi_rel) "Damping relationship";
annotation (Icon(graphics={
```

### Dual Spring Mass Damper System¶

Finally, we have all the parts we need in order to reconstruct the example we saw in the first chapter. Using the various components already defined in this section, the Modelica code for our component based system model looks like this:

```
within ModelicaByExample.Components.Rotational.Examples;
model SMD
Components.Ground ground annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=90,
origin={76,0})));
Components.Damper damper2(d=1)
annotation (Placement(transformation(extent={{30,10},{50,30}})));
Components.Spring spring2(c=5)
annotation (Placement(transformation(extent={{28,-30},{48,-10}})));
Components.Inertia inertia2(
J=1,
phi(fixed=true, start=1),
w(fixed=true, start=0))
annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
Components.Damper damper1(d=0.2)
annotation (Placement(transformation(extent={{-50,10},{-30,30}})));
Components.Spring spring1(c=11)
annotation (Placement(transformation(extent={{-50,-30},{-30,-10}})));
Components.Inertia inertia1(
J=0.4,
phi(fixed=true, start=0),
w(fixed=true, start=0))
annotation (Placement(transformation(extent={{-90,-10},{-70,10}})));
equation
connect(ground.flange_a, damper2.flange_b) annotation (Line(
points={{70,0},{66,0},{66,0},{60,0},{60,20},{50,20}},
color={0,0,0},
smooth=Smooth.None));
connect(ground.flange_a, spring2.flange_b) annotation (Line(
points={{70,0},{60,0},{60,-20},{48,-20}},
color={0,0,0},
smooth=Smooth.None));
connect(damper2.flange_a, inertia2.flange_b) annotation (Line(
points={{30,20},{20,20},{20,0},{10,0}},
color={0,0,0},
smooth=Smooth.None));
connect(spring2.flange_a, inertia2.flange_b) annotation (Line(
points={{28,-20},{20,-20},{20,0},{10,0}},
color={0,0,0},
smooth=Smooth.None));
connect(inertia2.flange_a, damper1.flange_b) annotation (Line(
points={{-10,0},{-20,0},{-20,20},{-30,20}},
color={0,0,0},
smooth=Smooth.None));
connect(inertia2.flange_a, spring1.flange_b) annotation (Line(
points={{-10,0},{-20,0},{-20,-20},{-30,-20}},
color={0,0,0},
smooth=Smooth.None));
connect(damper1.flange_a, inertia1.flange_b) annotation (Line(
points={{-50,20},{-60,20},{-60,0},{-70,0}},
color={0,0,0},
smooth=Smooth.None));
connect(spring1.flange_a, inertia1.flange_b) annotation (Line(
points={{-50,-20},{-60,-20},{-60,0},{-70,0}},
color={0,0,0},
smooth=Smooth.None));
end SMD;
```

The diagram for this model, when rendered, looks like this:

This completes our discussion of basic rotational components. But there is quite a bit more to say about rotational components in the next section on Advanced Rotational Components.