Speed Measurement Revisited

Recall our previous discussion on Speed Measurement. That discussion took place before we had introduced the idea of building reusable components. As a result, adding equations associated with the various speed measurement techniques was awkward.

In this section, we’ll revisit that topic and all of the various speed estimation techniques discussed there. As before, we assume that we have an existing model of the “plant” (the system whose speeds we wish to measure). But this time, we’ll create reusable component models for different speed estimation algorithms and add them to the plant model as graphical components.

Plant Model

We’ll start with our “plant model”. It is identical in behavior to the system we used in our previous discussion of Speed Measurement and when rendered as a schematic, looks like this:

Plant Model Schematic

The source code for the underlying Modelica model is:

within ModelicaByExample.Components.SpeedMeasurement.Examples;
model Plant "The basic plant model"
  extends ModelicaByExample.Components.Rotational.Examples.SMD;
  Components.IdealSensor idealSensor
    annotation ...
equation
  connect(idealSensor.flange, inertia1.flange_a) annotation ...
  annotation ...
end Plant;

In the remaining sections we will create models that use different approximation techniques to measure the speed of the inertia1 component in our plant model.

Before we look at the different speed approximation methods, let’s have a look at the actual speed response from our plant model.

/static/_images/PBase.svg

Note that this is exactly the same response we saw when we initially covered this topic.

Sample and Hold Sensor

Previously, we discussed the Sample and Hold approach to speed measurement. Here we will revisit this topic, but encapsulate the speed approximation in a reusable sensor model. The following model implements the “sample and hold” approximation to speed measurement:

within ModelicaByExample.Components.SpeedMeasurement.Components;
model SampleHold "A sample-hold ideal speed sensor"
  extends Interfaces.SpeedSensor;
  parameter Modelica.SIunits.Time sample_time;
initial equation
  w = der(flange.phi);
equation
  when sample(0, sample_time) then
    w = der(flange.phi);
  end when;
end SampleHold;

Behaviorally, there is no difference between this estimation technique and our previous implementation of Sample and Hold. But our approach is different this time because we have wrapped that estimation technique in a reusable component model.

We have once again saved ourselves some trouble by utilizing a partial model to represent code that will be common across our various sensor models. As we can see from the definition of the SpeedSensor model:

within ModelicaByExample.Components.SpeedMeasurement.Interfaces;
partial model SpeedSensor "The base class for all of our sensor models"
  extends Modelica.Mechanics.Rotational.Interfaces.PartialAbsoluteSensor;
  Modelica.Blocks.Interfaces.RealOutput w "Sensed speed"
    annotation ...
end SpeedSensor;

We can see from the SpeedSensor model that the output signal is named w. But we also see that SpeedSensor inherits from another model in the Modelica Standard Library, PartialAbsoluteSensor. The PartialAbsoluteSensor model is defined as:

partial model PartialAbsoluteSensor
  "Partial model to measure a single absolute flange variable"
  extends Modelica.Icons.RotationalSensor;

  Flange_a flange "Flange from which speed will be measured"
    annotation ...
equation
  0 = flange.tau;
end PartialAbsoluteSensor;

In addition to providing a nice icon, the PartialAbsoluteSensor model features a rotational connector, flange. Furthermore, the model assumes that the sensor model is completely passive (i.e., it has no impact on the system it is sensing) since it applies zero torque at the connection point.

To test this model, we simply extend from our Plant model, add an instance of the SampleHold sensor and connect it to the inertia, e.g.,

within ModelicaByExample.Components.SpeedMeasurement.Examples;
model PlantWithSampleHold "Comparison between ideal and sample-hold sensor"
  extends Plant;
  Components.SampleHold sampleHold(sample_time=0.125)
    annotation ...
equation
  connect(sampleHold.flange, inertia1.flange_b) annotation ...
  annotation ...
end PlantWithSampleHold;

When assembled, our final system looks like this:

Plant with sample hold sensor

If we simulate this system for 5 seconds, we can compare the actual speed of the inertia with the signal returned from our sensor:

/static/_images/PwSH.svg

These results are identical to the results from our previous discussion of the Sample and Hold approach.

Interval Measurement

Now let us turn our attention to the Interval Measurement technique. Again, we will create a reusable component model by extending from our Sensor model. This time, the implementation will use the time between teeth to estimate speed:

