Реализуйте варианты размерности для размеров массивов в сгенерированном коде

Варианты размерности

Используйте символические размерности, чтобы симулировать различные наборы вариантов размеров, не регенерируя код для каждого набора. Настройте модель с размерностями, которые вы задаете как символы в блоках и объектах данных. Эти символы распространяются по всей модели во время симуляции, а затем переходят в сгенерированный код. Ограничения моделирования для символов во время симуляции (для примера, C=A+B) выход как предварительные условия процессора в model.h или model _types.h файл.

Можно непосредственно задать информацию о размерности в качестве символа или числовой константы для этих блоков и объектов данных:

  • Inport

  • Вспомогательный порт

  • Спецификация сигнала

  • Память хранилища данных

  • Интерпретированная функция MATLAB

  • Simulink.Signal

  • Simulink.Parameter

  • Simulink.BusElement

  • AUTOSAR.Parameter

Блоки Data Store Memory и Interpreted MATLAB Function также поддерживают переменные сигналы размерности. Для этих блоков символические размерности управляют максимально допустимым размером.

Необходимо предоставить код инициализации для Simulink.Parameter объекты, которые содержат символические размерности. Чтобы предотвратить инициализацию этих параметров сгенерированным кодом, вы должны либо:

  • Сконфигурируйте параметры для использования класса памяти с Данными возможностей набора свойств для Imported, таких как ImportedExtern или ImportedExternPointer встроенные классы памяти.

  • Сконфигурируйте параметры, чтобы использовать класс памяти с Данными набора свойств инициализации, чтобы None.

Вы используете Simulink.Parameter объекты для задания информации о размерностях в качестве символов. Для получения дополнительной информации о размерах сигнала размерности Раздел «Определение размерностей сигнала».

Вы должны исправить символические значения размерности во время компиляции. Вы не можете разрешить символьную размерность другой переменной, а затем изменить его во время выполнения, потому что вы задаете поведение во время симуляции.

Примечание. По умолчанию размерность варианты функции. Можно выключить эту функцию, очистив параметр Разрешить спецификацию символьных размеров в диалоговом окне Параметры конфигурации (Configuration Parameters).

Задайте символьные размерности

Этот пример использует модель rtwdemo_dimension_variants чтобы показать, как реализовать символьные размерности. Эта модель имеет четыре шаблона моделирования с участием векторов и матриц.

  1. Чтобы показать имена блоков, на вкладке Debug, в меню Information Overlays, очистите параметр Hide Automatic Block Names.

  2. Откройте приложение Embedded Coder. На вкладке Код С выберите Code Interface > Individual Element Code Mappings.

  3. В редакторе Отображения на вкладке Parameters нажмите кнопку обновления. Семь Simulink.Parameter появляются объекты. Четыре из этих объектов предназначены для определения символьных размерностей. Эти Simulink.Parameter объекты имеют имена A, B, C, и D. Заметьте, что эти параметры имеют класс памяти CompilerFlag.

Как использовать Simulink.Parameter объект для спецификации размерности, он должен быть определен в базовом рабочем пространстве и иметь один из следующих классов памяти:

  • Define или ImportedDefine с заданным файлом заголовка

  • CompilerFlag

  • Пользовательский пользовательский класс памяти, который определяет данные как макрос в указанном заголовочном файле

Для Simulink.Parameter объекты со ImportedDefine пользовательский класс памяти, укажите файл заголовка в пути MATLAB. Вставьте имя файла заголовка в поле HeaderFile в Simulink. Параметр диалоговое окно.

Для задания символьных размерностей можно использовать выражения MATLAB. Список поддерживаемых выражений MATLAB см. в разделе «Операторы и операторы в выражениях исполнительных условий» в разделе «Введение в элементы управления исполнениями».

Задайте символические размерности для блоков и объектов данных

  1. Нажмите Inport Block In2. В Property Inspector, на вкладке Parameters, поле Port Dimensions содержит Simulink.Parameter A объекта. Для блоков Inport задаются символические размерности в поле Port Dimensions.

  2. Нажмите Inport block In3. Поле Port Dimensions содержит Simulink.Parameter B объекта.

  3. Щелкните блок Константа (Constant). Параметр Constant value имеет значение Data. В редакторе Отображения, на вкладке Parameters, нажмите Simulink.Parameter Data объекта. В Property Inspector поле Dimension имеет вектор символов '[1,C]' , что эквивалентно '[1,5]' потому что C имеет значение 5. Поле Value содержит массив с 5 значений, что соответствует его размерностям. Размерности объекта данных должны соответствовать значению Simulink.Parameter объект, находящийся в поле Dimensions. Заметьте, что Data имеет Класс памяти ImportedExtern.

  4. Откройте 1-D Lookup Table1 диалоговое окно параметров блоков. Поле данные содержит Simulink.Parameter, PT. Поле Breakpoints 1 содержит Simulink.Parameter, PB.

  5. В редакторе Отображения нажмите PB и PT и просматривать их свойства. Эти параметры содержат вектор символов '[1,D]' в своем поле Dimensions и являются массивами, состоящими из 15 значений. Значение D согласуется с размерностью PB и PT параметры из-за D имеет значение 15 .

  6. Симулируйте модель. Simulink распространяет размерности символически в схеме. Во время распространения Simulink устанавливает ограничения моделирования среди символов. Затем Simulink проверяет согласованность с этими ограничениями на основе текущих числовых назначений. Одно ограничение моделирования для rtwdemo_dimension_variants является ли это C=A+B. Diagnostic Viewer выдает предупреждение о любых нарушениях ограничений.

  7. Измените спецификацию размерности на другое строение и снова симулируйте модель.

Хотя в этом примере не показано, можно задать n-D размерности выражение с одним или несколькими размерностей, являющимися символом (например '[A,B,C]' или '[1,A,3]').

Сгенерируйте код для модели с вариантами размерности

После того, как вы проверили спецификации размерности посредством симуляции модели, сгенерируйте код для rtwdemo_dimension_variants.

Создайте временную папку для процесса сборки и проверки.

currentDir = pwd;
[~,cgDir] = rtwdemodir();

Создайте модель.

model='rtwdemo_dimension_variants';
slbuild(model)
### Starting build procedure for: rtwdemo_dimension_variants
### Successful completion of build procedure for: rtwdemo_dimension_variants

Build Summary

Top model targets built:

Model                       Action                       Rebuild Reason                                    
===========================================================================================================
rtwdemo_dimension_variants  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 15.38s

Просмотрите сгенерированный код. В rtwdemo_dimension_variants.h файл, символические размерности указаны в объявлениях данных.

hfile = fullfile(cgDir,'rtwdemo_dimension_variants_ert_rtw',...
    'rtwdemo_dimension_variants.h');
rtwdemodbtype(hfile,'/* External inputs', '/* Real-time', 1, 0);
/* External inputs (root inport signals with default storage) */
typedef struct {
  real_T In2[A];                       /* '<Root>/In2' */
  real_T In3[B];                       /* '<Root>/In3' */
} ExtU;

/* External outputs (root outports fed by signals with default storage) */
typedef struct {
  real_T Out1[(A + B)];                /* '<Root>/Out1' */
  real_T Out2[(A + B)];                /* '<Root>/Out2' */
} ExtY;

The rtwdemo_dimension_variants.h файл содержит определения данных и предварительные условия процессора, которые задают ограничения, установленные среди символов во время симуляции. Одно из этих ограничений заключается в том, что значение символьной размерности должно быть больше 1. Этот файл также включает пользовательский файл заголовка для любой Simulink.Parameter объекты со ImportedDefine пользовательский класс памяти.

hfile = fullfile(cgDir,'rtwdemo_dimension_variants_ert_rtw',...
    'rtwdemo_dimension_variants.h');
rtwdemodbtype(hfile,'#ifndef A', '/* Macros for accessing', 1, 0);
#ifndef A
#error The variable for the parameter "A" is not defined
#endif

#ifndef B
#error The variable for the parameter "B" is not defined
#endif

