Типы маршрутов
Ligral — это объектно-ориентированный язык моделирования, в котором можно создавать типы маршрутов и затем создавать несколько экземпляров для получения нескольких экземпляров. Мы считаем, что это очень полезно в сценариях моделирования. Например, если вы разработали класс пружины, то при моделировании определённого механизма вам может потребоваться ввести несколько моделей пружин, и тогда вы можете объявить несколько экземпляров пружин вместо того, чтобы копировать код.
Различия и сходства между маршрутами и классами/методами
Концепция маршрута имеет некоторое сходство с классом в C++, но также имеет некоторые отличия. Сходство заключается в следующем:
Отличие заключается в том, что:
С точки зрения класса, объявление экземпляра маршрута аналогично вызову конструктора. Ниже приведён пример синтаксиса объявления экземпляра в ligral (см. раздел «Объявление узла») и синтаксис объявления экземпляра в стиле C++:
# ligral
Spring[spring]{K:10};
// C++
auto spring = new Spring(10);
Можно видеть, что две инструкции несут одинаковую информацию (ligral поддерживает только явное указание имён параметров, в то время как C++ по умолчанию использует позиционные параметры, поэтому ligral добавляет K
). В последующем коде можно ссылаться на этот экземпляр через идентификатор spring
. Ligral разработал инструкцию объявления экземпляра таким образом, чтобы её было удобно объявлять во время вызова и всё же можно было связать экземпляр с идентификатором, чего нельзя сделать в C++.
# ligral
Step[src] -> Model;
src -> Print;
// C++
auto src = new Step();
src.to(new Model());
src.to(new Print());
После создания экземпляра класса маршрут больше похож на метод. Фактически, роль маршрута часто заключается в реализации метода (функции), которая вычисляет вывод на основе ввода. Без учёта цикла решателя следующие две инструкции имеют эквивалентный эффект:
# ligral
x -> Sin -> y;
// C++
y = sin(x);
Если вы знакомы только с математическими формулами, то синтаксис C++ явно более интуитивно понятен; если вы уже привыкли использовать Simulink, синтаксис ligral также прост и понятен. Ligral разработан таким образом, потому что он позволяет связывать вызовы без каких-либо последствий; напротив, синтаксис C++ приведёт к большому количеству скобок в конце программы, что повлияет на читаемость. Способ вызова в ligral аналогичен способу вызова pipe в сценарии оболочки, но синтаксис оболочки представляет собой смешанный стиль.
# ligral
x -> Sin -> Abs -> y;
// C++
y = abs(sin(x));
# shell
y=$(echo $x | sin | abs)
Таким образом, маршрут можно рассматривать как своего рода метод-метод, который создаёт методы путём выбора некоторых параметров для генерации методов с небольшими различиями, что немного похоже на декоратор Python.
Определение маршрута
Инструкция определения маршрута начинается с ключевого слова route
и заканчивается ключевым словом end
, включая информацию об атрибутах заголовка и логическую информацию о теле.
Атрибуты маршрута
Обычно инструкция определения маршрута первой строки содержит атрибуты маршрута, включая имя маршрута, подпись, параметры, входные и выходные порты. Среди них родительский класс, параметр и ввод-вывод могут быть опущены, а синтаксис следующий:
route RouteName(;;) ...
route RouteName:Interface(;;) ...
route RouteName(parameters; inputs; outputs) ...
Первая строка показывает синтаксис, когда все необязательные части опущены. Вторая строка демонстрирует, как объявить подпись объявления маршрута. Третья строка объясняет порядок параметров и входных данных, которые находятся в паре круглых скобок, разделённых двумя точками с запятой. Даже если один из них опущен, точка с запятой не может быть опущена. Синтаксис ввода и вывода очень прост, просто разделите имена портов запятыми, а порядок портов соответствует порядку номеров. Входные данные также могут быть установлены как необязательные с помощью ?
, и если указано значение по умолчанию, оно следует за ?
, в противном случае значение по умолчанию равно 0.
Синтаксис параметров немного сложнее. Во-первых, параметры делятся на обязательные и необязательные в зависимости от того, можно ли их опустить. Обязательные параметры требуют указания имени параметра и значения по умолчанию, а необязательные параметры должны указывать только имя параметра; во-вторых, параметры также делятся на постоянные параметры и параметры узла в соответствии с типом. Постоянные параметры принимают константу, а параметры узла принимают узел с указанной подписью. Параметры узла должны указывать подпись, а постоянные параметры не должны.
# постоянный обязательный параметр
param1,
# постоянный необязательный параметр
param2 = 0,
# обязательный параметр узла
param3:NodeSignature, ...
Параметры узла могут быть только обязательными параметрами, поскольку значение параметра по умолчанию создаётся при создании типа маршрута (а не его экземпляра), поэтому существует только одна копия глобального. Если вы объявите два экземпляра этого маршрута, эти два экземпляра будут привязаны к одному и тому же узлу, что обязательно вызовет ошибку Duplicated binding of InPort
.
Тело маршрута
Синтаксис тела маршрута такой же, как и у всей программы ligral. Внутри маршрута вы можете использовать инструкцию объявления локальной переменной для определения локальных переменных, кроме того, все параметры маршрута также являются локальными переменными. Более важно то, что вы можете объявлять узлы и описывать соединения между узлами, гарантируя, что все узлы, кроме входных, подключены, и все входные узлы не подключены.
Кроме того, хотя инструкции установки и импорта также можно использовать внутри маршрута, они, вероятно, будут запрещены в будущем, поскольку нет реальной области применения, и это может вызвать путаницу.
Полный пример
В этом разделе не обсуждается содержание, связанное с подписью интерфейса. На примере ПИД-контроллера показано, как определить маршрут:
route PIDController(Kp, Ki=0, Kd=0, tau=0.01; x; u)
x -> Integrator[xi];
x -> TransferFunction[xdot]{num=[1, 0], den=[tau, 1]};
x * Kp + xi * Ki + xdot * Kd -> u;
end
Имя этого маршрута — PIDController
, и у него есть четыре параметра, кроме Kp
, остальные три являются необязательными. Первые три — коэффициенты усиления контроллера, и если вы проигнорируете параметр Ki
, вы фактически объявите экземпляр PD-контроллера, а если вы проигнорируете Kd
, вы получите PI-контроллер. Четвёртый параметр — это постоянная времени, необходимая для дифференцирования. Есть только один вход и выход, и выход получается путём сложения входного сигнала, интегрированного сигнала и дифференцированного сигнала, умноженного на соответствующий коэффициент усиления, записанного в виде передаточной функции:
u(s) = K_px(s)+K_ix(s)\frac{1}{s}+K_dx(s)\frac{s}{\tau s+1}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )