exponenta event banner

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

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

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

Технологический процесс

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

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

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

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

Предположим, что используется следующий сценарий:

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

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

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

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

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

Имена блоков ввода на корневом уровне:

  • Дроссель

  • Тормоз

Имена сигнальных переменных:

  • Throttlex

  • Тормоз

Для сопоставления входных данных с блоками ввода корневого уровня в этом сценарии необходима пользовательская функция сопоставления для инструмента сопоставления корневого ввода. В этом примере используется пользовательская функция сопоставления CharingBlockName.

В этом примере будет использоваться slexAutotransRootInportsExample для проверки пользовательской функции сопоставления.

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

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

function inputMap = AlmostBlockName( modelName, signalNames, signals )

Получение сопоставления имени блока Simulink

Затем запланируйте все сигналы. Для этого сначала сопоставьте все сигналы в пределах допуска, используя режим отображения имени блока 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 теперь вектор содержит логический вектор, где true означает inputMap не имеет отображенного на него сигнала.

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

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

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

Завершение сопоставления

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

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

  1. В векторе empireIndex найдите все элементы, которые являются истинными. Эти элементы указывают на 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

Пользовательский файл сопоставления

Когда вы закончите, файл SharingBlockName.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, Brake».

Если сигналы находятся в Simulink.Toda.Dataset, для просмотра результатов функции отображения используйте следующий фрагмент кода в окне команд 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.PaydData.Dataset переменная inputStr содержит строку «» ds.getElement ('Throttlex'), ds.getElement ('Brake') '.