Построение кривых Лиссажу¶
Моделирование базовых математических объектов помогает лучше понять работу порождающих их процессов. В этом примере мы изучим два способа построения модели, создающих фигуры Лиссажу, а также настроим эти модели и сравним их работу при помощи команд программного управления, описанных на странице документации "Программное управление моделированием".
Моделируемый процесс¶
Фигуры Лиссажу – это тректории, прочерчиваемые точкой, совершающей одновременно два гармонических колебания. Обычно их порождают при помощи системы из двух тригонометрических функций. Зависимость координат $x$ и $y$ от времени $t$ имеет следующий вид:
$$\left\{\begin{align*} x(t) &= A \, sin(\alpha t + \beta) \\ y(t) &= B \, sin(\beta t) \end{align*}\right.$$
здесь $A, B$ – амплитуды каждого гармонического процесса (у нас будут равны 1
)
$\alpha, \beta$ – частоты обоих процессов,
$\delta$ – смещение между гармоническими процессами.
Модель, созданная из генераторов синусоид¶
Первая наша модель будет состоять из двух блоков Sine Wave
.
Модель, заданная в виде кода¶
Вторая модель будет состоять из одного блока Engee Function
и нескольких блоков Constant
, задающих интересующие нас параметры системы.
В обоих случаях выходными параметрами являются сигналы x
и y
, и они отмечены как логируемые сигналы. Благодаря этому мы сможем считать их при програмном запуске симуляции.
Загрузка моделей¶
Первым делом нужно получить управления этими моделями. Когда модель уже открыта (например, находится на холсте), для этого служит одна команда, когда ее нужно загружать – нужна другая команда. Получим список загруженных моделей:
all_model_names = [m.name for m in engee.get_all_models()]
Если модель уже открыта, то мы используем функцию open
чтобы получить на дней управление. Если нет, то мы воспользуемся функцией load
.
# Модель, состоящая из блоков
if "lissajous_curve_blocks" in all_model_names m1 = engee.open( "lissajous_curve_blocks" )
else m1 = engee.load( "/user/start/examples/edu/lissajous_curves/lissajous_curve_blocks.engee" )
end;
# Модель, состоящая из кода
if "lissajous_curve_function" in all_model_names m2 = engee.open( "lissajous_curve_function" )
else m2 = engee.load( "/user/start/examples/edu/lissajous_curves/lissajous_curve_function.engee" )
end;
Теперь у нас есть два объекта, m1
и m2
, через которые мы можем управлять параметрами и работой обеих изучаемых нами моделей.
Синхронизация параметров моделей¶
От соотношения параметров $\alpha$ и $\beta$ зависит форма кривой (количество лепестков). Сейчас мы выставим обеим моделям одинаковые параметры при помощи команд программного управления. Мы хотим, чтобы модели использовали следующие параметры:
alpha = 3;
beta = 4;
Изучим структуру параметров блока Sine Wave
модели lissajous_curve_blocks
.
param = engee.get_param( "lissajous_curve_blocks/Sine Wave" )
Это структура типа Pair
, которую можно изменить и передать целиком в качестве новых параметров блока lissajous_curve_blocks/Sine Wave
:
param.Frequency = alpha
engee.set_param!( "lissajous_curve_blocks/Sine Wave", param )
Можно использовать и более короткий синтаксис. Сделаем то же самое для второго блока и для второй модели:
engee.set_param!( "lissajous_curve_blocks/Sine Wave-1", "Frequency"=>beta )
engee.set_param!( "lissajous_curve_function/Constant", "Value"=>alpha )
engee.set_param!( "lissajous_curve_function/Constant-1", "Value"=>beta )
Структуру параметров симуляции можно получить командой engee.get_param( "lissajous_curve_function" )
.
Установим обеим моделям один и тот же шаг симуляции:
param = engee.get_param( "lissajous_curve_blocks" )
# Установим обеим моделям временной шаг 0.001
engee.set_param!( "lissajous_curve_function", "FixedStep"=>0.001 )
engee.set_param!( "lissajous_curve_blocks", "FixedStep"=>0.001 )
Теперь мы можем выполнить эти модели при помощи команды run
:
r1 = engee.run( m1; verbose=false );
# Иногда нужно дождаться, пока модель закончит выполнение
# while( engee.get_status() != Engee.Types.READY ) end;
r2 = engee.run( m2; verbose=false );
На выходе мы получаем структуру Dict
(словарь), который содержит набор таблиц DataFrame
. В каждой таблице есть столбцы вектор time
и value
, соответствующие времени и выходному значению каждого сохранённого сигнала модели.
Результаты моделирования¶
Выходные кривые легко сравнить при помощи графика:
using Plots
plot( r1["x"].value, r1["y"].value, lc=:red, lw=10, label="Блоки Sine Wave" )
plot!( r2["x"].value, r2["y"].value, lc=:orange, lw=4, label="Блоки Engee Function" )
Выводы¶
Мы изучили работу двух моделей одного из базовых математических объектов, который рассматривается в самых разных технических дисциплинах – от физики до схемотехники. Также мы применили механизм программного управления, установив моделям одинаковые параметры и проанализировали результаты моделирования на графике, не покидая скрипта.