within Modelica;
package Blocks "Library of basic input/output control blocks (continuous, discrete, logical, table blocks)"

  extends Modelica.Icons.Package;
  import Modelica.Units.SI;

package Examples
  "Library of examples to demonstrate the usage of package Blocks"

  extends Modelica.Icons.ExamplesPackage;

  model PID_Controller
    "Demonstrates the usage of a Continuous.LimPID controller"
    extends Modelica.Icons.Example;
    parameter SI.Angle driveAngle=1.570796326794897
      "Reference distance to move";
    Modelica.Blocks.Continuous.LimPID PI(
      k=100,
      Ti=0.1,
      yMax=12,
      Ni=0.1,
      initType=Modelica.Blocks.Types.Init.SteadyState,
      controllerType=Modelica.Blocks.Types.SimpleController.PI,
      limiter(u(start = 0)),
      Td=0.1)
    Modelica.Mechanics.Rotational.Components.Inertia inertia1(
      phi(fixed=true, start=0),
      J=1,
      a(fixed=true, start=0))

    Modelica.Mechanics.Rotational.Sources.Torque torque
    Modelica.Mechanics.Rotational.Components.SpringDamper spring(
      c=1e4,
      d=100,
      stateSelect=StateSelect.prefer,
      w_rel(fixed=true))
    Modelica.Mechanics.Rotational.Components.Inertia inertia2(J=2)
    Modelica.Blocks.Sources.KinematicPTP kinematicPTP(
      startTime=0.5,
      deltaq={driveAngle},
      qd_max={1},
      qdd_max={1})
    Modelica.Blocks.Continuous.Integrator integrator(initType=Modelica.Blocks.Types.Init.InitialState)
    Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor
    Modelica.Mechanics.Rotational.Sources.ConstantTorque loadTorque(
        tau_constant=10, useSupport=false)
  initial equation
    der(spring.w_rel) = 0;

  equation
    connect(spring.flange_b, inertia2.flange_a)
    connect(inertia1.flange_b, spring.flange_a)
    connect(torque.flange, inertia1.flange_a)
    connect(kinematicPTP.y[1], integrator.u)
    connect(speedSensor.flange, inertia1.flange_b)
    connect(loadTorque.flange, inertia2.flange_b)
    connect(PI.y, torque.tau)
    connect(speedSensor.w, PI.u_m)
    connect(integrator.y, PI.u_s)
  end PID_Controller;

  model Filter "Demonstrates the Continuous.Filter block with various options"
    extends Modelica.Icons.Example;
    parameter Integer order=3 "Number of order of filter";
    parameter SI.Frequency f_cut=2 "Cut-off frequency";
    parameter Modelica.Blocks.Types.FilterType filterType=Modelica.Blocks.Types.FilterType.LowPass
      "Type of filter (LowPass/HighPass)";
    parameter Modelica.Blocks.Types.Init init=Modelica.Blocks.Types.Init.SteadyState
      "Type of initialization (no init/steady state/initial state/initial output)";
    parameter Boolean normalized=true "= true, if amplitude at f_cut = -3db, otherwise unmodified filter";

    Modelica.Blocks.Sources.Step step(startTime=0.1, offset=0.1)
    Modelica.Blocks.Continuous.Filter CriticalDamping(
      analogFilter=Modelica.Blocks.Types.AnalogFilter.CriticalDamping,
      normalized=normalized,
      init=init,
      filterType=filterType,
      order=order,
      f_cut=f_cut,
      f_min=0.8*f_cut)
    Modelica.Blocks.Continuous.Filter Bessel(
      normalized=normalized,
      analogFilter=Modelica.Blocks.Types.AnalogFilter.Bessel,
      init=init,
      filterType=filterType,
      order=order,
      f_cut=f_cut,
      f_min=0.8*f_cut)
    Modelica.Blocks.Continuous.Filter Butterworth(
      normalized=normalized,
      analogFilter=Modelica.Blocks.Types.AnalogFilter.Butterworth,
      init=init,
      filterType=filterType,
      order=order,
      f_cut=f_cut,
      f_min=0.8*f_cut)
    Modelica.Blocks.Continuous.Filter ChebyshevI(
      normalized=normalized,
      analogFilter=Modelica.Blocks.Types.AnalogFilter.ChebyshevI,
      init=init,
      filterType=filterType,
      order=order,
      f_cut=f_cut,
      f_min=0.8*f_cut)

  equation
    connect(step.y, CriticalDamping.u)
    connect(step.y, Bessel.u)
    connect(Butterworth.u, step.y)
    connect(ChebyshevI.u, step.y)
  end Filter;

  model FilterWithDifferentiation
    "Demonstrates the use of low pass filters to determine derivatives of filters"
    extends Modelica.Icons.Example;
    parameter SI.Frequency f_cut=2 "Cut-off frequency";

    Modelica.Blocks.Sources.Step step(startTime=0.1, offset=0.1)
    Modelica.Blocks.Continuous.Filter Bessel(
      f_cut=f_cut,
      filterType=Modelica.Blocks.Types.FilterType.LowPass,
      order=3,
      analogFilter=Modelica.Blocks.Types.AnalogFilter.Bessel)

    Continuous.Der der1
    Continuous.Der der2
    Continuous.Der der3
  equation
    connect(step.y, Bessel.u)
    connect(Bessel.y, der1.u)
    connect(der1.y, der2.u)
    connect(der2.y, der3.u)
  end FilterWithDifferentiation;

  model FilterWithRiseTime
    "Demonstrates to use the rise time instead of the cut-off frequency to define a filter"
    import Modelica.Constants.pi;
    extends Modelica.Icons.Example;
    parameter Integer order=2 "Filter order";
    parameter SI.Time riseTime=2 "Time to reach the step input";

    Continuous.Filter filter_fac5(f_cut=5/(2*pi*riseTime), order=order)
    Sources.Step step(startTime=1)
    Continuous.Filter filter_fac4(f_cut=4/(2*pi*riseTime), order=order)
    Continuous.Filter filter_fac3(f_cut=3/(2*pi*riseTime), order=order)
  equation
    connect(step.y, filter_fac5.u)
    connect(step.y, filter_fac4.u)
    connect(step.y, filter_fac3.u)

where \"fac\" is typically 3, 4, or 5. The following image shows
the results of a simulation of this example model
(riseTime = 2 s, fac=3, 4, and 5):

Since the step starts at 1 s, and the rise time is 2 s, the filter output y
shall reach the value of 1 after 1+2=3 s. Depending on the factor \"fac\" this is
reached with different precisions. This is summarized in the following table:

   Filter order
   Factor fac
   Percentage of step value reached after rise time

   1
   3
   95.1 %

   1
   4
   98.2 %

   1
   5
   99.3 %

   2
   3
   94.7 %

   2
   4
   98.6 %

   2
   5
   99.6 %

"));
  end FilterWithRiseTime;

  model SlewRateLimiter
    "Demonstrate usage of Nonlinear.SlewRateLimiter"
    extends Modelica.Icons.Example;
    parameter SI.Velocity vMax=2 "Max. velocity";
    parameter SI.Acceleration aMax=20 "Max. acceleration";
    SI.Position s=positionStep.y "Reference position";
    SI.Position sSmoothed=positionSmoothed.y "Smoothed position";
    SI.Velocity vLimited=limit_a.y "Limited velocity";
    SI.Acceleration aLimited=a.y "Limited acceleration";
    Modelica.Blocks.Sources.Step positionStep(startTime=0.1)
    Modelica.Blocks.Nonlinear.SlewRateLimiter limit_v(
      initType=Modelica.Blocks.Types.Init.InitialOutput,
      Rising=vMax,
      y_start=positionStep.offset,
      Td=0.0001)
    Modelica.Blocks.Continuous.Der v
    Modelica.Blocks.Nonlinear.SlewRateLimiter limit_a(
      initType=Modelica.Blocks.Types.Init.InitialOutput,
      y_start=0,
      Rising=20,
      Td=0.0001)
    Modelica.Blocks.Continuous.Integrator positionSmoothed(
      k=1,
      initType=Modelica.Blocks.Types.Init.InitialOutput,
      y_start=positionStep.offset)
    Modelica.Blocks.Continuous.Der a
  equation
    connect(positionStep.y, limit_v.u)
    connect(limit_v.y, v.u)
    connect(v.y, limit_a.u)
    connect(limit_a.y, positionSmoothed.u)
    connect(limit_a.y, a.u)
  end SlewRateLimiter;

  model InverseModel "Demonstrates the construction of an inverse model"
    extends Modelica.Icons.Example;

    Continuous.FirstOrder firstOrder1(
      k=1,
      T=0.3,
      initType=Modelica.Blocks.Types.Init.SteadyState)
    Sources.Sine sine(
      f=2,
      offset=1,
      startTime=0.2)
    Math.InverseBlockConstraints inverseBlockConstraints
    Continuous.FirstOrder firstOrder2(
      k=1,
      T=0.3,
      initType=Modelica.Blocks.Types.Init.SteadyState)
    Math.Feedback feedback
    Continuous.CriticalDamping criticalDamping(n=1, f=50*sine.f)
  equation
    connect(firstOrder1.y, inverseBlockConstraints.u2)
    connect(inverseBlockConstraints.y2, firstOrder1.u)
    connect(firstOrder2.y, feedback.u1)
    connect(sine.y, criticalDamping.u)
    connect(criticalDamping.y, inverseBlockConstraints.u1)
    connect(sine.y, feedback.u2)
    connect(inverseBlockConstraints.y1, firstOrder2.u)
  end InverseModel;

  model ShowLogicalSources
    "Demonstrates the usage of logical sources together with their diagram animation"
    extends Modelica.Icons.Example;
    Sources.BooleanTable table(table={2,4,6,8})
    Sources.BooleanConstant const
    Sources.BooleanStep step(startTime=4)
    Sources.BooleanPulse pulse(period=1.5)

    Sources.SampleTrigger sample(period=0.5)
    Sources.BooleanExpression booleanExpression(y=pulse.y and step.y)
  end ShowLogicalSources;

  model LogicalNetwork1 "Demonstrates the usage of logical blocks"

    extends Modelica.Icons.Example;
    Sources.BooleanTable table2(table={1,3,5,7})
    Sources.BooleanTable table1(table={2,4,6,8})
    Logical.Not Not1

    Logical.And And1
    Logical.Or Or1
    Logical.Pre Pre1
  equation

    connect(table2.y, Not1.u)
    connect(And1.y, Or1.u2)
    connect(table1.y, Or1.u1)
    connect(Not1.y, And1.u1)
    connect(Pre1.y, And1.u2)
    connect(Or1.y, Pre1.u)
  end LogicalNetwork1;

model RealNetwork1 "Demonstrates the usage of blocks from Modelica.Blocks.Math"

  extends Modelica.Icons.Example;

  Modelica.Blocks.Math.MultiSum add(nu=2)
  Sources.Sine sine(amplitude=3, f=0.1)
  Sources.Step integerStep(height=3, startTime=2)
  Sources.Constant integerConstant(k=1)
  Modelica.Blocks.Interaction.Show.RealValue showValue
  Math.MultiProduct product(nu=2)
  Modelica.Blocks.Interaction.Show.RealValue showValue1(significantDigits=2)
  Sources.BooleanPulse booleanPulse1(period=1)
  Math.MultiSwitch multiSwitch(
    nu=2,
    expr={4,6},
    y_default=2)
  Sources.BooleanPulse booleanPulse2(period=2, width=80)
  Modelica.Blocks.Interaction.Show.RealValue showValue3(
    use_numberPort=false,
    number=multiSwitch.y,
    significantDigits=1)
  Math.LinearDependency linearDependency1(
    y0=1,
    k1=2,
    k2=3)
  Math.MinMax minMax(nu=2)
equation
  connect(booleanPulse1.y, multiSwitch.u[1])
  connect(booleanPulse2.y, multiSwitch.u[2])
  connect(sine.y, add.u[1])
  connect(integerStep.y, add.u[2])
  connect(add.y, showValue.numberPort)
  connect(integerStep.y, product.u[1])
  connect(integerConstant.y, product.u[2])
  connect(product.y, showValue1.numberPort)
  connect(add.y, linearDependency1.u1)
  connect(product.y, linearDependency1.u2)
  connect(add.y, minMax.u[1])
  connect(product.y, minMax.u[2])
end RealNetwork1;

  model IntegerNetwork1
    "Demonstrates the usage of blocks from Modelica.Blocks.MathInteger"

    extends Modelica.Icons.Example;

    MathInteger.Sum sum(nu=3)
    Sources.Sine sine(amplitude=3, f=0.1)
    Math.RealToInteger realToInteger
    Sources.IntegerStep integerStep(height=3, startTime=2)
    Sources.IntegerConstant integerConstant(k=1)
    Modelica.Blocks.Interaction.Show.IntegerValue showValue
    MathInteger.Product product(nu=2)
    Modelica.Blocks.Interaction.Show.IntegerValue showValue1
    MathInteger.TriggeredAdd triggeredAdd(use_reset=false, use_set=false)
    Sources.BooleanPulse booleanPulse1(period=1)
    Modelica.Blocks.Interaction.Show.IntegerValue showValue2
    MathInteger.MultiSwitch multiSwitch1(
      nu=2,
      expr={4,6},
      y_default=2,
      use_pre_as_default=false)
    Sources.BooleanPulse booleanPulse2(period=2, width=80)
    Modelica.Blocks.Interaction.Show.IntegerValue showValue3(use_numberPort=
          false, number=multiSwitch1.y)
  equation
    connect(sine.y, realToInteger.u)
    connect(realToInteger.y, sum.u[1])
    connect(integerStep.y, sum.u[2])
    connect(integerConstant.y, sum.u[3])
    connect(sum.y, showValue.numberPort)
    connect(sum.y, product.u[1])
    connect(integerStep.y, product.u[2])
    connect(product.y, showValue1.numberPort)
    connect(integerConstant.y, triggeredAdd.u)
    connect(booleanPulse1.y, triggeredAdd.trigger)
    connect(triggeredAdd.y, showValue2.numberPort)
    connect(booleanPulse1.y, multiSwitch1.u[1])
    connect(booleanPulse2.y, multiSwitch1.u[2])
  end IntegerNetwork1;

  model BooleanNetwork1
    "Demonstrates the usage of blocks from Modelica.Blocks.MathBoolean"

    extends Modelica.Icons.Example;

    Modelica.Blocks.Interaction.Show.BooleanValue showValue
    MathBoolean.And and1(nu=3)
    Sources.BooleanPulse booleanPulse1(width=20, period=1)
    Sources.BooleanPulse booleanPulse2(period=1, width=80)
    Sources.BooleanStep booleanStep(startTime=1.5)
    MathBoolean.Or or1(nu=2)
    MathBoolean.Xor xor1(nu=2)
    Modelica.Blocks.Interaction.Show.BooleanValue showValue2
    Modelica.Blocks.Interaction.Show.BooleanValue showValue3
    MathBoolean.Nand nand1(nu=2)
    MathBoolean.Nor or2(nu=2)
    Modelica.Blocks.Interaction.Show.BooleanValue showValue4
    MathBoolean.Not nor1
    MathBoolean.OnDelay onDelay(delayTime=1)
    MathBoolean.RisingEdge rising
    MathBoolean.MultiSwitch set1(nu=2, expr={false,true})
    MathBoolean.FallingEdge falling
    Sources.BooleanTable booleanTable(table={2,4,6,6.5,7,9,11})
    MathBoolean.ChangingEdge changing
    MathInteger.TriggeredAdd triggeredAdd
    Sources.IntegerConstant integerConstant(k=2)
    Modelica.Blocks.Interaction.Show.IntegerValue showValue1
    Modelica.Blocks.Interaction.Show.BooleanValue showValue5
    Modelica.Blocks.Interaction.Show.BooleanValue showValue6
    Logical.RSFlipFlop rSFlipFlop
    Sources.SampleTrigger sampleTriggerSet(period=0.5, startTime=0)
    Sources.SampleTrigger sampleTriggerReset(period=0.5, startTime=0.3)
  equation
    connect(booleanPulse1.y, and1.u[1])
    connect(booleanStep.y, and1.u[2])
    connect(booleanPulse2.y, and1.u[3])
    connect(and1.y, or1.u[1])
    connect(booleanPulse2.y, or1.u[2])
    connect(or1.y, xor1.u[1])
    connect(booleanPulse2.y, xor1.u[2])
    connect(and1.y, showValue.activePort)
    connect(or1.y, showValue2.activePort)
    connect(xor1.y, showValue3.activePort)
    connect(xor1.y, nand1.u[1])
    connect(booleanPulse2.y, nand1.u[2])
    connect(nand1.y, or2.u[1])
    connect(booleanPulse2.y, or2.u[2])
    connect(or2.y, nor1.u)
    connect(nor1.y, showValue4.activePort)
    connect(booleanPulse2.y, rising.u)
    connect(rising.y, set1.u[1])
    connect(falling.y, set1.u[2])
    connect(booleanPulse2.y, falling.u)
    connect(booleanTable.y, onDelay.u)
    connect(booleanPulse2.y, changing.u)
    connect(integerConstant.y, triggeredAdd.u)
    connect(changing.y, triggeredAdd.trigger)
    connect(triggeredAdd.y, showValue1.numberPort)
    connect(set1.y, showValue5.activePort)
    connect(onDelay.y, showValue6.activePort)
    connect(sampleTriggerSet.y, rSFlipFlop.S)
    connect(sampleTriggerReset.y, rSFlipFlop.R)
  end BooleanNetwork1;

  model Interaction1
    "Demonstrates the usage of blocks from Modelica.Blocks.Interaction.Show"

    extends Modelica.Icons.Example;

    Interaction.Show.IntegerValue integerValue
    Sources.IntegerTable integerTable(table=[0, 0; 1, 2; 2, 4; 3, 6; 4, 4; 6, 2])
    Sources.TimeTable timeTable(table=[0, 0; 1, 2.1; 2, 4.2; 3, 6.3; 4, 4.2; 6,
          2.1; 6, 2.1])
    Interaction.Show.RealValue realValue
    Sources.BooleanTable booleanTable(table={1,2,3,4,5,6,7,8,9})
    Interaction.Show.BooleanValue booleanValue
    Sources.RadioButtonSource start(buttonTimeTable={1,3}, reset={stop.on})
    Sources.RadioButtonSource stop(buttonTimeTable={2,4}, reset={start.on})
  equation
    connect(integerTable.y, integerValue.numberPort)
    connect(timeTable.y, realValue.numberPort)
    connect(booleanTable.y, booleanValue.activePort)
  end Interaction1;

  model BusUsage "Demonstrates the usage of a signal bus"
    extends Modelica.Icons.Example;

  public
    Modelica.Blocks.Sources.IntegerStep integerStep(
      height=1,
      offset=2,
      startTime=0.5)
    Modelica.Blocks.Sources.BooleanStep booleanStep(startTime=0.5)
    Modelica.Blocks.Sources.Sine sine(f=1)

    Modelica.Blocks.Examples.BusUsage_Utilities.Part part
    Modelica.Blocks.Math.Gain gain(k=1)
  protected
    BusUsage_Utilities.Interfaces.ControlBus controlBus
  equation

    connect(sine.y, controlBus.realSignal1)
    connect(booleanStep.y, controlBus.booleanSignal)
    connect(integerStep.y, controlBus.integerSignal)
    connect(part.subControlBus, controlBus.subControlBus)
    connect(gain.u, controlBus.realSignal1)
