Улучшите удобочитаемость кода для блоков MATLAB function

Требования для Использования оптимизации удобочитаемости

Чтобы использовать оптимизацию удобочитаемости в вашем коде, у вас должна быть лицензия Embedded Coder®. Эта оптимизация появляется только в коде, который вы генерируете для встроенного в реальном времени (ert) цель.

Примечание

Эта оптимизация не применяется к файлам MATLAB®, которые вы вызываете от блока MATLAB Function.

Для получения дополнительной информации смотрите, Конфигурируют Системный Конечный файл (Embedded Coder) и Параметры конфигурации Модели: Стиль кода (Embedded Coder).

Преобразование кода If-Elseif-Else к операторам case оператора switch

Когда вы генерируете код для встроенных целей в реальном времени, можно принять решение преобразовать if-elseif-else логика решения к switch-case операторы. Это преобразование может улучшить удобочитаемость кода.

Например, когда блок MATLAB Function содержит длинный список условий, switch-case структура:

  • Уменьшает использование круглых скобок и фигурных скобок

  • Минимизирует повторение в сгенерированном коде

Как преобразовать код If-Elseif-Else в операторов case оператора switch

Следующая процедура описывает, как преобразовать сгенерированный код для блока MATLAB Function из if-elseif-else к switch-case операторы.

ШагЗадачаСсылка
1

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

Проверка содержимого блока
2

Включите преобразование.

Включение преобразования
3

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

Генерация кода для модели

Правила для преобразования

Для преобразования, чтобы произойти, следующие правила должны содержать. LHS и RHS относятся к левой стороне и правой стороне условия, соответственно.

СоздатьПравила следовать
Блок MATLAB Function

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

Для получения дополнительной информации смотрите Как Условия Копии Указателей Преобразования.

Каждое условие

Должен протестировать равенство только.

Должен использовать ту же переменную или выражение для LHS.

Примечание

Можно инвертировать LHS и RHS.

Каждый LHS

Должна быть одна переменная или выражение, не составной оператор.

Не может быть константа.

Должен иметь целое число или перечисленный тип данных.

Не может иметь никаких побочных эффектов на симуляции.

Например, LHS может читать из, но не записать в глобальные переменные.

Каждый RHS

Должна быть константа.

Должен иметь целое число или перечисленный тип данных.

Как условия копии указателей преобразования

Если блок MATLAB Function имеет дублирующиеся условия, преобразование сохраняет только первое условие. Сгенерированный код отбрасывает все другие экземпляры дублирующихся условий.

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

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

Пример сгенерированного кодаКод после преобразования
if (x == 1) {
    block1
} else if (x == 2) {
    block2
} else if (x == 1) {  // duplicate
    block3
} else if (x == 3) {
    block4
} else if (x == 1) {  // duplicate
    block5
} else {
    block6
}
switch (x) {
    case 1:  
     block1; break;
    case 2:  
     block2; break;
    case 3:  
     block4; break;
    default: 
     block6; break;
}
if (x == 1) {
    block1
} else if (x == 1) {  // duplicate
    block2
} else {
    block3
}

Никакое изменение, потому что только одно уникальное условие существует

Пример преобразования кода для логики решения If-Elseif-Else к операторам case оператора switch

Предположим, что у вас есть следующая модель с блоком MATLAB Function. Примите, что типом выходных данных является double и типом входных данных является Controller, перечислимый тип, который вы задаете. (Для получения дополнительной информации смотрите Генерацию кода для Перечислений.)

Блок содержит следующий код:

function system = fcn(type)
%#codegen

if (type == Controller.P)
    system = 0;
elseif (type == Controller.I)
    system = 1;
elseif (type == Controller.PD)
    system = 2; 
elseif (type == Controller.PI)
    system = 3;
elseif (type == Controller.PID)
    system = 4;
else 
    system = 10;
end

Определение перечислимого типа в Controller.m :

classdef Controller < Simulink.IntEnumType
  enumeration
    P(0)
    I(1)
    PD(2)
    PI(3)
    PID(4)
    UNKNOWN(10)
  end
end

Если вы генерируете код для встроенной цели в реальном времени с помощью настроек по умолчанию, вы видите что-то вроде этого:

