Сгенерируйте классы C++ для классов MATLAB ®, которые моделируют простые и демпфированные генераторы

Классы MATLAB обеспечивают естественную среду для моделирования физических систем:

  • Можно смоделировать простую систему как класс MATLAB. Свойствами частного класса являются системные параметры. Конструктор классов создает образец системы с заданными параметрами. Общедоступный метод захватывает динамику системы, возвращая окончательное состояние для заданного начального состояния и временного интервала. Класс может также содержать другие вспомогательные методы, которые модулируют математический анализ.

  • Вы часто начинаете анализ с простой системы, а затем вводите дополнительные эффекты (такие как механическое демпфирование), чтобы повысить точность анализа. В MATLAB можно смоделировать расширенную систему как подкласс, который наследует от исходного класса. Подкласс может содержать дополнительные частную собственность для дополнительных системных параметров (таких как константа демпфирования). В зависимости от специфики системы, подкласс может наследовать определенные методы от базового класса и может перегрузить другие методы.

Этот пример показывает, как сгенерировать код С++ для функции MATLAB, которая сравнивает эволюцию времени простого генератора и демпфированного генератора с идентичными параметрами и начальными условиями. Две системы генераторов моделируются с помощью классов MATLAB simpleOscillator и dampedOscillator которые заданы в пакете MATLAB mySystem. Сгенерированный код содержит классы C++ для исходных классов MATLAB. В примере также показано, как классы MATLAB сопоставляются с сгенерированными классами C++ и как использовать сгенерированный код в пользовательской основной функции C++.

Простые и демпфированные генераторы как классы MATLAB

Управляющие уравнения

Простой гармонический генератор имеет два параметра, массу m и коэффициент упругости k. Угловая частота генератора ω=km. Положение генератора x как функция времени t определяется:

x(t)=Asin(ωt+ϕ).

Амплитуда A и фазовой константы ϕ определяются начальным положением x0 и начальная скорость v0 простого генератора. В этом примере класс MATLAB simpleOscillator моделирует эту систему.

Демпфированный гармонический генератор имеет один дополнительный параметр, константу демпфирования b. Этот пример рассматривает случай, когда нормированный параметр демпфирования γ=b2m является маленьким по сравнению с угловой частотой ω таким образом, существенными являются только эффекты демпфирования первого порядка. Положение демпфированного генератора xd как функция времени t является:

xd(t)=Ae-γtsin(ωt+ϕd)

Как и прежде, амплитуда A и фазовой константы ϕd определяются начальным положением x0 и начальная скорость v0 демпфированного генератора. Основной эффект демпфирования состоит в том, чтобы заставить амплитуду распадаться экспоненциально. В этом примере класс MATLAB dampedOscillator который является подклассом simpleOscillator моделирует демпфированную систему.

Файлы MATLAB и C++

Этот пример использует эти вспомогательные файлы, которые присутствуют в текущей рабочей директории:

  • Папка пакета +mySystem содержит два файла классов simpleOscillator.m и dampedOscillator.m.

  • Функция effectOfDamping вычисляет и возвращает траектории простого генератора и демпфированного генератора с заданными параметрами и начальными условиями.

  • Заголовок C++ и исходные файлы main_damped_oscillator.h и main_damped_oscillator.cpp реализуйте пользовательскую основную функцию C++ и используются для генерации исполняемого файла в последней части примера.

Запуск кода MATLAB

Задайте структуру params который имеет поля для трех параметров генератора. Убедитесь, что dampingConstant параметр мал по сравнению с springConstant и mass (в нормированных модулях).

params.springConstant = 1;
params.dampingConstant = 0.1;
params.mass = 1;

Вызовите effectOfDamping функция для вычисления положения и временных траекторий простых и демпфированных генераторов t=0 кому t=100. Задайте начальное положение x0=1и начальная скорость v0=0.

[time1,position1,time2,position2] = effectOfDamping(params,1,0,100,0.01);

Постройте график положения по сравнению с графиками времени простых и демпфированных генераторов. Наблюдайте, как амплитуда демпфированного генератора падает экспоненциально со временем.

plot(time1,position1)
hold on
plot(time2,position2)

Figure contains an axes. The axes contains 2 objects of type line.

Отобразите окончательное положение простого генератора.

disp(position1(end))
    0.8623

Отобразите окончательное положение демпфированного генератора. Заметьте, что демпфирование приводит к тому, что это окончательное положение близко к среднему положению xmean=0.

