Используя режимы отображения с пользовательски сопоставленными внешними входными параметрами

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

Этот пример принимает, что вы знакомы с командой getRootInportMap и Корневым Инструментом Картопостроителя Inport пользовательская возможность отображения. Если вы не знакомы с теми концепциями, считайте документацию и рассмотрите примеры, которые принадлежат getRootInportMap и пользовательским отображениям.

Рабочий процесс

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

Этот пример использует список входных параметров с двумя видами сигналов:

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

  • Сигналы, которые не могут быть сопоставлены с помощью блока Simulink, называют режим отображения. Необходимо сопоставить эти сигналы с пользовательским режимом отображения.

Примите следующий сценарий:

  • Вы хотите использовать группу сигналов как входные параметры к вашей модели Simulink.

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

  • Каждый сигнал, который использует это соглашение о присвоении имен, в допуске.

  • Каждый сигнал, которому добавили 'x' символ к его имени, рассматривается внешним допуском.

Этот пример использует режим отображения, подобный методу отображения имени блока Simulink.

Имена блока импорта корневого уровня:

  • Дроссель

  • Тормоз

Имена переменной сигнала:

  • Throttlex

  • Тормоз

Чтобы сопоставить входные параметры с корневым уровнем импортируют блоки в этом сценарии, вам нужна пользовательская функция отображения для инструмента Root Inport Mapper. Этот пример использует AlmostBlockName пользовательская функция отображения.

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

Объявите пользовательскую функцию отображения

Объявите имя функции, входные параметры и выходные параметры. Для этого скопируйте и вставьте следующий фрагмент кода в файл MATLAB и сохраните файл как AlmostBlockName.m.

function inputMap = AlmostBlockName( modelName, signalNames, signals )

Получите отображение Simulink BlockName

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

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

inputMap = getRootInportMap('empty');
if ~bdIsLoaded(modelName)
   load_system(modelName);
end
[inputMap, hasASignal] = getSlRootInportMap('Model', modelName, ...
        'MappingMode','BlockName',...
        'signalName',signalNames, 'signalValue', signals);

Найдите Недостающие входные сигналы

На предыдущем шаге вы создали отображение с помощью режима отображения имени блока. Необходимо теперь объяснить пустой inputMap и для inputMap(s), которые не были сопоставлены с сигналом в допуске. Функциональный getSlRootInportMap отметил эти сигналы с помощью выходной переменной hasASignal. Для этого:

  1. Проверяйте переменную inputMap.

  2. Если переменная inputMap не пуста, определите, какие элементы вектора inputMap не были присвоены сигнал. Для этого используйте логический ~ на векторе hasASignal как показано ниже. Вектор emptyIndex теперь содержит логический вектор, где верный означает, что inputMap не сопоставили сигнал с ним.

  3. Скопируйте и вставьте следующий фрагмент кода под вызовом getSlRootInportMap и перед концом если bdIsLoaded(modelName).

if ~isempty(inputMap)
    emptyIndex = ~hasASignal;
end

Фрагмент кода выполняет шаги один и два для вас.

Завершите отображение

На предыдущем шаге вы создали логический векторный emptyIndex, чтобы видеть, не был ли какой-либо из объектов inputMap сопоставлен к сигналу. Если все элементы emptyIndex вектора являются ложными, у вас есть полное отображение, и код, добавленный в этом разделе, не будет выполнен.

Если вектор emptyIndex содержит по крайней мере одно значение, которое верно, у вас есть объекты inputMap, которые не сопоставлены к сигналу. Вручную присвойте переменный сигнал (сигналы) этому inputMap. Затем замените inputMap с именем сигнала, которое совпадает с ожидаемым именем сигнала:

  1. В emptyIndex векторе найдите все элементы, которые верны. Эти элементы указывают на inputMap(s), который все еще должен быть сопоставлен с сигналом.

  2. Для каждого inputMap используйте свойство 'BlockName' получить имя блока импорта, которому присвоен inputMap.

  3. Добавьте 'x' к имени блока, чтобы заставить имя сигнала быть присвоенным inputMap.

  4. Сравните результат с каждым элементом в signalNames переменном массиве ячеек.

  5. Если соответствие найдено, замените inputMap с именем сигнала, которое совпадает с ожидаемым именем сигнала. Чтобы заменить объект inputMap, используйте функцию getRootInportMap с 'InputMap' и свойствами 'SignalName'.

