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

Требования к использованию оптимизации читаемости

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

Примечание

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

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

Преобразование кода if-Elseif-Else в операторы Switch-Case

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

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

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

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

Преобразование кода if-Elseif-Else в операторы Switch-Case

Следующая процедура описывает, как преобразовать сгенерированный код для блока 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 в операторы Switch-Case

Предположим, что у вас есть следующая модель с 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.

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

Проверьте, что блок соответствует всем правилам в Rules for Conversion.

КонструкцияКак конструкция следует правилам
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. Откройте диалоговое окно Параметры конфигурации.

  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;
}

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

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

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

Похожие примеры

Подробнее о