disp(position2(end))
    0.0056

Сгенерируйте и запустите C++ MEX

Чтобы проверить проблемы во время выполнения, сгенерируйте функцию C++ MEX для effectOfDamping функция. Укажите первый аргумент, имеющий тот же тип и размер params. Задайте другие аргументы, которые будут скалярными двойными.

codegen -lang:c++ effectOfDamping -args {params,0,0,0,0} -report
Code generation successful: To view the report, open('codegen/mex/effectOfDamping/html/report.mldatx').

Вызовите сгенерированную MEX-функцию effectOfDamping_mex вычислить положение и временные траектории простых и демпфированных генераторов t=0 кому t=100. Задайте начальное положение x0=1и начальная скорость v0=0.

[time1,position1,time2,position2] = effectOfDamping_mex(params,1,0,100,0.01);

Постройте график положения по сравнению с графиками времени простых и демпфированных генераторов. Заметьте, что график идентичен графику, произведенному исходной функцией MATLAB.

plot(time1,position1)
hold on
plot(time2,position2)

Figure contains an axes. The axes contains 4 objects of type line.

Отображение конечных положений двух генераторов. Эти значения также идентичны значениям, произведенным оригинальным кодом MATLAB.

disp(position1(end))
    0.8623
disp(position2(end))
    0.0056

Очистите файл MEX из памяти.

clear effectOfDamping_mex

Сгенерируйте и смотрите статическую библиотеку C++

Создайте объект строения кода для генерации статической библиотеки C++ с интерфейсом класса. Укажите имя класса интерфейса, который будет 'myOscillators'. Для этих настроек генератор кода производит функцию точки входа как метод класса C++ myOscillators'. Конструктор и деструктор этого класса интерфейса реализуют функции инициализации и завершения, соответственно.

cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = 'myOscillators';

Настройте глобальные настройки для инкрустации функции так:

  • Сохраните модульность в коде, который вы написали для лучшей читаемости. Задайте InlineBetweenUserFunctions на 'Readability'.

  • Сгенерируйте высоко оптимизированный код для функций MathWorks ®, даже если это приводит к менее читаемому коду, потому что вы с меньшей вероятностью смотрите эту часть своей основы кода. Задайте InlineBetweenMathWorksFunctions на 'Speed'.

  • В сгенерированном коде функционируют отдельные функции, которые вы записываете, и MathWorks так, чтобы сгенерированный код не выглядел сильно отличным от вашего кода MATLAB. Задайте InlineBetweenUserAndMathWorksFunctions на 'Readability'.

cfg.InlineBetweenUserFunctions = 'Readability'; 
cfg.InlineBetweenUserAndMathWorksFunctions = 'Readability';
cfg.InlineBetweenMathWorksFunctions = 'Speed';

Для получения дополнительной информации об управлении поведением встраивания функции генератора кода, смотрите Control Inlining to Fine-Tune Performance и Readibility of Сгенерированный Код.

Сгенерируйте статическую библиотеку C++ при помощи codegen команда.

codegen -config cfg effectOfDamping -args {params,0,0,0,0} -report
Code generation successful: To view the report, open('codegen/lib/effectOfDamping/html/report.mldatx').

Откройте отчет генерации кода и проверьте сгенерированный исходный код C++:

  • Файлы simpleOscillator.h и simpleOscillator.cpp содержат реализацию класса C++ для простого генератора. Файлы dampedOscillator.h и dampedOscillator.cpp содержат реализацию класса C++ для демпфированного генератора. Структура наследования классов MATLAB уплощена в сгенерированном коде. Итак, dampedOscillator не является подклассом simpleOscillator и повторяет все методы, которые наследует соответствующий класс MATLAB. Дополнительные сведения о отображении классов MATLAB и классов C++ см. в разделе Генерация классов C++ для классов MATLAB.

  • Пакет MATLAB сопоставлен с пространством имен C++. В сгенерированном коде simpleOscillator и dampedOscillator классы определены в mySystem пространство имен. Для получения дополнительной информации смотрите Организовать сгенерированный код С++ в пространства имен.

  • Файлы myOscillators.h и myOscillators.cpp содержат реализацию класса интерфейса myOscillators. Функция точки входа реализована в методе myOscillators::effectOfDamping. Функции инициализации и завершения реализованы в конструкторе классов и деструкторе классов, соответственно. В следующей части этого примера показано, как использовать этот интерфейс класса в пользовательской основной функции C++. Для получения дополнительной информации смотрите Сгенерировать код С++ с интерфейсом класса.

  • Размер выходных аргументов effectOfDamping функция определяется входами во время выполнения timeInterval и timeStep. Итак, сгенерированный код представляет эти аргументы как динамические массивы C++, которые реализованы при помощи coder::array шаблон класса. Следующая часть этого примера показывает, как использовать coder::array шаблон класса в пользовательской основной функции C++. Для получения дополнительной информации смотрите Использование динамически выделенных массивов C++ в Сгенерированных интерфейсах функции.