within ModelicaByExample.Components.SpeedMeasurement.Components;
model IntervalMeasure
  "Estimate speed by measuring interval between encoder teeth"
  extends Interfaces.SpeedSensor;
  parameter Integer teeth;
  Real next_phi, prev_phi;
  Real last_time;
protected
  parameter Modelica.SIunits.Angle tooth_angle=2*Modelica.Constants.pi/teeth;
initial equation
  next_phi = flange.phi+tooth_angle;
  prev_phi = flange.phi-tooth_angle;
  last_time = time;
equation
  when {flange.phi>=pre(next_phi),flange.phi<=pre(prev_phi)} then
    w = tooth_angle/(time-pre(last_time));
    next_phi = flange.phi+tooth_angle;
    prev_phi = flange.phi-tooth_angle;
    last_time = time;
  end when;
end IntervalMeasure;

Adding this sensor to our plant model is as simple as creating the following Modelica model:

within ModelicaByExample.Components.SpeedMeasurement.Examples;
model PlantWithIntervalMeasure
  "Comparison between ideal and an interval measuring sensor"
  extends Plant;
  Components.IntervalMeasure intervalMeasure(teeth=200)
    annotation ...
equation
  connect(intervalMeasure.flange, inertia1.flange_b) annotation ...
  annotation ...
end PlantWithIntervalMeasure;

When assembled, our system model looks like this:

Plant with interval measure sensor

Simulating this system, we get the following results for estimated speed:

/static/_images/PwIM.svg

As we saw in our previous discussion of the Interval Measurement technique, the quality of the estimated signal is severely reduced if we reduce the number of teeth. The previous plot used a sensor with 200 teeth per rotation. If we plot the shaft angle with respect to the bracketing teeth angles, we see that the shaft cannot move very far without triggering a measurement:

/static/_images/PwIM_gaps.svg

On the other hand, if we reduce the number of teeth per rotation down to 20, we get the following results:

/static/_images/PwIMf.svg

Plotting the teeth angles that bracket the current shaft angle, we see that crossings are far less frequent, and, as a result the accuracy of the measurement is greatly reduced:

/static/_images/PwIMf_gaps.svg

Again, we can validate our component-oriented sensor implementations by noting that these results are identical to the results presented during our previous discussion of the Interval Measurement technique.

Pulse Counter

Finally, we have the Pulse Counting approach. Again, the estimation technique can be wrapped in a reusable component that extends from the base Sensor model:

within ModelicaByExample.Components.SpeedMeasurement.Components;
model PulseCounter "Compute speed using pulse counting"
  extends Interfaces.SpeedSensor;
  parameter Modelica.SIunits.Time sample_time;
  parameter Integer teeth;
  Modelica.SIunits.Angle next_phi, prev_phi;
  Integer count;
protected
  parameter Modelica.SIunits.Angle tooth_angle=2*Modelica.Constants.pi/teeth;
initial equation
  next_phi = flange.phi+tooth_angle;
  prev_phi = flange.phi-tooth_angle;
  count = 0;
algorithm
  when {flange.phi>=pre(next_phi), flange.phi<=pre(prev_phi)} then
    next_phi := flange.phi + tooth_angle;
    prev_phi := flange.phi - tooth_angle;
    count := pre(count) + 1;
  end when;
  when sample(0,sample_time) then
    w := pre(count)*tooth_angle/sample_time;
    count := 0 "Another equation for count?";
  end when;
end PulseCounter;

and then added to our overall Plant model:

within ModelicaByExample.Components.SpeedMeasurement.Examples;
model PlantWithPulseCounter
  "Comparison between ideal and pulse counting sensor"
  extends Plant;
  Components.PulseCounter pulseCounter(sample_time=0.125, teeth=200)
    annotation ...
equation
  connect(pulseCounter.flange, inertia1.flange_b) annotation ...
  annotation ...
end PlantWithPulseCounter;

The resulting system, when rendered, looks like this:

Plant with pulse counter sensor

Simulating the system, we see that the results are the same as in our previous discussion of Pulse Counting:

/static/_images/PwPC.svg

Conclusion

The discussion of Speed Measurement earlier in the book went into great detail about the various measurement techniques that can be used to estimate the speed of a rotating shaft. The purpose of this section was not to revisit that discussion but rather to show how the estimation techniques presented earlier can benefit greatly from the component-oriented features in Modelica. As we have seen, all of these techniques can be nicely encapsulated in component models. The result is that utilizing these different estimation techniques is now as easy as dragging and dropping one of these sensor models into a system and attaching it to the rotating element whose speed you wish to measure.