Двигатель постоянного тока в Engee
Создание сложных компонентов на языке физического моделирования Engee
Язык физического моделирования Engee позволяет не только разрабатывать свои компоненты но и объединять разные компоненты в единое целое. Такие компоненты называются составными.
Это как конструктор, когда есть детали (компоненты) и наша задача - соединить их в правильном порядке.
Зачем делать составные компоненты?
- "Упаковка" множества компонентов в один (как подсистема в обычном моделировании)
- Массивы компонентов
Пример составного компонента
В качестве примера составного компонента рассмотрим двигатель постоянного тока с внешней нагрузкой вала.
Что бы удостовериться в том, что компонент был собран правильно, возьмем эталонную реализацию на примитивах из библиотеки ненаправленных блоков:
Для тестирования будем моделировать следующий сценарий: в первые 0.1 секунды работы двигатель работает без нагрузки на вал, и достигает максимальной скорости, а затем на вале возникает нагрузка.
Создание составного компонента
Составные компоненты создаются точно также как и пользовательские компоненты при помощи языка физического моделирования Engee. Поэтому, код компонента должен содержаться в файле *.ngpc, расположенном по пути поиска Engee.
Посмотрим на код компонента из файла DCMotorComosite.ngpc:
@engeemodel DCMotorComposite begin
@components begin
p = EngeePhysicalFoundation.Electrical.Pin(), [view = ("+", "left")]
n = EngeePhysicalFoundation.Electrical.Pin(), [view = ("-", "left")]
r = EngeePhysicalFoundation.Mechanical.Rotational.Flange(), [view = ("R", "right")]
c = EngeePhysicalFoundation.Mechanical.Rotational.Flange(), [view = ("C", "right")]
end
@parameters begin
rotor_resistance = 3.9, [unit="Ohm"]
rotor_inductance = 12e-6, [unit="H"]
motor_inertia = 0.01, [unit="g*cm^2"]
breakaway_torque = 0.02e-3, [unit="N*m"]
coulomb_torque = 0.02e-3, [unit="N*m"]
breakaway_velocity = 0.03347, [unit="rad/s"]
back_emf_constant = 0.072e-3*60/(2*pi), [unit="V/(rad/s)"]
viscous_coefficient = 0.0, [unit="N*m/(rad/s)"]
end
@components [gui = None] begin
rotorResistor = EngeePhysicalFoundation.Electrical.Elements.Resistor(R=default(rotor_resistance))
rotorInductor = EngeePhysicalFoundation.Electrical.Elements.Inductor(L=default(rotor_inductance))
motorInertia = EngeePhysicalFoundation.Mechanical.Rotational.Elements.Inertia(I=default(motor_inertia))
friction = EngeePhysicalFoundation.Mechanical.Rotational.Elements.Friction(w_breakaway=default(breakaway_velocity),T_breakaway=default(breakaway_torque),T_coulomb=default(coulomb_torque), viscous_coefficient=default(viscous_coefficient))
rotEMechConverter = EngeePhysicalFoundation.Electrical.Elements.RotationalConverter(k=default(back_emf_constant))
end
@equations begin
connect(p, rotorResistor.p)
connect(rotorResistor.n, rotorInductor.p)
connect(rotorInductor.n, rotEMechConverter.p)
connect(rotEMechConverter.n, n)
connect(rotEMechConverter.rod_flange, friction.rod_flange, motorInertia.flange, r)
connect(rotEMechConverter.case_flange, friction.case_flange, c)
end
end
Обратите внимание на то, как мы создаем подкомпоненты - они содержатся в секции @components. Мы инициализируем их параметры значениями из секции @parameters
Сборка подкомпонентов в единый компонент происходит в секции @equations с помощью функции connect(). Обратим внимание, что можно указывать сразу несколько портов для соединения!
Тестирование составного компонента
Проверим результаты моделирования нашего составного компонента относительно той же модели, но на примитивах
demoroot = @__DIR__
engee.addpath(demoroot)
mdl = engee.open(joinpath(demoroot,"DCComposite.engee"))
sim_res = engee.run(mdl);
Давайте построим графики результатов симуляции:
using Plots
CustC = collect(sim_res["Cust"]);
Primitives = collect(sim_res["Prim"]);
plot(CustC.time,CustC.value, label = "Пользовательский компонент")
plot!(Primitives.time,Primitives.value, label = "Библиотека блоков")
plot!(legend=:outerbottom,legendcolumns=2)
Найдем максимальную абсолютную ошибку:
err = CustC.value .- Primitives.value;
println("Максимальная абсолютная ошибка: $(maximum(err))")
Результаты моделирования фактически совпадают, а значит наш компонент работает правильно!
Выводы
Язык физического моделирования Engee - это не просто язык написания пользовательских компонентов для 1-d моделирования, но и язык для создания и описания сложных физических систем. При этом была сохранена читаемость кода, что важно для сложных систем!