#ifndef C
#error The variable for the parameter "C" is not defined
#endif

#ifndef D
#error The variable for the parameter "D" is not defined
#endif

/*
 * Constraints for division operations in dimension variants
 */
#if (1 == 0) || (((A+B) % 1) != 0)
# error "The preprocessor definition '1' must not be equal to zero and     the division of '(A+B)' by '1' must not have a remainder."
#endif

/*
 * Registered constraints for dimension variants
 */
/* Constraint 'C == (A+B)' registered by:
 * '<Root>/1-D Lookup Table1'
 */
#if C != (A+B)
# error "The preprocessor definition 'C' must be equal to '(A+B)'"
#endif

#if A <= 1
# error "The preprocessor definition 'A' must be greater than '1'"
#endif

#if B <= 1
# error "The preprocessor definition 'B' must be greater than '1'"
#endif

/* Constraint 'D > 1' registered by:
 * '<Root>/1-D Lookup Table1'
 */
#if D <= 1
# error "The preprocessor definition 'D' must be greater than '1'"
#endif

/* Constraint 'C > 3' registered by:
 * '<S2>/Assignment'
 */
#if C <= 3
# error "The preprocessor definition 'C' must be greater than '3'"
#endif

#if (A+B) <= 3
# error "The preprocessor definition '(A+B)' must be greater than '3'"
#endif

#if (A-1) <= 0
# error "The preprocessor definition '(A-1)' must be greater than '0'"
#endif

#if (A+B-1) <= 2
# error "The preprocessor definition '(A+B-1)' must be greater than '2'"
#endif

#if (D-1) <= 0
# error "The preprocessor definition '(D-1)' must be greater than '0'"
#endif

#if A >= 11
# error "The preprocessor definition 'A' must be less than '11'"
#endif

#if B >= 11
# error "The preprocessor definition 'B' must be less than '11'"
#endif

/* Constraint 'D < 21' registered by:
 * '<Root>/1-D Lookup Table1'
 */
#if D >= 21
# error "The preprocessor definition 'D' must be less than '21'"
#endif

/* Constraint 'C < 11' registered by:
 * '<S2>/Assignment'
 */
#if C >= 11
# error "The preprocessor definition 'C' must be less than '11'"
#endif

#if (A+B) >= 21
# error "The preprocessor definition '(A+B)' must be less than '21'"
#endif

#if (A-1) >= 10
# error "The preprocessor definition '(A-1)' must be less than '10'"
#endif

#if (A+B-1) >= 10
# error "The preprocessor definition '(A+B-1)' must be less than '10'"
#endif

#if (D-1) >= 20
# error "The preprocessor definition '(D-1)' must be less than '20'"
#endif

В rtwdemo_dimension_variants.c файл, символьные размерности участвуют в цикле вычислениях, вычислениях размера массива и смещения индекса, и параметризованной служебной функции (для примера, блок Интерполяционной таблицы) вычислении.

cfile = fullfile(cgDir,'rtwdemo_dimension_variants_ert_rtw',...
    'rtwdemo_dimension_variants.c');
rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_dimension_variants_step(void)
{
  real_T rtb_VectorConcatenate[A + B];
  real_T rtb_VectorConcatenate_m;
  int32_T ForEach_itr;
  int32_T i;
  int32_T s2_iter;

  /* Gain: '<Root>/Gain' incorporates:
   *  Inport: '<Root>/In2'
   */
  for (ForEach_itr = 0; ForEach_itr <= (int32_T)(A - 1); ForEach_itr++) {
    rtb_VectorConcatenate[ForEach_itr] = 2.0 * rtU.In2[ForEach_itr];
  }

  /* End of Gain: '<Root>/Gain' */

  /* Gain: '<Root>/Gain1' incorporates:
   *  Inport: '<Root>/In3'
   */
  for (ForEach_itr = 0; ForEach_itr <= (int32_T)(B - 1); ForEach_itr++) {
    rtb_VectorConcatenate[(int32_T)(A + ForEach_itr)] = 3.0 *
      rtU.In3[ForEach_itr];
  }

  /* End of Gain: '<Root>/Gain1' */

  /* Outputs for Iterator SubSystem: '<Root>/For Each Subsystem' incorporates:
   *  ForEach: '<S1>/For Each'
   */
  for (ForEach_itr = 0; ForEach_itr <= (int32_T)((int32_T)(A + B) - 1);
       ForEach_itr++) {
    /* Sum: '<Root>/Add' incorporates:
     *  Constant: '<Root>/Constant'
     *  Lookup_n-D: '<Root>/1-D Lookup Table1'
     */
    rtb_VectorConcatenate_m = rtb_VectorConcatenate[ForEach_itr] + look1_binlx
      (Data[ForEach_itr], PB, PT, (uint32_T)((uint32_T)D - 1U));

    /* ForEachSliceAssignment generated from: '<S1>/Out1' incorporates:
     *  MATLAB Function: '<S1>/MATLAB Function'
     */
    /* MATLAB Function 'For Each Subsystem/MATLAB Function': '<S3>:1' */
    /* '<S3>:1:4' y = 2*u; */
    rtY.Out1[ForEach_itr] = 2.0 * rtb_VectorConcatenate_m;

    /* Sum: '<Root>/Add' */
    rtb_VectorConcatenate[ForEach_itr] = rtb_VectorConcatenate_m;
  }

  /* End of Outputs for SubSystem: '<Root>/For Each Subsystem' */

  /* Outputs for Iterator SubSystem: '<Root>/For Iterator Subsystem' incorporates:
   *  ForIterator: '<S2>/For Iterator'
   */
  /* Constant: '<Root>/Constant1' */
  ForEach_itr = ((int32_T)A);
  if (((int32_T)A) < 0) {
    ForEach_itr = 0;
  }

  /* End of Constant: '<Root>/Constant1' */
  for (s2_iter = 0; s2_iter < ForEach_itr; s2_iter++) {
    /* Assignment: '<S2>/Assignment' incorporates:
     *  Constant: '<S2>/Constant'
     *  Outport: '<Root>/Out2'
     *  Product: '<S2>/Product'
     *  Selector: '<S2>/Selector'
     */
    if (s2_iter == 0) {
      for (i = 0; i <= (int32_T)((int32_T)(A + B) - 1); i++) {
        rtY.Out2[i] = rtb_VectorConcatenate[i];
      }
    }

    rtY.Out2[s2_iter] = rtb_VectorConcatenate[s2_iter] * 2.0;

    /* End of Assignment: '<S2>/Assignment' */
  }

  /* End of Outputs for SubSystem: '<Root>/For Iterator Subsystem' */
}

Закройте модель и отчет о генерации кода.

bdclose(model)
rtwdemoclean;
cd(currentDir)

Установите значение параметров на основе варианта выбора

Когда вы задаете размерности параметра в модели с помощью символа, необходимо убедиться, что значение параметров соответствует значению размерности. Чтобы симулировать различные варианты значения размерности, необходимо вручную исправить значение параметров.

Для примера, в rtwdemo_dimension_variants модель, Simulink.Parameter Data объекта сохраняет значение вектора, [1 2 3 4 5], и использует символьную размерность C с начальным значением 5. Если вы меняете значение C, чтобы симулировать модель, необходимо убедиться, что количество элементов в вектор значении совпадает с новым значением C.

Чтобы уменьшить усилия обслуживания, когда вы изменяете значение C, можно задать значение Data к выражению, включающему C.

  1. Откройте модель.

    rtwdemo_dimension_variants

  2. В командной строке проверьте начальные значения Data и C. Значение Data является вектором целых чисел из 1 на C.

    Data.Value
    
    ans =
    
         1     2     3     4     5
    C.Value
    ans =
    
         5

  3. В MATLAB® синтаксис кода, значение Data является 1:C. Чтобы сохранить эту связь между объектами параметра, задайте значение Data при помощи slexpr функция.

    Data.Value = slexpr('1:C');

  4. Чтобы предотвратить ошибки распространения типа данных, установите тип данных Data явно для double, который является типом данных, полученным параметром перед установкой значения параметров на выражение.

    Data.DataType = 'double';

  5. Установите значение C на другое число, например 6. Из-за размерных ограничений в модели необходимо задать значение другого символа размерности A, в 3.

    C.Value = 6;
    A.Value = 3;

  6. Симулируйте модель. Схема блока показывает, что значение Data теперь имеет шесть элементов.