end ControlBus;

Note, the \"annotation\" in the connector is important since the color
and thickness of a connector line are taken from the first
line element in the icon annotation of a connector class. Above, a small rectangle in the
color of the bus is defined (and therefore this rectangle is not
visible). As a result, when connecting from an instance of this
connector to another connector instance, the connecting line has
the color of the \"ControlBus\" with double width (due to \"thickness=0.5\").

An expandable connector is a connector where the content of the connector
is constructed by the variables connected to instances of this connector.
For example, if \"sine.y\" is connected to the \"controlBus\", a pop-up menu may appear:

The \"Add variable/New name\" field allows the user to define the name of the signal on
the \"controlBus\". When typing \"realSignal1\" as \"New name\", a connection of the form:

connect(sine.y, controlBus.realSignal1)

is generated and the \"controlBus\" contains the new signal \"realSignal1\". Modelica tools
may give more support in order to list potential signals for a connection. Therefore, in
BusUsage_Utilities.Interfaces
the expected implementation of the \"ControlBus\" and of the \"SubControlBus\" are given.
For example \"Internal.ControlBus\" is defined as:

expandable connector StandardControlBus
  extends BusUsage_Utilities.Interfaces.ControlBus;

  import Modelica.Units.SI;
  SI.AngularVelocity    realSignal1   \"First Real signal\";
  SI.Velocity           realSignal2   \"Second Real signal\";
  Integer               integerSignal \"Integer signal\";
  Boolean               booleanSignal \"Boolean signal\";
  StandardSubControlBus subControlBus \"Combined signal\";
end StandardControlBus;

Consequently, when connecting now from \"sine.y\" to \"controlBus\", the menu
looks differently:

Note, even if the signals from \"Internal.StandardControlBus\" are listed, these are
just potential signals. The user might still add different signal names.