Для примера вот объявление сгенерированного mySystem::simpleOscillator класс, содержащийся в заголовочном файле simpleOscillator.h.

type codegen/lib/effectOfDamping/simpleOscillator.h
//
// File: simpleOscillator.h
//
// MATLAB Coder version            : 5.2
// C/C++ source code generated on  : 21-Apr-2021 01:24:07
//

#ifndef SIMPLEOSCILLATOR_H
#define SIMPLEOSCILLATOR_H

// Include Files
#include "rtwtypes.h"
#include "coder_array.h"
#include <cstddef>
#include <cstdlib>

// Type Definitions
namespace mySystem {
class simpleOscillator {
public:
  void init(double m, double k);
  void evolution(double initialPosition, double initialVelocity,
                 double timeInterval, double timeStep,
                 coder::array<double, 1U> &b_time,
                 coder::array<double, 1U> &position) const;
  double dynamics(double initialPosition, double initialVelocity,
                  double timeInterval) const;
  double amplitude(double initialPosition, double initialVelocity) const;
  double angularFrequency() const;
  double phase(double initialPosition, double initialVelocity) const;

protected:
  double mass;
  double springConstant;
};

} // namespace mySystem

#endif
//
// File trailer for simpleOscillator.h
//
// [EOF]
//

Если у вас есть Embedded Coder ®, можно задать VerificationMode свойство объекта строения, чтобы 'SIL' и сгенерируйте функцию SIL MEX effectOfDamping_sil. Этот интерфейс SIL позволяет вам проверить готовый исходный код в среде MATLAB. Смотрите Выполнение Software-in-the-Loop из командной строки (Embedded Coder).

Сгенерируйте и запустите исполняемый файл

В предыдущей части этого примера, когда вы генерируете код библиотеки, генератор кода также производит примеры основных файлов main.h и main.cpp в examples подпапка папки сборки. Поддерживающие файлы C++ main_damped_oscillator.h и main_damped_oscillator.cpp являются измененными версиями этих файлов примера.

  • В main_damped_oscillator.cpp, а main функция использует класс интерфейса myOscillators для взаимодействия с сгенерированным кодом. Эта функция использует new C++ оператор, чтобы выделить память для образца myOscillators, вызывает main_effectOfDamping функция, и, наконец, освобождает память при помощи delete C++ оператор.

  • The main_effectOfDamping функция выполняет те же расчеты, что и скрипт MATLAB в первой части этого примера. Он использует coder::array API для взаимодействия с динамическими массивами, которые effectOfDamping сгенерированные возврат функции. В конце своего выполнения main_effectOfDamping функция печатает окончательные положения двух генераторов.

Создайте объект строения кода для генерации исполняемого файла C++. Используйте те же настройки, что и в предыдущей части этого примера.

cfg = coder.config('exe');
cfg.TargetLang = 'C++';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = 'myOscillators';

cfg.InlineBetweenUserFunctions = 'Readability'; 
cfg.InlineBetweenUserAndMathWorksFunctions = 'Readability';
cfg.InlineBetweenMathWorksFunctions = 'Speed';

Укажите пользовательский исходный файл C++ и пользовательскую папку включения.

cfg.CustomSource = 'main_damped_oscillator.cpp';
cfg.CustomInclude = pwd;

Сгенерируйте исполняемый файл при помощи codegen команда.

codegen -config cfg main_damped_oscillator.cpp main_damped_oscillator.h effectOfDamping -args {params,0,0,0,0} -report
Code generation successful: To view the report, open('codegen/exe/effectOfDamping/html/report.mldatx').

Запустите сгенерированный исполняемый файл. Заметьте, что окончательные положения двух генераторов, которые это выполнение возвращает, совпадают с выходами оригинального кода MATLAB.

if isunix
    system('./effectOfDamping')
elseif ispc
    system('effectOfDamping.exe')
else
    disp('Platform is not supported')
end
0.862319
0.00563263
ans = 0

См. также

|

Похожие темы