Для более сложных приложений можно написать свою собственную функцию MATLAB, которая возвращает значения параметров на основе размерности символов. Установите значение данных параметра в выражение, которое вызывает вашу функцию.

Общие сведения об использовании выражения для задания значения Simulink.Parameter объект, см. «Задать значение переменных при помощи математического выражения».

Факторы об оптимизации генерации кода

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

  • Генератор кода повторно использует буферы, только если распространение размерности устанавливает эквивалентность среди буферов.

  • Два цикла с символьными вычислениями, связанными с циклом, объединяются вместе, только если они имеют эквивалентное символьное выражение.

  • Оптимизация не устраняет символьное выражение или проверку условия, основанную на текущем значении символьной размерности.

Обратная совместимость

Если существующая модель использует Simulink.Parameter объекты для задания размеров могут быть несовместимы с вариантами размерностей. Вот два распространенных сценария:

  • Только подмножество блоков принимает символические спецификации размерности. Если блок не совместим с символьными размерностями, это вызывает ошибку схемы обновления.

  • Simulink.Parameter объекты, которые используются для определения символьных размерностей или имеют символьные размерности, должны иметь один из классов памяти, описанных в этом примере. Если эти спецификации не выполняются, процедура сборки для модели прекращает работать во время генерации кода.

Вы можете решить эти проблемы обратной совместимости, выполнив следующее:

  • Отключите функцию вариантов размерности путем очистки параметра Allow symbolic dimension specification в диалоговом окне Параметры конфигурации (Configuration Parameters).

  • Обновление Simulink.Parameter объекты, которые задают символьные размерности или имеют символьные спецификации размерностей.

  • Обновите модель так, чтобы только поддерживаемые блоки имели символические размерности или распространяли символьные размерности.

Поддерживаемые блоки

Список поддерживаемых блоков см. в Block Support Table. Для доступа к информации в этой таблице введите showblockdatatypetable в командной строке MATLAB. Неподдерживаемые блоки (для примера, MATLAB Function) все еще могут работать в модели, содержащей символические размерности, пока эти блоки не взаимодействуют непосредственно с символьными размерностями.

В следующих случаях поддерживаемые блоки не распространяют символьные размерности.

  • Для блоков Assignment и Selector установите параметр Block Parameters > Index Option равным Index vector (dialog). Для блоков Selector и Assignment, если вы задаете символическую размерность для параметра Index, генератор кода не воспринимает символическую размерность в сгенерированном коде.

  • Для блока Product вы задаете значение 1 для параметра Block Parameters > Number of inputs, и вы устанавливаете параметр Multiply over равным Specified dimensions.

  • Для ForEach блока задаётся символьная размерность для параметра Partition Width.

Обратите внимание, что следующие шаблоны моделирования являются одними из тех шаблонов моделирования, которые могут вызвать ошибку Simulink:

  • Для Switch блоков входной сигнал или параметр Threshold имеют символические размерности, и вы выбираете Allow different data input sizes (Results in variable-size output signal).

  • Блок Data Store Read выбирает элементы массива Simulink.Bus сигнал, имеющий символические размерности.

  • Для Lookup Table блоков на вкладке Block Parameters > Algorithm вы выбираете Use one input port for all input data параметра.

Ограничения

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

  • Замена кода для интерполяционных таблиц

  • Циклы (SIL) и Цикле (PIL)

  • Режимы симуляции Accelerator и rapid Accelerator

  • Возможности и наблюдение за симуляцией (для примера, логгирования, SDI и так далее)

  • Покрытие модели

  • Simulink Design Verifier

  • Fixed-Point Designer

  • Словарь данных

  • Simulink PLC Coder

  • HDL Coder