if (if_to_switch_eml_blocks_U.In1 == P) {
  /* '<S1>:1:4' */
  /* '<S1>:1:5' */
  if_to_switch_eml_blocks_Y.Out1 = 0.0;
} else if (if_to_switch_eml_blocks_U.In1 == I) {
  /* '<S1>:1:6' */
  /* '<S1>:1:7' */
  if_to_switch_eml_blocks_Y.Out1 = 1.0;
} else if (if_to_switch_eml_blocks_U.In1 == PD) {
  /* '<S1>:1:8' */
  /* '<S1>:1:9' */
  if_to_switch_eml_blocks_Y.Out1 = 2.0;
} else if (if_to_switch_eml_blocks_U.In1 == PI) {
  /* '<S1>:1:10' */
  /* '<S1>:1:11' */
  if_to_switch_eml_blocks_Y.Out1 = 3.0;
} else if (if_to_switch_eml_blocks_U.In1 == PID) {
  /* '<S1>:1:12' */
  /* '<S1>:1:13' */
  if_to_switch_eml_blocks_Y.Out1 = 4.0;
} else {
  /* '<S1>:1:15' */
  if_to_switch_eml_blocks_Y.Out1 = 10.0;
}

Переменная LHS if_to_switch_eml_blocks_U.In1 появляется многократно в сгенерированном коде.

Примечание

По умолчанию переменные, которые появляются в блоке, не сохраняют свои имена в сгенерированном коде. Модифицированные идентификаторы гарантируют, что никакие конфликты по совпадению имен не происходят.

Комментарии трассируемости появляются между каждым набором /* и */ маркеры. Чтобы узнать больше о трассируемости, смотрите Трассируемость Использования в блоках MATLAB function.

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

Проверяйте, что блок следует всем правилам в Правилах для Преобразования.

СоздатьКак построение следует правилам
Блок MATLAB Function

Пять уникальных условий существуют, в дополнение к значению по умолчанию:

  • (type == Controller.P)

  • (type == Controller.I)

  • (type == Controller.PD)

  • (type == Controller.PI)

  • (type == Controller.PID)

Каждое условие

Каждое условие:

  • Тестовое равенство

  • Использует тот же вход для LHS

Каждый LHS

Каждый LHS:

  • Содержит одну переменную

  • Вход с блоком и поэтому не константой

  • Имеет перечислимый тип Controller, который вы задаете в Controller.m на пути MATLAB

  • Не имеет никаких побочных эффектов на симуляции

Каждый RHS

Каждый RHS:

  • Перечисляемое значение и поэтому константа

  • Имеет перечислимый тип Controller

Включение преобразования

  1. Откройте диалоговое окно Configuration Parameters.

  2. В панели Code Generation выберите ert.tlc для System target file.

    Этот шаг задает встроенную цель в реальном времени для вашей модели.

  3. В Code Generation> панель Code Style, установите флажок Convert if-elseif-else patterns to switch-case statements.

    Совет

    Это преобразование работает над на базис модели. Если вы устанавливаете этот флажок, преобразование применяется:

    • Весь MATLAB Function блокируется в модели

    • Функции MATLAB во всех графиках Stateflow® той модели

    • Блок-схемы во всех диаграммах Stateflow той модели

    Для получения дополнительной информации смотрите, Улучшают Удобочитаемость Кода для Блок-схем (Embedded Coder).

Генерация кода для модели

В окне модели нажмите Ctrl+B.

Код для блока MATLAB Function использует switch-case операторы вместо if-elseif-else код:

switch (if_to_switch_eml_blocks_U.In1) {
 case P:
  /* '<S1>:1:4' */
  /* '<S1>:1:5' */
  if_to_switch_eml_blocks_Y.Out1 = 0.0;
  break;

 case I:
  /* '<S1>:1:6' */
  /* '<S1>:1:7' */
  if_to_switch_eml_blocks_Y.Out1 = 1.0;
  break;

 case PD:
  /* '<S1>:1:8' */
  /* '<S1>:1:9' */
  if_to_switch_eml_blocks_Y.Out1 = 2.0;
  break;

 case PI:
  /* '<S1>:1:10' */
  /* '<S1>:1:11' */
  if_to_switch_eml_blocks_Y.Out1 = 3.0;
  break;

 case PID:
  /* '<S1>:1:12' */
  /* '<S1>:1:13' */
  if_to_switch_eml_blocks_Y.Out1 = 4.0;
  break;

 default:
  /* '<S1>:1:15' */
  if_to_switch_eml_blocks_Y.Out1 = 10.0;
  break;
}

switch-case операторы предоставляют следующие преимущества, чтобы улучшить удобочитаемость:

  • Код уменьшает использование круглых скобок и фигурных скобок.

  • Переменная LHS if_to_switch_eml_blocks_U.In1 появляется только однажды, минимизируя повторение в коде.

Связанные примеры

Больше о