if isa( signals{1}, 'Simulink.SimulationData.Dataset')
    signalNames = signals{1}.getElementNames';
end
idxEmpty = find(emptyIndex==true);
for kEmpty =1:length(idxEmpty)
    idxOfEmpty = idxEmpty(kEmpty);
    destBlockName = get(inputMap(idxOfEmpty),'BlockName');
    outSideToleranceSig = [destBlockName 'x'];
    isAMatch = strcmp(signalNames, outSideToleranceSig);
    if any(isAMatch)
        inputMap(idxOfEmpty) = getRootInportMap('InputMap', ...
            inputMap(idxOfEmpty),'SignalName',outSideToleranceSig);
    end
end

Пользовательский файл карты

По окончании, файл, AlmostBlockName.m должен напомнить следующий код.

function inputMap = AlmostBlockName(modelName, signalNames, signals)
inputMap = getRootInportMap('empty');
if bdIsLoaded(modelName)
     [inputMap, hasASignal] = getSlRootInportMap('Model', modelName, ...
     'MappingMode','BlockName',...
     'signalName',signalNames, 'signalValue', signals);
     if ~isempty(inputMap)
        emptyIndex = ~hasASignal;
        idxEmpty = find(emptyIndex==1);
        if isa( signals{1}, 'Simulink.SimulationData.Dataset')
             signalNames = signals{1}.getElementNames';
        end
        for kEmpty =1:length(idxEmpty)
            idxOfEmpty = idxEmpty(kEmpty);
            destBlockName = get(inputMap(idxOfEmpty),'BlockName');
            nonNominalSig = [destBlockName 'x'];
            isAMatch = strcmp(signalNames, nonNominalSig);
            if any(isAMatch)
                inputMap(idxOfEmpty) = getRootInportMap('InputMap', ...
                    inputMap(idxOfEmpty),'SignalName',nonNominalSig);
            end
        end
     end
end

Подтвердите пользовательское отображение

Подтверждать ваше пользовательское отображение:

  1. Сохраните функцию AlmostBlockName в файле на пути MATLAB.

  2. Чтобы видеть результаты вашей функции отображения, скопируйте и вставьте следующий фрагмент кода к Окну Команды MATLAB.

modelName  = 'slexAutotransRootInportsExample';
Throttlex  = timeseries(zeros(10,1));
Brake      = timeseries(ones(10,1));
signalNames= {'Throttlex' ,'Brake'};
signals    = { Throttlex  , Brake };
open_system(modelName);
inputMap   = AlmostBlockName(modelName, signalNames, signals);
inputStr   = getInputString(inputMap,'base');
close_system(modelName);

После выполнения фрагмента кода переменная inputStr содержит строку 'Throttlex, Тормоз'.

Если ваши сигналы находятся в Simulink. SimulationData. Набор данных, чтобы видеть результаты вашей функции отображения, использует следующий фрагмент кода в Окне Команды MATLAB.

modelName  = 'slexAutotransRootInportsExample';
Throttlex  = timeseries(zeros(10,1));
Brake      = timeseries(ones(10,1));
ds         = Simulink.SimulationData.Dataset;
ds         = ds.addElement( Throttlex, 'Throttlex' );
ds         = ds.addElement( Brake, 'Brake' );
signalNames= {'ds'};
signals    = { ds };
open_system(modelName);
inputMap   = AlmostBlockName(modelName, signalNames, signals);
inputStr   = getInputString(inputMap,'base');
close_system(modelName);

После выполнения фрагмента кода для сигналов в Simulink. SimulationData. Набор данных, переменная inputStr содержит строку 'ds.getElement ('Throttlex'), ds.getElement ('Тормоз')'.