Следующие варианты размерности не поддерживаются:

  • Системный объект

  • Диаграммы Stateflow, которые используют MATLAB в качестве языка действий

  • Физическое моделирование

  • Дискретно-событийная симуляция

  • Системы координат

  • Функции MATLAB

Следующие ограничения также применяются к моделям, которые используют символические размерности.

  • Для симуляции размер символической размерности может равняться 1. Для генерации кода размер символической размерности должен быть больше 1.

  • Если символьная размерность является выражением MATLAB, которое содержит арифметическое выражение и реляционное или логическое выражение, необходимо добавить +0 после реляционной или логической части выражения MATLAB. Если вы не добавляете +0, ошибки модели во время симуляции, потому что вы не можете смешать boolean тип данных с целым числом или double типы данных. Добавление +0 преобразует тип данных реляционной или логической части выражения из boolean в double.

    Например, предположим, в диалоговом окне Inport параметры блоков, параметр Port dimensions имеет выражение [(C==8)*D+E,3]. Параметр Data type установлен в double. Начиная с C==8 является реляционным выражением, вы должны изменить выражение на [((C==8)+0)*D+E,3] чтобы предотвратить создание модели ошибки во время симуляции.

  • Simulink распространяет символические размерности для всей структуры или матрицы, но не для части структуры или матрицы. Для примера, Simulink.Parameter P является 2x3 матрица с символьными размерностями [Dim,Dim1].

    p=Simulink.Parameter(struct('A',[1 2 3;4 5 6]))
    p.DataType='Bus:bo'
    bo=Simulink.Bus
    bo.Elements(1).Name='A'
    bo.Elements(1).Dimensions='[Dim,Dim1]'
    Dim=Simulink.Parameter(2)
    Dim1=Simulink.Parameter(3)
    p.CoderInfo.StorageClass='Custom'
    p.CoderInfo.CustomStorageClass='Define'
    Dim.CoderInfo.StorageClass='Custom'
    Dim.CoderInfo.CustomStorageClass='Define'
    Dim1.CoderInfo.StorageClass='Custom'
    Dim1.CoderInfo.CustomStorageClass='Define'
    

    Если вы задаете p.A для параметра размерностей Simulink распространяет символические размерности [Dim,Dim1]. Если вы задаете p.A(1,:)Simulink распространяет числовую размерность 3 но не символическая размерность, Dim1.

  • Выражение MATLAB A(:) не поддерживает символическую информацию о размерности. Использование A вместо этого.

  • Выражение MATLAB P(2:A) не поддерживает символическую информацию о размерности. Вместо этого используйте блок Selector.

  • Выражение MATLAB P(2,:) не является настраиваемым выражением, поэтому не поддерживает символьную информацию о размерности.

  • Предположим, что вы задаете значение параметра маски, myMaskParam, при помощи поля структуры или при помощи подмножества структур в массиве структур. Структура или массив структур хранятся в Simulink.Parameter объект, чтобы вы могли использовать Simulink.Bus объект для применения символьных размерностей к полям колодца. Под маской вы конфигурируете параметры блоков, чтобы использовать одно из полей с символическими размерностями. Таблица показывает некоторые примеры случаев.

    ОписаниеЗначение параметра маски (myMaskParam)Значение параметров блоков
    myStruct - структура с полем gains, который использует символические размерности.myStruct.gainsmyMaskParam
    myStruct - структура с иерархией полей myStruct.subStruct.gains. Полевые gains использует символические размерности.myStruct.subStructmyMaskParam.gains
    myStructs - массив структур. Каждая структура имеет поле gains, который использует символические размерности.myStructs(2)myMaskParam.gains

    В этих случаях вы не можете сгенерировать код из модели. В качестве обходного пути выберите один из следующих методов:

    • Используйте всю структуру (myStruct) или массив структур (myStructs) как значение параметра маски. Под маской сконфигурируйте параметры блоков, чтобы отсчитать целевое поле из параметра маски с помощью выражения, такого как myMaskParam.subStruct.gains.

    • Используйте буквальные размерности вместо символических для целевого поля (gains).

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

Похожие темы