Skip to content
RotationalEMFTest.md

RotationalEMFTest

A test circuit for a rotational electromechanical transducer (RotationalEMF) driven by a sinusoidal voltage and connected to an inertial load.

This model simulates a rotational electromechanical device (RotationalEMF) whose electrical terminals are excited by a sinusoidal voltage. The housing of the RotationalEMF is mechanically fixed, while its rotor is connected to a rotational Inertia. A Sine signal generator provides the input for a VoltageSource, which in turn applies voltage to the RotationalEMF. This setup allows for testing the dynamic response of the RotationalEMF and the connected inertia to electrical stimulation. The primary behavior demonstrated is the conversion of electrical energy (sinusoidal voltage) into mechanical motion (rotation of the inertia) and the generation of torque.

Usage

RotationalEMFTest()

Behavior

julia
using ElectricalComponents #hide
using ModelingToolkit #hide
@named sys = RotationalEMFTest() #hide
full_equations(sys) #hide
<< @example-block not executed in draft mode >>

Source

dyad
# A test circuit for a rotational electromechanical transducer (RotationalEMF) driven by a sinusoidal voltage and connected to an inertial load.
#
# This model simulates a rotational electromechanical device (`RotationalEMF`) whose electrical terminals are excited by a sinusoidal voltage. The housing of the `RotationalEMF` is mechanically fixed, while its rotor is connected to a rotational `Inertia`. A `Sine` signal generator provides the input for a `VoltageSource`, which in turn applies voltage to the `RotationalEMF`. This setup allows for testing the dynamic response of the `RotationalEMF` and the connected inertia to electrical stimulation. The primary behavior demonstrated is the conversion of electrical energy (sinusoidal voltage) into mechanical motion (rotation of the inertia) and the generation of torque.
test component RotationalEMFTest
  # Electromechanical transducer converting electrical to rotational energy and vice-versa, with coupling constant k=1.
  rot_emf = RotationalEMF(k=1) [{
    "Dyad": {"placement": {"icon": {"x1": 300, "y1": 700, "x2": 500, "y2": 900, "rot": 0}}}
  }]
  # Represents a mechanically fixed point, providing a stationary reference for the EMF housing.
  fixed = RotationalComponents.Fixed() [{
    "Dyad": {"placement": {"icon": {"x1": 0, "y1": 700, "x2": 200, "y2": 900, "rot": 180}}}
  }]
  # Generates a sinusoidal signal (amplitude=1, frequency=1 rad/s, offset=0, start_time=0) to define the voltage source's behavior.
  input_signal = BlockComponents.Sine(amplitude=1, frequency=1, offset=0, start_time=0) [{
    "Dyad": {"placement": {"icon": {"x1": 300, "y1": 100, "x2": 500, "y2": 300, "rot": 0}}}
  }]
  # Ideal voltage source whose output voltage is driven by the input_signal.
  sine_voltage = VoltageSource() [{
    "Dyad": {"placement": {"icon": {"x1": 500, "y1": 400, "x2": 700, "y2": 600, "rot": 0}}}
  }]
  # Rotational inertia with moment of inertia J=100 kg.m^2, representing the mechanical load.
  inertia = RotationalComponents.Inertia(J=100) [{
    "Dyad": {"placement": {"icon": {"x1": 600, "y1": 700, "x2": 800, "y2": 900, "rot": 0}}}
  }]
relations
  initial rot_emf.phi = 0.0
  connect(input_signal.y, sine_voltage.V) [{"Dyad": {"edges": [{"S": 1, "M": [{"x": 600, "y": 200}], "E": 2}]}}]
  connect(fixed.spline, rot_emf.housing) [{"Dyad": {"edges": [{"S": 1, "E": 2}]}}]
  connect(rot_emf.p, sine_voltage.p) [{"Dyad": {"edges": [{"S": 1, "M": [{"x": 400, "y": 500}], "E": 2}]}}]
  connect(sine_voltage.n, rot_emf.n) [{
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 750, "y": 500},
            {"x": 750, "y": 650},
            {"x": 550, "y": 650},
            {"x": 550, "y": 950},
            {"x": 400, "y": 950}
          ],
          "E": 2
        }
      ]
    }
  }]
  connect(rot_emf.rotor, inertia.spline_a) [{"Dyad": {"edges": [{"S": 1, "E": 2}]}}]
metadata {
  "Dyad": {
    "tests": {"case1": {"stop": 10, "expect": {"signals": ["rot_emf.tau", "rot_emf.phi"]}}}
  }
}
end
Flattened Source
dyad
# A test circuit for a rotational electromechanical transducer (RotationalEMF) driven by a sinusoidal voltage and connected to an inertial load.
#
# This model simulates a rotational electromechanical device (`RotationalEMF`) whose electrical terminals are excited by a sinusoidal voltage. The housing of the `RotationalEMF` is mechanically fixed, while its rotor is connected to a rotational `Inertia`. A `Sine` signal generator provides the input for a `VoltageSource`, which in turn applies voltage to the `RotationalEMF`. This setup allows for testing the dynamic response of the `RotationalEMF` and the connected inertia to electrical stimulation. The primary behavior demonstrated is the conversion of electrical energy (sinusoidal voltage) into mechanical motion (rotation of the inertia) and the generation of torque.
test component RotationalEMFTest
  # Electromechanical transducer converting electrical to rotational energy and vice-versa, with coupling constant k=1.
  rot_emf = RotationalEMF(k=1) [{
    "Dyad": {"placement": {"icon": {"x1": 300, "y1": 700, "x2": 500, "y2": 900, "rot": 0}}}
  }]
  # Represents a mechanically fixed point, providing a stationary reference for the EMF housing.
  fixed = RotationalComponents.Fixed() [{
    "Dyad": {"placement": {"icon": {"x1": 0, "y1": 700, "x2": 200, "y2": 900, "rot": 180}}}
  }]
  # Generates a sinusoidal signal (amplitude=1, frequency=1 rad/s, offset=0, start_time=0) to define the voltage source's behavior.
  input_signal = BlockComponents.Sine(amplitude=1, frequency=1, offset=0, start_time=0) [{
    "Dyad": {"placement": {"icon": {"x1": 300, "y1": 100, "x2": 500, "y2": 300, "rot": 0}}}
  }]
  # Ideal voltage source whose output voltage is driven by the input_signal.
  sine_voltage = VoltageSource() [{
    "Dyad": {"placement": {"icon": {"x1": 500, "y1": 400, "x2": 700, "y2": 600, "rot": 0}}}
  }]
  # Rotational inertia with moment of inertia J=100 kg.m^2, representing the mechanical load.
  inertia = RotationalComponents.Inertia(J=100) [{
    "Dyad": {"placement": {"icon": {"x1": 600, "y1": 700, "x2": 800, "y2": 900, "rot": 0}}}
  }]
relations
  initial rot_emf.phi = 0.0
  connect(input_signal.y, sine_voltage.V) [{"Dyad": {"edges": [{"S": 1, "M": [{"x": 600, "y": 200}], "E": 2}]}}]
  connect(fixed.spline, rot_emf.housing) [{"Dyad": {"edges": [{"S": 1, "E": 2}]}}]
  connect(rot_emf.p, sine_voltage.p) [{"Dyad": {"edges": [{"S": 1, "M": [{"x": 400, "y": 500}], "E": 2}]}}]
  connect(sine_voltage.n, rot_emf.n) [{
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 750, "y": 500},
            {"x": 750, "y": 650},
            {"x": 550, "y": 650},
            {"x": 550, "y": 950},
            {"x": 400, "y": 950}
          ],
          "E": 2
        }
      ]
    }
  }]
  connect(rot_emf.rotor, inertia.spline_a) [{"Dyad": {"edges": [{"S": 1, "E": 2}]}}]
metadata {
  "Dyad": {
    "tests": {"case1": {"stop": 10, "expect": {"signals": ["rot_emf.tau", "rot_emf.phi"]}}}
  }
}
end


Test Cases

julia
using ElectricalComponents
using ModelingToolkit, OrdinaryDiffEqDefault
using Plots
using CSV, DataFrames

snapshotsdir = joinpath(dirname(dirname(pathof(ElectricalComponents))), "test", "snapshots")
<< @setup-block not executed in draft mode >>

Test Case case1

julia
@mtkbuild model_case1 = RotationalEMFTest()
u0_case1 = []
prob_case1 = ODEProblem(model_case1, u0_case1, (0, 10))
sol_case1 = solve(prob_case1)
<< @setup-block not executed in draft mode >>
julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.rot_emf.tau])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "RotationalEMFTest_case1_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.rot_emf.tau], width=2, label="Actual value of rot_emf.tau")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of rot_emf.tau")
end
<< @setup-block not executed in draft mode >>
julia
plt
<< @example-block not executed in draft mode >>
julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.rot_emf.phi])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "RotationalEMFTest_case1_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.rot_emf.phi], width=2, label="Actual value of rot_emf.phi")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of rot_emf.phi")
end
<< @setup-block not executed in draft mode >>
julia
plt
<< @example-block not executed in draft mode >>