"), experiment(StopTime=2));
  end BusUsage;

  model Rectifier6pulseFFT "Example of FFT block"
    extends Modelica.Electrical.Machines.Examples.Transformers.Rectifier6pulse;
    Modelica.Blocks.Math.RealFFT realFFT(
      startTime=0.04,
      f_max=2000,
      f_res=5,
      resultFileName="rectifier6pulseFFTresult.mat")
  equation
    connect(currentSensor.i[1], realFFT.u)
  end Rectifier6pulseFFT;

  model Rectifier12pulseFFT "Example of FFT block"
    extends Modelica.Electrical.Machines.Examples.Transformers.Rectifier12pulse;
    Modelica.Blocks.Math.RealFFT realFFT(
      startTime=0.04,
      f_max=2000,
      f_res=5,
      resultFileName="rectifier12pulseFFTresult.mat")
  equation
    connect(currentSensor.i[1], realFFT.u)
  end Rectifier12pulseFFT;

  model TotalHarmonicDistortion "Calculation of total harmonic distortion of voltage"
    extends Modelica.Icons.Example;
    parameter SI.Frequency f1 = 50 "Fundamental wave frequency";
    parameter SI.Voltage V1 = 100 "Fundamental wave RMS voltage";
    parameter SI.Voltage V3 = 20 "Third harmonic wave RMS voltage";
    final parameter Real THD1 = V3/V1 "Theoretically obtained THD with respect to fundamental wave";
    final parameter Real THDrms = V3/sqrt(V1^2+V3^2) "Theoretically obtained THD with respect to RMS";
    Modelica.Electrical.Analog.Basic.Ground ground
    Modelica.Electrical.Analog.Sources.SineVoltage sineVoltage3(V=sqrt(2)*V3, f=3*f1,
      startTime=0.02)
    Modelica.Electrical.Analog.Sources.SineVoltage sineVoltage1(V=sqrt(2)*V1, f=f1,
      startTime=0.02)
    Modelica.Electrical.Analog.Sensors.VoltageSensor voltageSensor
    Modelica.Blocks.Math.TotalHarmonicDistortion thd1(f=f1)
    Modelica.Blocks.Math.TotalHarmonicDistortion thdRMS(f=f1, useFirstHarmonic=false)
  equation
    connect(voltageSensor.p, sineVoltage3.p)
    connect(sineVoltage3.n, sineVoltage1.p)
    connect(sineVoltage1.n, ground.p)
    connect(ground.p, voltageSensor.n)
    connect(thd1.u, voltageSensor.v)
    connect(voltageSensor.v, thdRMS.u)
  end TotalHarmonicDistortion;

  model Modulation "Demonstrate amplitude modulation and frequency modulation"
    extends Modelica.Icons.Example;
    Modelica.Blocks.Sources.SineVariableFrequencyAndAmplitude sine(
      useConstantAmplitude=true,
      useConstantFrequency=true,
      constantFrequency=100,
      phi(fixed=true))
    Modelica.Blocks.Sources.Sine amplitude(
      amplitude=0.5,
      f=2,
      offset=1)
    Modelica.Blocks.Sources.SineVariableFrequencyAndAmplitude sinAM(
      useConstantAmplitude=false,
      useConstantFrequency=true,
      constantFrequency=100,
      phi(fixed=true))
    Sources.CosineVariableFrequencyAndAmplitude cosAM(
      useConstantAmplitude=false,
      useConstantFrequency=true,
      constantFrequency=100,
      phi(fixed=true))
    Modelica.Blocks.Sources.Sine frequency(
      amplitude=50,
      f=2,
      offset=100)
    Modelica.Blocks.Sources.SineVariableFrequencyAndAmplitude sinFM(
      useConstantAmplitude=true,
      useConstantFrequency=false,
      constantFrequency=100,
      phi(fixed=true))
    Sources.CosineVariableFrequencyAndAmplitude cosFM(
      useConstantAmplitude=true,
      useConstantFrequency=false,
      constantFrequency=100,
      phi(fixed=true))
  equation
    connect(amplitude.y, sinAM.amplitude)
    connect(frequency.y, sinFM.f)
    connect(amplitude.y, cosAM.amplitude)
    connect(frequency.y, cosFM.f)
  end Modulation;

  model SinCosEncoder "Evaluation of a sinusoidal encoder"
    extends Modelica.Icons.Example;
    import Modelica.Constants.pi;
    SI.AngularVelocity w=2*pi*ramp.y "2*pi*f";
    Sources.Ramp ramp(
      height=100,
      duration=1,
      offset=0,
      startTime=0)
    Sources.CosineVariableFrequencyAndAmplitude
                                              cosB(
      useConstantAmplitude=true,
      offset=1.5,
      phi(fixed=true))
    Sources.CosineVariableFrequencyAndAmplitude
                                              cosBminus(
      useConstantAmplitude=true,
      constantAmplitude=-1,
      offset=1.5,
      phi(fixed=true))
    Sources.SineVariableFrequencyAndAmplitude sinA(
      useConstantAmplitude=true,
      offset=1.5,
      phi(fixed=true))
    Sources.SineVariableFrequencyAndAmplitude sinAminus(
      useConstantAmplitude=true,
      constantAmplitude=-1,
      offset=1.5,
      phi(fixed=true))
    Math.Feedback feedbackCos
    Math.Feedback feedbackSin
    Electrical.Machines.SpacePhasors.Blocks.Rotator rotator
    Continuous.Integrator integrator(k=1e6)
    Continuous.Der der1
    Math.WrapAngle wrapAngle(positiveRange=false)
    Electrical.Machines.SpacePhasors.Blocks.ToPolar toPolar
  equation
    connect(ramp.y, sinA.f)
    connect(ramp.y, sinAminus.f)
    connect(ramp.y, cosBminus.f)
    connect(ramp.y, cosB.f)
    connect(cosBminus.y, feedbackCos.u2)
    connect(cosB.y, feedbackCos.u1)
    connect(sinA.y, feedbackSin.u1)
    connect(sinAminus.y, feedbackSin.u2)
    connect(feedbackCos.y, rotator.u[1])
    connect(feedbackSin.y, rotator.u[2])
    connect(rotator.y[2], integrator.u)
    connect(integrator.y, rotator.angle)
    connect(integrator.y, der1.u)
    connect(integrator.y, wrapAngle.u)
    connect(feedbackCos.y, toPolar.u[1])
    connect(feedbackSin.y, toPolar.u[2])
  end SinCosEncoder;

  model CompareSincExpSine "Compare sinc and exponential sine signal"
    extends Modelica.Icons.Example;
    Sources.Sinc sinc(f=5)
    Sources.ExpSine expSine1(f=5, damping=5)
    Sources.ExpSine expSine2(
      f=5,
      phase=Modelica.Constants.pi/2,
      damping=5)
  end CompareSincExpSine;

  model DemonstrateSignalExtrema "Test detection of signal extrema"
    extends Modelica.Icons.Example;
    Sources.Sine amplitude(
      amplitude=2,
      f=63,
      offset=3)
    Sources.Cosine frequency(
      amplitude=45,
      f=77,
      offset=55)
    Modelica.Blocks.Sources.SineVariableFrequencyAndAmplitude sine(
        useConstantFrequency=false, phi(fixed=true))
    Modelica.Blocks.Math.SignalExtrema signalExtrema1(Ts=1e-2)
    Modelica.Blocks.Math.SignalExtrema signalExtrema2(Ts=1e-4)
  equation
    connect(sine.y, signalExtrema1.u)
    connect(sine.y, signalExtrema2.u)
    connect(amplitude.y, sine.amplitude)
    connect(frequency.y, sine.f)
  end DemonstrateSignalExtrema;

  model DemonstrateContinuousSignalExtrema
    "Test the ContinuousSignalExtrema block"
    extends Modelica.Icons.Example;
    Modelica.Blocks.Sources.Sine sine(
      amplitude=1,
      f=9,
      offset=-2)
    Modelica.Blocks.Sources.SawTooth sawTooth(
      amplitude=2,
      period=1/9,
      offset=1)
    Modelica.Blocks.Sources.Sine amplitude(
      amplitude=1,
      f=1.75,
      offset=0)
    Modelica.Blocks.Math.Product product1
    Modelica.Blocks.Math.Product product2
    Modelica.Blocks.Math.ContinuousSignalExtrema signalExtrema1
    Modelica.Blocks.Math.ContinuousSignalExtrema signalExtrema2
    Sources.Sine sine1(
      amplitude=1,
      f=7,
      offset=-2)
    Sources.Pulse pulse(
      amplitude=2,
      period=1/9,
      offset=1)
    Math.Add add
    Math.Product product3
    Sources.SawTooth sawTooth1(
      amplitude=2,
      period=1/13,
      offset=-1)
    Math.ContinuousSignalExtrema signalExtrema3
  equation
    connect(amplitude.y, product1.u2)
    connect(amplitude.y, product2.u1)
    connect(sine.y, product1.u1)
    connect(sawTooth.y, product2.u2)
    connect(product1.y, signalExtrema1.u)
    connect(product2.y, signalExtrema2.u)
    connect(sine1.y, add.u1)
    connect(pulse.y, add.u2)
    connect(add.y, product3.u2)
    connect(sawTooth1.y, product3.u1)
    connect(product3.y, signalExtrema3.u)
  end DemonstrateContinuousSignalExtrema;

  model DemoSignalCharacteristic
    "Demonstrate characteristic values of a signal"
    extends Modelica.Icons.Example;
    import Modelica.Constants.pi;
    parameter Real app(final min=0)=1 "Peak-to-peak value of pulse signal";
    parameter Real dutyCycle(final min=0, final max=1)=0.5 "Duty cycle of pulse signal";
    parameter Real offset=0 "Offset of pulse signal";
    parameter Modelica.Units.SI.Frequency f=50 "Base frequency of pulse signal";
    Real y = pulse.y "Investigated pulse signal";
    //Analytical prediction of results
    parameter Real y_mean=offset + app*dutyCycle "Mean value";
    parameter Real y_rect=abs(offset + app)*dutyCycle + abs(offset)*(1 - dutyCycle) "Rectified mean";
    parameter Real y_rms=sqrt((offset + app)^2*dutyCycle + offset^2*(1 - dutyCycle)) "Root mean square";
    parameter Real y1_cos=((offset + app)*( sin(dutyCycle*2*pi) - sin(0)) + offset*( sin(2*pi) - sin(dutyCycle*2*pi)))/pi/sqrt(2) "First harmonic cosine rms component";
    parameter Real y1_sin=((offset + app)*(-cos(dutyCycle*2*pi) + cos(0)) + offset*(-cos(2*pi) + cos(dutyCycle*2*pi)))/pi/sqrt(2) "First harmonic sine rms component";
    parameter Real y1_rms=sqrt(y1_cos^2+y1_sin^2) "RMS value of first harmonic";
    parameter Real y1_arg=atan2(y1_sin,y1_cos) "Argument of first harmonic";
    Sources.Pulse pulse(
      amplitude=app,
      width=dutyCycle*100,
      period=1/f,
      offset=offset)
    Math.Mean mean(f=f, y0=y_mean)
    Math.RectifiedMean rectifiedMean(f=f, y0=y_rect)
    Math.RootMeanSquare rootMeanSquare(f=f, y0=y_rms)
    Math.Harmonic harmonic(f=f, k=1,
      y0Cos=y1_cos,
      y0Sin=y1_sin)
  equation
    connect(pulse.y, mean.u)
    connect(pulse.y, rectifiedMean.u)
    connect(pulse.y, rootMeanSquare.u)
    connect(pulse.y, harmonic.u)
  end DemoSignalCharacteristic;

  package Noise "Library of examples to demonstrate the usage of package Blocks.Noise"
    extends Modelica.Icons.ExamplesPackage;

    model UniformNoise
      "Demonstrates the most simple usage of the UniformNoise block"
      extends Modelica.Icons.Example;
      output Real uniformNoise2_y = uniformNoise2.y;

      inner Modelica.Blocks.Noise.GlobalSeed globalSeed
      Modelica.Blocks.Noise.UniformNoise uniformNoise1(
        samplePeriod=0.02,
        y_min=-1,
        y_max=3)
      Modelica.Blocks.Noise.UniformNoise uniformNoise2(
        samplePeriod=0.02, y_min=-1, y_max=3,
        useAutomaticLocalSeed=false,
        fixedLocalSeed=10)
    end UniformNoise;

    model AutomaticSeed
      "Demonstrates noise with startTime and automatic local seed for UniformNoise"
       extends Modelica.Icons.Example;
       parameter SI.Time startTime = 0.5 "Start time of noise";
       parameter Real y_off = -1.0 "Output of block before startTime";

       output Real manualSeed1_y = manualSeed1.y;
       output Real manualSeed2_y = manualSeed2.y;
       output Real manualSeed3_y = manualSeed3.y;

      inner Modelica.Blocks.Noise.GlobalSeed globalSeed(useAutomaticSeed=false, enableNoise=true)

      Modelica.Blocks.Noise.UniformNoise automaticSeed1(
        samplePeriod=0.01,
        startTime=startTime,
        y_off=y_off,
        y_min=-1, y_max=3)
      Modelica.Blocks.Noise.UniformNoise automaticSeed2(
        samplePeriod=0.01,
        startTime=startTime,
        y_off=y_off,y_min=-1, y_max=3)
      Modelica.Blocks.Noise.UniformNoise automaticSeed3(
        samplePeriod=0.01,
        startTime=startTime,
        y_off=y_off, y_min=-1, y_max=3)
      Modelica.Blocks.Noise.UniformNoise manualSeed1(
        samplePeriod=0.01,
        startTime=startTime,
        y_off=y_off,
        useAutomaticLocalSeed=false,
        fixedLocalSeed=1,y_min=-1, y_max=3,
        enableNoise=true)
      Modelica.Blocks.Noise.UniformNoise manualSeed2(
        samplePeriod=0.01,
        startTime=startTime,
        y_off=y_off,
        useAutomaticLocalSeed=false,
        fixedLocalSeed=2,y_min=-1, y_max=3)
      Modelica.Blocks.Noise.UniformNoise manualSeed3(
        samplePeriod=0.01,
        startTime=startTime,
        y_off=y_off,
        useAutomaticLocalSeed=false,y_min=-1, y_max=3,
        fixedLocalSeed=3)
    end AutomaticSeed;

    model Distributions
      "Demonstrates noise with different types of distributions"
      extends Modelica.Icons.Example;
      parameter SI.Period samplePeriod=0.02
        "Sample period of all blocks";
      parameter Real y_min = -1 "Minimum value of band for random values";
      parameter Real y_max = 3 "Maximum value of band for random values";
      inner Modelica.Blocks.Noise.GlobalSeed globalSeed(useAutomaticSeed=
            false)
      output Real uniformNoise_y =         uniformNoise.y;
      output Real truncatedNormalNoise_y = truncatedNormalNoise.y;

      Integer n=if time < 0.5 then 12 else 2;

      Modelica.Blocks.Noise.UniformNoise uniformNoise(
        useAutomaticLocalSeed=false,
        fixedLocalSeed=1,
        samplePeriod=samplePeriod,
        y_min=y_min,
        y_max=y_max)
      Modelica.Blocks.Noise.TruncatedNormalNoise truncatedNormalNoise(
        useAutomaticLocalSeed=false,
        fixedLocalSeed=1,
        samplePeriod=samplePeriod,
        y_min=y_min,
        y_max=y_max)
    end Distributions;

    model UniformNoiseProperties
      "Demonstrates the computation of properties for uniformly distributed noise"
      extends Modelica.Icons.Example;
      parameter Real y_min = 0 "Minimum value of band";
      parameter Real y_max = 6 "Maximum value of band";
      parameter Real pMean = (y_min + y_max)/2
        "Theoretical mean value of uniform distribution";
      parameter Real var =  (y_max - y_min)^2/12
        "Theoretical variance of uniform distribution";
      parameter Real std =  sqrt(var)
        "Theoretical standard deviation of uniform distribution";
      inner Modelica.Blocks.Noise.GlobalSeed globalSeed
      output Real meanError_y = meanError.y;
      output Real sigmaError_y = sigmaError.y;

      Modelica.Blocks.Noise.UniformNoise noise(
        samplePeriod=0.001,
        y_min=y_min,
        y_max=y_max,
        useAutomaticLocalSeed=false)
      Modelica.Blocks.Math.ContinuousMean mean
      Modelica.Blocks.Math.Variance variance
      Modelica.Blocks.Math.MultiProduct theoreticalVariance(nu=2)
      Modelica.Blocks.Math.Feedback meanError
      Modelica.Blocks.Sources.Constant theoreticalMean(k=pMean)
      Modelica.Blocks.Math.Feedback varianceError
      Modelica.Blocks.Sources.Constant theoreticalSigma(k=std)
      Modelica.Blocks.Math.StandardDeviation standardDeviation
      Modelica.Blocks.Math.Feedback sigmaError
    equation
      connect(noise.y, mean.u)
      connect(noise.y, variance.u)
      connect(mean.y, meanError.u1)
      connect(theoreticalMean.y, meanError.u2)
      connect(theoreticalSigma.y, theoreticalVariance.u[1])
      connect(theoreticalSigma.y, theoreticalVariance.u[2])
      connect(variance.y, varianceError.u1)
      connect(theoreticalVariance.y, varianceError.u2)
      connect(noise.y, standardDeviation.u)
      connect(standardDeviation.y, sigmaError.u1)
      connect(theoreticalSigma.y, sigmaError.u2)
    end UniformNoiseProperties;

    model NormalNoiseProperties
      "Demonstrates the computation of properties for normally distributed noise"
      extends Modelica.Icons.Example;
      parameter Real mu = 3 "Mean value for normal distribution";
      parameter Real sigma = 1 "Standard deviation for normal distribution";
      parameter Real pMean = mu "Theoretical mean value of normal distribution";
      parameter Real var =  sigma^2
        "Theoretical variance of uniform distribution";
      parameter Real std =  sigma
        "Theoretical standard deviation of normal distribution";
      inner Modelica.Blocks.Noise.GlobalSeed globalSeed
      output Real meanError_y = meanError.y;
      output Real sigmaError_y = sigmaError.y;

      Modelica.Blocks.Noise.NormalNoise noise(
        samplePeriod=0.001,
        mu=mu,
        sigma=sigma,
        useAutomaticLocalSeed=false)
      Modelica.Blocks.Math.ContinuousMean mean
      Modelica.Blocks.Math.Variance variance
      Modelica.Blocks.Math.MultiProduct theoreticalVariance(nu=2)
      Modelica.Blocks.Math.Feedback meanError
      Modelica.Blocks.Sources.Constant theoreticalMean(k=pMean)
      Modelica.Blocks.Math.Feedback varianceError
      Modelica.Blocks.Sources.Constant theoreticalSigma(k=std)
      Modelica.Blocks.Math.StandardDeviation standardDeviation
      Modelica.Blocks.Math.Feedback sigmaError
    equation
      connect(noise.y, mean.u)
      connect(noise.y, variance.u)
      connect(mean.y, meanError.u1)
      connect(theoreticalMean.y, meanError.u2)
      connect(theoreticalSigma.y, theoreticalVariance.u[1])
      connect(theoreticalSigma.y, theoreticalVariance.u[2])
      connect(variance.y, varianceError.u1)
      connect(theoreticalVariance.y, varianceError.u2)
      connect(noise.y, standardDeviation.u)
      connect(standardDeviation.y, sigmaError.u1)
      connect(theoreticalSigma.y, sigmaError.u2)
    end NormalNoiseProperties;

    model Densities
      "Demonstrates how to compute distribution densities (= Probability Density Function)"
      extends Modelica.Icons.Example;
      output Real uniformDensity_y = uniformDensity.y;
      output Real normalDensity_y = normalDensity.y;
      output Real weibullDensity_y = weibullDensity.y;

      Utilities.UniformDensity
                        uniformDensity(u_min=-4, u_max=4)
      Modelica.Blocks.Sources.ContinuousClock clock
      Modelica.Blocks.Sources.Constant const(k=-10)
      Modelica.Blocks.Math.Add add
      Utilities.NormalDensity
                        normalDensity(mu=0, sigma=2)
      Utilities.WeibullDensity
                        weibullDensity(lambda=3, k=1.5)
    equation
      connect(clock.y, add.u1)
      connect(const.y, add.u2)
      connect(add.y, uniformDensity.u)
      connect(add.y, normalDensity.u)
      connect(add.y, weibullDensity.u)
    end Densities;

    model ImpureGenerator
      "Demonstrates the usage of the impure random number generator"
      extends Modelica.Icons.Example;
      output Real impureRandom_y = impureRandom.y;

      inner Modelica.Blocks.Noise.GlobalSeed globalSeed(useAutomaticSeed=
            false)

      Utilities.ImpureRandom impureRandom(samplePeriod=0.01)
    end ImpureGenerator;

    model ActuatorWithNoise
      "Demonstrates how to model measurement noise in an actuator"
    extends Modelica.Icons.Example;
      Utilities.Parts.MotorWithCurrentControl motor
      Utilities.Parts.Controller controller
      Modelica.Blocks.Sources.Step speed(startTime=0.5, height=50)
      Modelica.Mechanics.Rotational.Components.Gearbox gearbox(
        lossTable=[0,0.85,0.8,0.1,0.1],
        c=1e6,
        d=1e4,
        ratio=10,
        w_rel(fixed=true),
        b=0.0017453292519943,
        phi_rel(fixed=true))
      Modelica.Mechanics.Translational.Components.IdealGearR2T idealGearR2T(ratio=
            300)
      Modelica.Mechanics.Translational.Components.Mass mass(m=100)
      Modelica.Mechanics.Translational.Sources.ConstantForce constantForce(
          f_constant=10000)
      Modelica.Blocks.Nonlinear.SlewRateLimiter slewRateLimiter(Rising=50)
      Modelica.Mechanics.Translational.Components.Mass rodMass(m=3)
      Modelica.Mechanics.Translational.Components.SpringDamper elastoGap(c=1e8, d=
            1e5,
        v_rel(fixed=true),
        s_rel(fixed=true))
      inner .Modelica.Blocks.Noise.GlobalSeed globalSeed(enableNoise=true)
    equation
      connect(controller.y1, motor.iq_rms1)
      connect(motor.phi, controller.positionMeasured)
      connect(motor.flange, gearbox.flange_a)
      connect(gearbox.flange_b, idealGearR2T.flangeR)
      connect(constantForce.flange, mass.flange_b)
      connect(speed.y, slewRateLimiter.u)
      connect(slewRateLimiter.y, controller.positionReference)
      connect(rodMass.flange_a, idealGearR2T.flangeT)
      connect(rodMass.flange_b, elastoGap.flange_a)
      connect(elastoGap.flange_b, mass.flange_a)
    end ActuatorWithNoise;

    model DrydenContinuousTurbulence
      "Demonstrates how to model wind turbulence for aircraft with the BandLimitedWhiteNoise block (a simple model of vertical Dryden gust speed at low altitudes < 1000 ft)"
      extends Modelica.Icons.Example;

      import Modelica.Constants.pi;

      parameter SI.Velocity V =            140 * 0.5144
        "Airspeed of aircraft (typically 140kts during approach)";
      parameter SI.Velocity sigma = 0.1 *   30 * 0.5144
        "Turbulence intensity (=0.1 * wind at 20 ft, typically 30 kt)";
      parameter SI.Length   L =            600 * 0.3048
        "Scale length (= flight altitude)";

      Modelica.Blocks.Continuous.TransferFunction Hw(b=sigma*sqrt(L/pi/V)*{sqrt(3)*
            L/V,1}, a={L^2/V^2,2*L/V,1},
        initType=Modelica.Blocks.Types.Init.InitialState)
        "Transfer function of vertical turbulence speed according to MIL-F-8785C"
      Modelica.Blocks.Noise.BandLimitedWhiteNoise whiteNoise(samplePeriod=
           0.005)
      constant SI.Velocity unitVelocity = 1
      Modelica.Blocks.Math.Gain compareToSpeed(k=unitVelocity/V)
      inner Modelica.Blocks.Noise.GlobalSeed globalSeed
    equation
      connect(whiteNoise.y, Hw.u)
      connect(Hw.y, compareToSpeed.u)
    end DrydenContinuousTurbulence;

    package Utilities "Library of utility models used in the examples"
      extends Modelica.Icons.UtilitiesPackage;

      block UniformDensity "Calculates the density of a uniform distribution"
        import distribution = Modelica.Math.Distributions.Uniform.density;
        extends Modelica.Blocks.Icons.Block;

        parameter Real u_min "Lower limit of u";
        parameter Real u_max "Upper limit of u";

        Modelica.Blocks.Interfaces.RealInput u "Real input signal"
        Modelica.Blocks.Interfaces.RealOutput y
          "Density of the input signal according to the uniform probability density function"
      equation
        y = distribution(u, u_min, u_max);
      end UniformDensity;

      block NormalDensity "Calculates the density of a normal distribution"
        import distribution = Modelica.Math.Distributions.Normal.density;
        extends Modelica.Blocks.Icons.Block;

        parameter Real mu "Expectation (mean) value of the normal distribution";
        parameter Real sigma "Standard deviation of the normal distribution";

        Modelica.Blocks.Interfaces.RealInput u "Real input signal"
        Modelica.Blocks.Interfaces.RealOutput y
          "Density of the input signal according to the normal probability density function"
      equation
        y = distribution(u, mu, sigma);
      end NormalDensity;

      block WeibullDensity "Calculates the density of a Weibull distribution"
        import distribution = Modelica.Math.Distributions.Weibull.density;
        extends Modelica.Blocks.Icons.Block;

        parameter Real lambda(min=0)
          "Scale parameter of the Weibull distribution";
        parameter Real k(min=0) "Shape parameter of the Weibull distribution";

        Modelica.Blocks.Interfaces.RealInput u "Real input signal"
        Modelica.Blocks.Interfaces.RealOutput y
          "Density of the input signal according to the Weibull probability density function"
      equation
        y = distribution(u, lambda, k);
      end WeibullDensity;

      block ImpureRandom
        "Block generating random numbers with the impure random number generator"
        extends Modelica.Blocks.Interfaces.SO;

        parameter SI.Period samplePeriod
          "Sample period for random number generation";

      protected
         outer Modelica.Blocks.Noise.GlobalSeed globalSeed;

      equation
         when {initial(), sample(samplePeriod,samplePeriod)} then
            y = Modelica.Math.Random.Utilities.impureRandom(globalSeed.id_impure);
         end when;
      end ImpureRandom;

      package Parts "Parts for use in the ActuatorWithNoise examples"
        extends Modelica.Icons.Package;

        model MotorWithCurrentControl
          "Synchronous machine with current controller and measurement noise"
          extends Modelica.Electrical.Machines.Icons.TransientMachine;
          constant Integer m=3 "Number of phases";
          parameter SI.Voltage VNominal=100
            "Nominal RMS voltage per phase";
          parameter SI.Frequency fNominal=50 "Nominal frequency";
          parameter SI.Frequency f=50 "Actual frequency";
          parameter SI.Time tRamp=1 "Frequency ramp";
          parameter SI.Torque TLoad=181.4 "Nominal load torque";
          parameter SI.Time tStep=1.2 "Time of load torque step";
          parameter SI.Inertia JLoad=0.29 "Load's moment of inertia";

          Modelica.Electrical.Machines.BasicMachines.SynchronousMachines.SM_PermanentMagnet
            smpm(
            p=smpmData.p,
            fsNominal=smpmData.fsNominal,
            Rs=smpmData.Rs,
            TsRef=smpmData.TsRef,
            Lszero=smpmData.Lszero,
            Lssigma=smpmData.Lssigma,
            Jr=smpmData.Jr,    Js=smpmData.Js,
            frictionParameters=smpmData.frictionParameters,
            wMechanical(fixed=true),
            statorCoreParameters=smpmData.statorCoreParameters,
            strayLoadParameters=smpmData.strayLoadParameters,
            VsOpenCircuit=smpmData.VsOpenCircuit,
            Lmd=smpmData.Lmd,
            Lmq=smpmData.Lmq,
            useDamperCage=smpmData.useDamperCage,
            Lrsigmad=smpmData.Lrsigmad,
            Lrsigmaq=smpmData.Lrsigmaq,
            Rrd=smpmData.Rrd,
            Rrq=smpmData.Rrq,
            TrRef=smpmData.TrRef,
            permanentMagnetLossParameters=smpmData.permanentMagnetLossParameters,
            phiMechanical(fixed=true),
            TsOperational=293.15,
            alpha20s=smpmData.alpha20s,
            TrOperational=293.15,
            alpha20r=smpmData.alpha20r)
          Modelica.Electrical.Polyphase.Sources.SignalCurrent signalCurrent(final m=m)
          Modelica.Electrical.Polyphase.Basic.Star star(final m=m)
          Modelica.Electrical.Analog.Basic.Ground ground
          Modelica.Electrical.Machines.Utilities.DQToThreePhase dqToThreePhase(
              p=smpm.p)
          Modelica.Electrical.Polyphase.Basic.Star starM(final m=m)
          Modelica.Electrical.Analog.Basic.Ground groundM
          Modelica.Electrical.Machines.Utilities.TerminalBox terminalBox(
              terminalConnection="Y")
          Modelica.Electrical.Machines.Sensors.RotorDisplacementAngle rotorDisplacementAngle(p=smpm.p)
          Modelica.Mechanics.Rotational.Sensors.AngleSensor angleSensor
          Modelica.Mechanics.Rotational.Sensors.TorqueSensor torqueSensor
          Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor
          Modelica.Electrical.Machines.Sensors.VoltageQuasiRMSSensor voltageQuasiRMSSensor
          Modelica.Electrical.Machines.Sensors.CurrentQuasiRMSSensor currentQuasiRMSSensor
          Modelica.Mechanics.Rotational.Components.Inertia inertiaLoad(J=0.29)
          parameter
            Modelica.Electrical.Machines.Utilities.ParameterRecords.SM_PermanentMagnetData
            smpmData(useDamperCage=false) "Data for motor"
          Modelica.Blocks.Sources.Constant id(k=0)
          Modelica.Blocks.Interfaces.RealInput iq_rms1
          Modelica.Mechanics.Rotational.Interfaces.Flange_b flange
            "Right flange of shaft"
          Modelica.Blocks.Interfaces.RealOutput phi(unit="rad")
            "Absolute angle of flange as output signal"
          output Real phi_motor(unit="rad", displayUnit="deg")=angleSensor.phi
            "Rotational position";
          output Real w(unit="rad/s")=speedSensor.w "Rotational speed";
          Modelica.Blocks.Math.Add addNoise
          .Modelica.Blocks.Noise.UniformNoise uniformNoise(
            samplePeriod=1/200,
            y_min=-0.01,
            y_max=0.01)
        equation
          connect(star.pin_n, ground.p)
          connect(rotorDisplacementAngle.plug_n, smpm.plug_sn)
          connect(rotorDisplacementAngle.plug_p, smpm.plug_sp)
          connect(terminalBox.plug_sn, smpm.plug_sn)
          connect(terminalBox.plug_sp, smpm.plug_sp)
          connect(smpm.flange, rotorDisplacementAngle.flange)
          connect(signalCurrent.plug_p, star.plug_p)
          connect(angleSensor.flange, rotorDisplacementAngle.flange)
          connect(angleSensor.phi, dqToThreePhase.phi)
          connect(groundM.p, terminalBox.starpoint)
          connect(smpm.flange, torqueSensor.flange_a)
          connect(voltageQuasiRMSSensor.plug_p, terminalBox.plugSupply)
          connect(starM.plug_p, voltageQuasiRMSSensor.plug_n)
          connect(starM.pin_n, groundM.p)
          connect(dqToThreePhase.y, signalCurrent.i)
          connect(speedSensor.flange, smpm.flange)
          connect(torqueSensor.flange_b, inertiaLoad.flange_a)
          connect(signalCurrent.plug_n, currentQuasiRMSSensor.plug_p)
          connect(currentQuasiRMSSensor.plug_n, voltageQuasiRMSSensor.plug_p)
          connect(inertiaLoad.flange_b, flange)
          connect(angleSensor.phi, addNoise.u2)
          connect(addNoise.y, phi)
          connect(uniformNoise.y, addNoise.u1)
          connect(id.y, dqToThreePhase.d)
          connect(iq_rms1, dqToThreePhase.q)
        end MotorWithCurrentControl;

        model Controller "Simple position controller for actuator"
          extends Modelica.Blocks.Icons.Block;

          Modelica.Blocks.Continuous.PI speed_PI(k=10, T=5e-2,
            initType=Modelica.Blocks.Types.Init.InitialOutput)
          Modelica.Blocks.Math.Feedback speedFeedback
          Modelica.Blocks.Continuous.Derivative positionToSpeed(initType=Modelica.Blocks.Types.Init.InitialOutput,
              T=0.01)
          Modelica.Blocks.Interfaces.RealInput positionMeasured
            "Position signal of motor"
          Modelica.Blocks.Interfaces.RealInput positionReference
            "Reference position"
          Modelica.Blocks.Interfaces.RealOutput y1
            "Connector of Real output signal"
          Modelica.Blocks.Continuous.PI position_PI(T=5e-1, k=3,
            initType=Modelica.Blocks.Types.Init.InitialState)
          Modelica.Blocks.Math.Feedback positionFeedback
          Modelica.Blocks.Continuous.FirstOrder busdelay(T=1e-3, initType=Modelica.Blocks.Types.Init.InitialOutput)
        equation
          connect(speedFeedback.y, speed_PI.u)
          connect(positionFeedback.u2, positionToSpeed.u)
          connect(positionReference, positionFeedback.u1)
          connect(positionFeedback.y, position_PI.u)
          connect(position_PI.y, speedFeedback.u1)
          connect(speed_PI.y, busdelay.u)
          connect(y1, busdelay.y)
          connect(positionMeasured, positionToSpeed.u)
          connect(positionToSpeed.y, speedFeedback.u2)
        end Controller;
      end Parts;
    end Utilities;
  end Noise;

  package BusUsage_Utilities
    "Utility models and connectors for example Modelica.Blocks.Examples.BusUsage"
    extends Modelica.Icons.UtilitiesPackage;
    package Interfaces "Interfaces specialised for this example"
      extends Modelica.Icons.InterfacesPackage;

      expandable connector ControlBus
        "Control bus that is adapted to the signals connected to it"
        extends Modelica.Icons.SignalBus;

        SI.AngularVelocity realSignal1 "First Real signal (angular velocity)"
        SI.Velocity realSignal2 "Second Real signal"
        Integer integerSignal "Integer signal"
        Boolean booleanSignal "Boolean signal"
        SubControlBus subControlBus "Combined signal"

      end ControlBus;

      expandable connector SubControlBus
        "Sub-control bus that is adapted to the signals connected to it"
        extends Modelica.Icons.SignalSubBus;
        Real myRealSignal
        Boolean myBooleanSignal

      end SubControlBus;
    end Interfaces;

    model Part "Component with sub-control bus"

      Interfaces.SubControlBus subControlBus
      Sources.RealExpression realExpression(y=time)
      Sources.BooleanExpression booleanExpression(y=time >= 0.5)
    equation
      connect(realExpression.y, subControlBus.myRealSignal)
      connect(booleanExpression.y, subControlBus.myBooleanSignal)
    end Part;
  end BusUsage_Utilities;
end Examples;
end Blocks;


within Modelica.Blocks;
package Routing "Library of blocks to combine and extract signals"
  extends Modelica.Icons.Package;

  block Replicator "Signal replicator"
    extends Modelica.Blocks.Interfaces.SIMO;
  equation
    y = fill(u, nout);
  end Replicator;

  block IntegerReplicator "Integer signal replicator"
    extends Modelica.Blocks.Icons.IntegerBlock;
    parameter Integer nout=1 "Number of outputs";
    Modelica.Blocks.Interfaces.IntegerInput u
      "Connector of Integer input signal"
    Modelica.Blocks.Interfaces.IntegerOutput y[nout]
      "Connector of Integer output signals"
  equation

    y = fill(u, nout);
  end IntegerReplicator;

  block BooleanReplicator "Boolean signal replicator"
    extends Modelica.Blocks.Icons.BooleanBlock;
    parameter Integer nout=1 "Number of outputs";
    Modelica.Blocks.Interfaces.BooleanInput u
      "Connector of Boolean input signal"
    Modelica.Blocks.Interfaces.BooleanOutput y[nout]
      "Connector of Boolean output signals"
  equation

    y = fill(u, nout);
  end BooleanReplicator;

block ExtractSignal "Extract signals from an input signal vector"
  extends Modelica.Blocks.Interfaces.MIMO;
  parameter Integer extract[nout]=1:nout "Extracting vector";

equation
  for i in 1:nout loop
    y[i] = u[extract[i]];

  end for;
end ExtractSignal;

block Extractor
    "Extract scalar signal out of signal vector dependent on IntegerRealInput index"

  extends Modelica.Blocks.Interfaces.MISO;

  parameter Boolean allowOutOfRange=false "= true, if index may be out of range"
  parameter Real outOfRangeValue=1e10 "Output signal if index is out of range"

  Modelica.Blocks.Interfaces.IntegerInput index
  protected
  Real k[nin];
equation

  when {initial(),change(index)} then

    for i in 1:nin loop
      k[i] = if index == i then 1 else 0;
    end for;

  end when;

  y = if not allowOutOfRange or index >= 1 and index <= nin then
              k*u else outOfRangeValue;

  if not allowOutOfRange then
    assert(index >= 1 and index <= nin,
      "The input index (=" + String(index) + ") is out of range.");
  end if;
end Extractor;

  block Multiplex "Multiplexer block for arbitrary number of input connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n(min=0)=0 "Dimension of input signal connector"
    Modelica.Blocks.Interfaces.RealVectorInput u[n]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealOutput y[n+0]
      "Connector of Real output signals"

  equation
      y = u;
  end Multiplex;

  block Multiplex2 "Multiplexer block for two input connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of input signal connector 1";
    parameter Integer n2=1 "Dimension of input signal connector 2";
    Modelica.Blocks.Interfaces.RealInput u1[n1]
      "Connector of Real input signals 1"
    Modelica.Blocks.Interfaces.RealInput u2[n2]
      "Connector of Real input signals 2"
    Modelica.Blocks.Interfaces.RealOutput y[n1 + n2]
      "Connector of Real output signals"

  equation
    [y] = [u1; u2];
  end Multiplex2;

  block Multiplex3 "Multiplexer block for three input connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of input signal connector 1";
    parameter Integer n2=1 "Dimension of input signal connector 2";
    parameter Integer n3=1 "Dimension of input signal connector 3";
    Modelica.Blocks.Interfaces.RealInput u1[n1]
      "Connector of Real input signals 1"
    Modelica.Blocks.Interfaces.RealInput u2[n2]
      "Connector of Real input signals 2"
    Modelica.Blocks.Interfaces.RealInput u3[n3]
      "Connector of Real input signals 3"
    Modelica.Blocks.Interfaces.RealOutput y[n1 + n2 + n3]
      "Connector of Real output signals"

  equation
    [y] = [u1; u2; u3];
  end Multiplex3;

  block Multiplex4 "Multiplexer block for four input connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of input signal connector 1";
    parameter Integer n2=1 "Dimension of input signal connector 2";
    parameter Integer n3=1 "Dimension of input signal connector 3";
    parameter Integer n4=1 "Dimension of input signal connector 4";
    Modelica.Blocks.Interfaces.RealInput u1[n1]
      "Connector of Real input signals 1"
    Modelica.Blocks.Interfaces.RealInput u2[n2]
      "Connector of Real input signals 2"
    Modelica.Blocks.Interfaces.RealInput u3[n3]
      "Connector of Real input signals 3"
    Modelica.Blocks.Interfaces.RealInput u4[n4]
      "Connector of Real input signals 4"
    Modelica.Blocks.Interfaces.RealOutput y[n1 + n2 + n3 + n4]
      "Connector of Real output signals"

  equation
    [y] = [u1; u2; u3; u4];
  end Multiplex4;

  block Multiplex5 "Multiplexer block for five input connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of input signal connector 1";
    parameter Integer n2=1 "Dimension of input signal connector 2";
    parameter Integer n3=1 "Dimension of input signal connector 3";
    parameter Integer n4=1 "Dimension of input signal connector 4";
    parameter Integer n5=1 "Dimension of input signal connector 5";
    Modelica.Blocks.Interfaces.RealInput u1[n1]
      "Connector of Real input signals 1"
    Modelica.Blocks.Interfaces.RealInput u2[n2]
      "Connector of Real input signals 2"
    Modelica.Blocks.Interfaces.RealInput u3[n3]
      "Connector of Real input signals 3"
    Modelica.Blocks.Interfaces.RealInput u4[n4]
      "Connector of Real input signals 4"
    Modelica.Blocks.Interfaces.RealInput u5[n5]
      "Connector of Real input signals 5"
    Modelica.Blocks.Interfaces.RealOutput y[n1 + n2 + n3 + n4 + n5]
      "Connector of Real output signals"

  equation
    [y] = [u1; u2; u3; u4; u5];
  end Multiplex5;

  block Multiplex6 "Multiplexer block for six input connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of input signal connector 1";
    parameter Integer n2=1 "Dimension of input signal connector 2";
    parameter Integer n3=1 "Dimension of input signal connector 3";
    parameter Integer n4=1 "Dimension of input signal connector 4";
    parameter Integer n5=1 "Dimension of input signal connector 5";
    parameter Integer n6=1 "Dimension of input signal connector 6";
    Modelica.Blocks.Interfaces.RealInput u1[n1]
      "Connector of Real input signals 1"
    Modelica.Blocks.Interfaces.RealInput u2[n2]
      "Connector of Real input signals 2"
    Modelica.Blocks.Interfaces.RealInput u3[n3]
      "Connector of Real input signals 3"

    Modelica.Blocks.Interfaces.RealInput u4[n4]
      "Connector of Real input signals 4"
    Modelica.Blocks.Interfaces.RealInput u5[n5]
      "Connector of Real input signals 5"
    Modelica.Blocks.Interfaces.RealInput u6[n6]
      "Connector of Real input signals 6"
    Modelica.Blocks.Interfaces.RealOutput y[n1 + n2 + n3 + n4 + n5 + n6]
      "Connector of Real output signals"

  equation
    [y] = [u1; u2; u3; u4; u5; u6];
  end Multiplex6;

  block DeMultiplex "DeMultiplexer block for arbitrary number of output connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n(min=0)=0 "Dimension of output signal connector"
    Modelica.Blocks.Interfaces.RealInput u[n+0]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealVectorOutput y[n]
      "Connector of Real output signals"

  equation
      y = u;
  end DeMultiplex;

  block DeMultiplex2 "DeMultiplexer block for two output connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of output signal connector 1";
    parameter Integer n2=1 "Dimension of output signal connector 2";
    Modelica.Blocks.Interfaces.RealInput u[n1 + n2]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealOutput y1[n1]
      "Connector of Real output signals 1"
    Modelica.Blocks.Interfaces.RealOutput y2[n2]
      "Connector of Real output signals 2"

  equation
    [u] = [y1; y2];
  end DeMultiplex2;

  block DeMultiplex3 "DeMultiplexer block for three output connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of output signal connector 1";
    parameter Integer n2=1 "Dimension of output signal connector 2";
    parameter Integer n3=1 "Dimension of output signal connector 3";
    Modelica.Blocks.Interfaces.RealInput u[n1 + n2 + n3]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealOutput y1[n1]
      "Connector of Real output signals 1"
    Modelica.Blocks.Interfaces.RealOutput y2[n2]
      "Connector of Real output signals 2"
    Modelica.Blocks.Interfaces.RealOutput y3[n3]
      "Connector of Real output signals 3"

  equation
    [u] = [y1; y2; y3];
  end DeMultiplex3;

  block DeMultiplex4 "DeMultiplexer block for four output connectors"

    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of output signal connector 1";
    parameter Integer n2=1 "Dimension of output signal connector 2";
    parameter Integer n3=1 "Dimension of output signal connector 3";
    parameter Integer n4=1 "Dimension of output signal connector 4";
    Modelica.Blocks.Interfaces.RealInput u[n1 + n2 + n3 + n4]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealOutput y1[n1]
      "Connector of Real output signals 1"
    Modelica.Blocks.Interfaces.RealOutput y2[n2]
      "Connector of Real output signals 2"
    Modelica.Blocks.Interfaces.RealOutput y3[n3]
      "Connector of Real output signals 3"
    Modelica.Blocks.Interfaces.RealOutput y4[n4]
      "Connector of Real output signals 4"

  equation
    [u] = [y1; y2; y3; y4];
  end DeMultiplex4;

  block DeMultiplex5 "DeMultiplexer block for five output connectors"

    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of output signal connector 1";
    parameter Integer n2=1 "Dimension of output signal connector 2";
    parameter Integer n3=1 "Dimension of output signal connector 3";
    parameter Integer n4=1 "Dimension of output signal connector 4";
    parameter Integer n5=1 "Dimension of output signal connector 5";
    Modelica.Blocks.Interfaces.RealInput u[n1 + n2 + n3 + n4 + n5]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealOutput y1[n1]
      "Connector of Real output signals 1"
    Modelica.Blocks.Interfaces.RealOutput y2[n2]
      "Connector of Real output signals 2"
    Modelica.Blocks.Interfaces.RealOutput y3[n3]
      "Connector of Real output signals 3"
    Modelica.Blocks.Interfaces.RealOutput y4[n4]
      "Connector of Real output signals 4"
    Modelica.Blocks.Interfaces.RealOutput y5[n5]
      "Connector of Real output signals 5"

  equation
    [u] = [y1; y2; y3; y4; y5];
  end DeMultiplex5;

  block DeMultiplex6 "DeMultiplexer block for six output connectors"
    extends Modelica.Blocks.Icons.Block;
    parameter Integer n1=1 "Dimension of output signal connector 1";
    parameter Integer n2=1 "Dimension of output signal connector 2";
    parameter Integer n3=1 "Dimension of output signal connector 3";
    parameter Integer n4=1 "Dimension of output signal connector 4";
    parameter Integer n5=1 "Dimension of output signal connector 5";
    parameter Integer n6=1 "Dimension of output signal connector 6";
    Modelica.Blocks.Interfaces.RealInput u[n1 + n2 + n3 + n4 + n5 + n6]
      "Connector of Real input signals"
    Modelica.Blocks.Interfaces.RealOutput y1[n1]
      "Connector of Real output signals 1"
    Modelica.Blocks.Interfaces.RealOutput y2[n2]
      "Connector of Real output signals 2"
    Modelica.Blocks.Interfaces.RealOutput y3[n3]
      "Connector of Real output signals 3"
    Modelica.Blocks.Interfaces.RealOutput y4[n4]
      "Connector of Real output signals 4"
    Modelica.Blocks.Interfaces.RealOutput y5[n5]
      "Connector of Real output signals 5"
    Modelica.Blocks.Interfaces.RealOutput y6[n6]
      "Connector of Real output signals 6"

  equation
    [u] = [y1; y2; y3; y4; y5; y6];
  end DeMultiplex6;

  model RealPassThrough "Pass a Real signal through without modification"
    extends Modelica.Blocks.Interfaces.SISO;
  equation
    y = u;
  end RealPassThrough;

  model IntegerPassThrough "Pass a Integer signal through without modification"
    extends Modelica.Blocks.Icons.IntegerBlock;

    Modelica.Blocks.Interfaces.IntegerInput u "Input signal"
    Modelica.Blocks.Interfaces.IntegerOutput y "Output signal"
  equation
    y = u;
  end IntegerPassThrough;

  model BooleanPassThrough "Pass a Boolean signal through without modification"
    extends Modelica.Blocks.Interfaces.BooleanSISO;
  equation
    y = u;
  end BooleanPassThrough;
end Routing;