Задайте шаги расчета S-функции

О шагах расчета

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

Можно задать скорости S-функций (т.е. шаги расчета) как

  • Основанные на блоках шаги расчета

  • Основанные на порте шаги расчета

  • Гибридные блоковые и портовые шаги расчета

С основанными на блоках шагами расчета, S-функция задает набор рабочих скоростей для блока в целом во время фазы инициализации симуляции. С шагами расчета на основе портов S-функция задает шаг расчета для каждого входного и выходного порта индивидуально во время инициализации. Во время фазы симуляции, с основанными на блоках шагами расчета, S-функция обрабатывает все входы и выходы каждый раз, когда попадание выборки происходит для блока. В отличие от этого, с шагами расчета на основе портов блок обрабатывает конкретный порт только, когда для этого порта происходит попадание выборки.

Для примера рассмотрим две скорости дискретизации, 0,5 и 0,25 секунды, соответственно:

  • В блочном методе выбор 0,5 и 0,25 предписывает блоку выполнять входы и выходы с шагом 0,25 секунды.

  • В методе, основанном на порте, установка входного порта 0,5 и выходного порта 0,25 заставляет блок обрабатывать входы на 2 Гц и выходы на 4 Гц.

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

В некоторых приложениях блоку S-Function может потребоваться работать внутри с одной или несколькими скоростями дискретизации во время ввода или вывода сигналов с другими скоростями. Гибридный метод определения частот дискретизации на основе блоков и портов позволяет создавать такие блоки.

В типичных приложениях вы задаете только один основанный на блоках шаг расчета. Расширенные S-функции могут потребовать спецификации шагов расчета на основе портов или нескольких блоков.

Основанные на блоках шаги расчета

S-функции MEX на C задают основанную на блоках информацию о шаге расчета в

В следующих двух разделах обсуждается, как задать основанные на блоках шаги расчета для S-функций C MEX. В третьем разделе представлен простой пример, который показывает, как задать шаги расчета в mdlInitializeSampleTimes. Подробный пример см. в разделе mixedm.c.

Определение количества шагов расчета в mdlInitializeSizes

Чтобы сконфигурировать свою S-функцию для основанных на блоках шагов расчета, используйте

ssSetNumSampleTimes(S,numSampleTimes);

где numSampleTimes > 0. Это говорит Simulink® движком, который ваша S-функция имеет основанные на блоках шаги расчета. механизм вызывает mdlInitializeSampleTimes, который, в свою очередь, устанавливает шаги расчета.

Установка шагов расчета и определение вызовов функций в mdlInitializeSampleTimes

mdlInitializeSampleTimes задает две части информации о выполнении:

  • Время дискретизации и смещения - В mdlInitializeSampleTimes, вы должны задать период выборки и смещение для каждого шага расчета используя ssSetSampleTime и ssSetOffsetTime. Если применимо, можно вычислить соответствующий период выборки и смещение до установки их, например, путем вычисления наилучшего шага расчета для блока на основе параметров диалога S-функции, полученных с помощью ssGetSFcnParam.

  • Вызовы функций - В mdlInitializeSampleTimes, использование ssSetCallSystemOutput для определения элементов выхода, которые выполняют вызовы функций. См. sfun_fcncall.c для примера и реализации Подсистем вызова функций с S-функциями для объяснения этой S-функции.

Вы задаете шаги расчета как пары [sample_time, offset_time], с использованием этих макросов

ssSetSampleTime(S, sampleTimePairIndex, sample_time)
ssSetOffsetTime(S, offsetTimePairIndex, offset_time)

где sampleTimePairIndex и offsetTimePairIndex начинается с 0.

Допустимыми парами шага расчета являются (заглавные значения являются макросами, определенными в simstruc.h):

[CONTINUOUS_SAMPLE_TIME,  0.0                       ]
[CONTINUOUS_SAMPLE_TIME,  FIXED_IN_MINOR_STEP_OFFSET]
[discrete_sample_period,  offset                    ]
[VARIABLE_SAMPLE_TIME  ,  0.0                       ]

Кроме того, можно задать, что шаг расчета наследуется от ведущего блока, в этом случае S-функция может иметь только одну пару шага расчета,

[INHERITED_SAMPLE_TIME,  0.0                       ]

или

[INHERITED_SAMPLE_TIME,  FIXED_IN_MINOR_STEP_OFFSET]

Примечание

Если ваша S-функция наследует свои шаги расчета, необходимо указать, безопасно ли использовать S-функцию в модели-ссылке, т.е. модели, на которую ссылается другая модель. Дополнительные сведения см. Модель-ссылку разделе «Определение наследования Шага расчета».

Следующие инструкции могут помочь в определении шагов расчета:

  • Непрерывная функция, которая изменяется во время незначительных шагов интегрирования, должна регистрировать [CONTINUOUS_SAMPLE_TIME, 0.0] Шаг расчета.

  • Непрерывная функция, которая не меняется во время незначительных шагов интегрирования, должна регистрировать [CONTINUOUS_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET] Шаг расчета.

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

    [discrete_sample_period, offset]
    

    где

    discrete_sample_period > 0.0
    

    и

    0.0 <= offset < discrete_sample_period
    
  • Дискретная функция, которая изменяется с переменной скоростью, должна регистрировать дискретную [VARIABLE_SAMPLE_TIME, 0.0] с переменным шагом Шаг расчета. В S-функциях MEX на C, mdlGetTimeOfNextVarHit вызывается функция, чтобы получить время следующей выборки хита для дискретной задачи с переменным шагом. The VARIABLE_SAMPLE_TIME может использоваться только с решателями переменного шага.

Если ваша функция не имеет внутреннего шага расчета, вы должны указать, что она наследуется в соответствии со следующими рекомендациями:

  • Функция, которая изменяется по мере изменения входных параметров, даже во время незначительных шагов интегрирования, должна регистрировать [INHERITED_SAMPLE_TIME, 0.0] Шаг расчета.

  • Функция, которая изменяется по мере изменения входов, но не изменяется во время незначительных шагов интегрирования (что означает, удерживается во время мелких шагов), должна регистрировать [INHERITED_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET] Шаг расчета.

Для проверки на наличие выборки удара во время выполнения (в mdlOutputs или mdlUpdate), использовать ssIsSampleHit или ssIsContinuousTask макрос. Для примера используйте следующий фрагмент кода для проверки на непрерывную выборку попадание:

if (ssIsContinuousTask(S,tid)) {
}

Чтобы определить, имеет ли третье (дискретное) задание попадание, используйте следующий фрагмент кода:

if (ssIsSampleHit(S,2,tid) {
}

Механизм Simulink всегда присваивает индекс 0 к непрерывной частоте дискретизации, если она существует, однако вы получаете неправильные результаты, если используете ssIsSampleHit(S,0,tid).

Пример: mdlInitializeSampleTimes

Этот пример задает, что существует два дискретных шага расчета с периодами 0,01 и 0,5 секунды.

static void mdlInitializeSampleTimes(SimStruct *S)
{
  ssSetSampleTime(S, 0, 0.01);
  ssSetOffsetTime(S, 0, 0.0);
  ssSetSampleTime(S, 1, 0.5);
  ssSetOffsetTime(S, 1, 0.0);
} /* End of mdlInitializeSampleTimes. */

Определение шагов расчета на основе портов

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

Чтобы использовать основанные на портах шаги расчета в вашей функции C MEX S, необходимо указать количество шагов расчета как основанных на портах в функции S mdlInitializeSizes метод:

ssSetNumSampleTimes(S, PORT_BASED_SAMPLE_TIMES)

Вы также должны задать шаг расчета каждого входного и выходного порта в S-функции mdlInitializeSizes метод, с использованием следующих макросов

ssSetInputPortSampleTime(S, idx, period)
ssSetInputPortOffsetTime(S, idx, offset)
ssSetOutputPortSampleTime(S, idx, period)
ssSetOutputPortOffsetTime(S, idx, offset)

Вызов ssSetNumSampleTimes могут быть помещены до или после того, как основанные на порте шаги расчета фактически указаны в mdlInitializeSizes. Однако, если ssSetNumSampleTimes не конфигурирует S-функцию для использования основанных на портах шагов расчета, любые шаги расчета, установленные на портах, будут проигнорированы.

Для любого данного порта можно задать

Определение наследованного шага расчета для порта

Чтобы указать, что шаг расчета порта наследуется в S-функции MEX на C, mdlInitializeSizes метод должен установить его период равным -1 и его смещение на 0. Для примера следующий код задает унаследованные шаги расчета для первого порта входа функции MEX S на C:

ssSetInputPortSampleTime(S, 0, -1);
ssSetInputPortOffsetTime(S, 0, 0);

Когда вы задаете основанные на портах шаги расчета, механизм Simulink вызывает mdlSetInputPortSampleTime и mdlSetOutputPortSampleTime для определения скоростей наследуемых сигналов.

После того, как все тарифы определены, механизм вызывает mdlInitializeSampleTimes. Несмотря на то, что на данной точке нет необходимости инициализировать шаги расчета на основе портов, механизм вызывает этот метод, чтобы предоставить вашей S-функции возможность сконфигурировать соединения вызова функции. Таким образом, ваша S-функция должна обеспечить реализацию для этого метода независимо от того, использует ли он основанные на порте шаги расчета или соединения вызова функции. Несмотря на то, что вы можете предоставить пустую реализацию, вы можете использовать ее, чтобы проверить уместность шагов расчета, которые унаследовал блок во время распространения выборки. Использовать ssGetInputPortSampleTime и ssGetOutputPortSampleTime в mdlInitializeSampleTimes для получения значений унаследованных шагов расчета. Например, следующий код в mdlInitializeSampleTimes проверяет, унаследовал ли первый вход S-функции непрерывный шаг расчета.

if (!ssGetInputPortSampleTime(S,0)) {
    ssSetErrorStatus(S,"Cannot inherit a continuous sample time.")
};

Примечание

Если вы задаете, что ваши порты S-функции наследуют свой шаг расчета, вы также должны указать, безопасно ли использовать S-функцию в ссылочной модели, то есть модели, на которую ссылается другая модель. Дополнительные сведения см. Модель-ссылку разделе «Определение наследования Шага расчета».

Если вы записываете TLC код, чтобы сгенерировать inlined код из S-функции, и если TLC код содержит Outputs функция, вы должны изменить код TLC, если эти условия верны:

  • Порт выхода имеет постоянное значение. Он использует или наследует шаг расчета Inf.

  • S-функция является многократной S-функцией или использует основанные на порте шаги расчета.

В этом случае код TLC должен сгенерировать код для порта выхода с постоянными значениями при помощи функции OutputsForTID вместо функции Outputs. Для получения дополнительной информации смотрите Задание Постоянного Шага Расчета (Inf) для Порта.

Чтобы предотвратить наследование портами шага расчета Inf, установите опцию SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME в коде S-функции. В этом случае можно использовать функцию TLC Outputs для генерации кода для выходных портов с постоянными значениями.

Определение постоянного шага расчета (Inf) для порта

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

Чтобы сделать порт выходным постоянным значением, S-функция должна:

  • Использование ssSetOptions в своей mdlInitializeSizes метод, чтобы добавить поддержку для шага расчета Inf:

    ssSetOptions(S,SS_OPTION_ALLOW_CONSTANT_PORT_SAMPLE_TIME);
    

    Примечание

    Эта опция заставляет порты S-функции поддерживать шаг расчета Inf, включая порты, которые наследуют их шаги расчета от других блоков. Если какие-либо порты S-функции, которые наследуют шаг расчета, не могут иметь шаг расчета Inf, возникает ошибка. Установите шаги расчета для этих портов, используя mdlSetInputPortSampleTime и mdlSetOutputPortSampleTime методы.

  • Установите значение шага расчета порта равным Inf и его смещение на 0, например,

    ssSetInputPortSampleTime(S,0,mxGetInf());
    ssSetInputPortOffsetTime(S,0,0);
    
  • Сдать на хранение mdlOutputs является ли метод tid аргумент равен CONSTANT_TID и если да, задайте значение выхода порта, если он является выходом портом.

Чтобы увидеть пример того, как создать порты, которые выводят постоянное значение, смотрите sfun_port_constant.c, исходный файл для sfcndemo_port_constant пример.

Если вы записываете TLC код, чтобы сгенерировать inlined код из S-функции, и если TLC код содержит Outputs function, измените код TLC, если все эти условия верны:

  • Порт выхода имеет постоянное значение. Он использует или наследует шаг расчета Inf.

  • S-функция является многократной S-функцией или использует основанные на порте шаги расчета.

В этом случае код TLC должен сгенерировать код для порта выхода с постоянными значениями при помощи функции OutputsForTID вместо функции Outputs. Функция OutputsForTID генерирует выходной код для постоянного компонента S-функции. Если вы конфигурируете модель, чтобы сгенерировать многозадачный код, OutputsForTID также генерирует выходной код для периодических компонентов S-функции.

Для примера просмотрите файл TLC sfun_port_constant.tlc для функции C S sfun_port_constant.c в sfcndemo_port_constant модели. В модели вход блочного S-Function2 имеет постоянное значение на протяжении всей симуляции. В коде S-функции первый выходной порт наследует шаг расчета входного порта, поэтому выходной порт также имеет постоянное значение. Код S-функции непосредственно задает постоянное значение для второго выходного порта.

В коде TLC, если порт имеет постоянное значение, функция Outputs не генерирует код для первого выходного порта. Функция не генерирует код для второго выходного порта ни при каких обстоятельствах, потому что порт всегда имеет постоянное значение.

Для этой S-функции OutputsForTID генерирует код для выходных портов, которые имеют постоянное значение. Генератор кода вызывает функцию OutputsForTID, и устанавливает аргумент tid идентификатору задачи, который соответствует постоянным значениям. Только если идентификатор задачи выходного порта соответствует постоянным значениям, это так OutputsForTID затем сгенерируйте код для порта.

Конфигурирование шагов расчета на основе портов для использования в триггируемых подсистемах

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

  • Использование ssSetOptions в mdlInitializeSizes метод для указания, что S-функция может выполняться в триггируемую подсистему:

    ssSetOptions(S, 
    SS_OPTION_ALLOW_PORT_SAMPLE_TIME_IN_TRIGSS);
    
  • Установите все его порты унаследованными (-1) или постоянный шаг расчета (Inf) в его mdlInitializeSizes способ.

  • Указатель шага расчета в mdlSetInputPortSampleTime и mdlSetOutputPortSampleTime методы следующим образом.

    Поскольку порты S-функции наследуют свои шаги расчета, механизм Simulink вызывает либо mdlSetInputPortSampleTime или mdlSetOutputPortSampleTime во время распространения шага расчета. Макрос ssSampleAndOffsetAreTriggered может использоваться в этих методах, чтобы определить, находится ли S-функция в триггируемой подсистеме. Если S-функция находится в триггируемой подсистеме, любой метод, который вызывается, должен задать шаг расчета и смещение порта, для которого она вызывается INHERITED_SAMPLE_TIME (-1).

    Установка шага расчета порта и смещение обоих значений INHERITED_SAMPLE_TIME указывает, что шаг расчета порта срабатывает, т.е. выдает выход или принимает вход только тогда, когда инициируется подсистема, в которой он находится. Затем метод должен также задать шаги расчета и смещения всех других входных и выходных портов S-функции, чтобы иметь либо активированный, либо постоянный шаг расчета (Inf), в зависимости от того, что подходит, например,

    static void mdlSetInputPortSampleTime(SimStruct *S,
                                          int_T portIdx,
                                          real_T sampleTime
                                          real_T offsetTime)
    {
        /* If the S-function resides in a triggered subsystem,
           the sample time and offset passed to this method
           are both equal to INHERITED_SAMPLE_TIME. Therefore,
           if triggered, the following lines set the sample time
           and offset of the input port to INHERITED_SAMPLE_TIME.*/
    
        ssSetInputPortSampleTime(S, portIdx, sampleTime);
        ssSetInputPortOffsetTime(S, portIdx, offsetTime);
        
        /* If triggered, set the output port to inherited, as well */
    
        if (ssSampleAndOffsetAreTriggered(sampleTime,offsetTime)) {
            ssSetOutputPortSampleTime(S, 0, INHERITED_SAMPLE_TIME);
            ssSetOutputPortOffsetTime(S, 0, INHERITED_SAMPLE_TIME);
    
            /* Note, if there are additional input and output ports
               on this S-function, they should be set to either
               inherited or constant at this point, as well. */
        }
    }

    Нет способа, чтобы S-функция, проживающая в триггируемой подсистеме, предсказала, вызовет ли механизм Simulink mdlSetInputPortSampleTime или mdlSetOutputPortSampleTime чтобы задать шаги расчета порта. По этой причине оба метода должны иметь возможность правильно задать шаги расчета всех портов, поэтому механизм должен вызывать только один из методов в одно время.

  • В mdlUpdate и mdlOutputs, использование ssGetPortBasedSampleTimeBlockIsTriggered чтобы проверить, находится ли S-функция в триггируемой подсистеме, и если да, используйте соответствующие алгоритмы для вычисления ее состояний и выходов.

См. sfun_port_triggered.c, исходный файл для sfcndemo_port_triggered пример модели, для примера того, как создать S-функцию, которая может использоваться в триггируемой подсистеме.

Гибридные блоковые и портовые Шаги расчета

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

Затем установите SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED опция, использование ssSetOptions, чтобы сообщить механизму симуляции, что вы собираетесь использовать основанный на порте метод, чтобы задать скорости входного и выходного портов индивидуально. Далее, как и в основанном на блоках методе, вы задаете периоды и смещения всех частот блока, как внутренних, так и внешних, используя

ssSetSampleTime
ssSetOffsetTime

Наконец, как и в методе на основе портов, вы задаете скорости для каждого порта, используя

ssSetInputPortSampleTime(S, idx, period)
ssSetInputPortOffsetTime(S, idx, offset)
ssSetOutputPortSampleTime(S, idx, period)
ssSetOutputPortOffsetTime(S, idx, offset)

Обратите внимание, что каждая из назначенных частот портов должна быть такой же, как и одна из ранее объявленных частот блоков. Для примера S-функции см mixedm.c.

Примечание

Если вы используете SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED опция, ваша S-функция не может наследовать шаги расчета. Вместо этого необходимо задать скорость, с которой запускается каждый входной и выходной порт.

Мультирациональные блоки s-function

В многократном блоке S-Function можно инкапсулировать код, который определяет каждое поведение в mdlOutputs и mdlUpdate функции с оператором, который определяет, произошла ли выборка столкновение. В S-функции MEX на C ssIsSampleHit макрос определяет, является ли текущее время выборки хитом в течение заданного шага расчета. Макрос имеет следующий синтаксис:

ssIsSampleHit(S, st_index, tid)

где S является SimStruct, st_index определяет определенный индекс шага расчета и tid - идентификатор задачи (tid является аргументом в mdlOutputs и mdlUpdate функций).

Например, эти операторы в S-функции C MEX задают три шагов расчета: один для непрерывного поведения и два для дискретного поведения.

ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetSampleTime(S, 1, 0.75);
ssSetSampleTime(S, 2, 1.0);

В mdlUpdate функция, следующий оператор инкапсулирует код, который определяет поведение для шага расчета 0,75 секунды.

if (ssIsSampleHit(S, 1, tid)) {
}

Второй аргумент, 1, соответствует второй шаг расчета, 0,75 секунды.

Используйте следующие линии, чтобы инкапсулировать код, который определяет поведение для непрерывного попадания выборки:

if (ssIsContinuousTask(S,tid)) {
}

Пример определения шага расчета для непрерывного блока

Этот пример задает шаг расчета для блока, который является непрерывным.

/* Initialize the sample time and offset. */
static void mdlInitializeSampleTimes(SimStruct *S)
{
  ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
  ssSetOffsetTime(S, 0, 0.0);
}

Вы должны добавить этот оператор к mdlInitializeSizes функция.

ssSetNumSampleTimes(S, 1);

Пример определения шага расчета для гибридного блока

Этот пример задает шаги расчета для гибридного блока S-Function.

/* Initialize the sample time and offset. */
static void mdlInitializeSampleTimes(SimStruct *S)
{
  /* Continuous state sample time and offset. */
  ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
  ssSetOffsetTime(S, 0, 0.0);

  /* Discrete state sample time and offset. */
  ssSetSampleTime(S, 1, 0.1);
  ssSetOffsetTime(S, 1, 0.025);
}

Во втором шаге расчета смещение заставляет механизм Simulink вызывать mdlUpdate функция в эти моменты времени: 0,025 секунды, 0,125 секунды, 0,225 секунды и так далее, с шагами 0,1 секунды.

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

ssSetNumSampleTimes(S, 2);

Мультирейт S-функций и шагов расчета ударов

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

Этот метод вычисления становится важным, если вы рассматриваете выполнение логики Boolean на основе времени задачи в многократных S-функциях. Например, рассмотрим S-функцию, которая имеет два шага расчета. То, что (ssIsSampleHit (S, idx1) == истинный && ssIsSampleHit (S, idx2) == верный, не гарантирует что ssGetTaskTime (S, idx1) == ssGetTaskTime (S, idx2).

Синхронизация многократных блоков s-function

Если задачи, выполняемые с различными скоростями, должны совместно использовать данные, необходимо убедиться, что данные, сгенерированные одной задачей, действительны при доступе к другой задаче, выполняемой с другой скоростью. Можно использовать ssIsSpecialSampleHit макрос в mdlUpdate или mdlOutputs стандартная программа многоразовой S-функции, чтобы убедиться, что разделяемые данные действительны. Этот макрос возвращает true если попадание выборки произошло с одной скоростью, и попадание выборки также произошло с другой скоростью на том же временном шаге. Таким образом, это позволяет более высокоскоростной задаче предоставлять данные, необходимые для более медленной задачи со скоростью, которую может принять более медленная задача. При использовании ssIsSpecialSampleHit макрос, более медленный шаг расчета должно быть целым числом, кратным более быстрому шагу расчета.

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

if (ssIsSampleHit(S, 0, tid) {
  if (ssIsSpecialSampleHit(S, 0, 1, tid) {
     /* Transfer input to output memory. */
     ...
  }
}

if (ssIsSampleHit(S, 1, tid) {
   /* Emit output. */
   ...
}

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

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

Определение Модели-ссылки наследования шага расчета

Если ваша C MEX S-функция наследует свои шаги расчета от блоков, которые управляют ею, ваша S-функция должна указать, могут ли модели-ссылки, содержащие вашу S-функцию, наследовать шаги расчета от их родительской модели. Если выход S-функции не зависит от его унаследованного шага расчета, используйте ssSetModelReferenceSampleTimeInheritanceRule макрос, чтобы задать для S-функции шага расчета правила наследования значение USE_DEFAULT_FOR_DISCRETE_INHERITANCE. В противном случае установите правило на DISALLOW_SAMPLE_TIME_INHERITANCE запретить наследование шаг расчета для ссылочных моделей, которые включают S-функции, выходы которых зависят от их унаследованного шага расчета и тем самым избегают непреднамеренных ошибок симуляции.

Примечание

Если ваша S-функция не устанавливает этот флаг, механизм Simulink принимает, что он не препятствует модели-ссылке, содержащей его, наследовать время расчета. Однако механизм опционально предупреждает вас, что ссылочная модель содержит S-функции, которые не задают правило наследования шаг расчета (см. «Блоки, выходы которых зависят от наследованного шага расчета»).

Если вы не уверены, зависит ли выход существующей S-функции от ее унаследованного шага расчета, проверьте, вызывает ли она любой из следующих макросов C:

  • ssGetSampleTime

  • ssGetInputPortSampleTime

  • ssGetOutputPortSampleTime

  • ssGetInputPortOffsetTime

  • ssGetOutputPortOffsetTime

  • ssGetInputPortSampleTimeIndex

  • ssGetOutputPortSampleTimeIndex

или функции TLC:

  • LibBlockSampleTime

  • CompiledModel.SampleTime

  • LibBlockInputSignalSampleTime

  • LibBlockInputSignalOffsetTime

  • LibBlockOutputSignalSampleTime

  • LibBlockOutputSignalOffsetTime

Если ваша S-функция не вызывает ни один из этих макросов или функций, ее выход не зависит от ее унаследованных шагов расчета и, следовательно, безопасно использовать в ссылочных моделях, которые наследуют их шаг расчета.

Пример правила наследования шаг расчета

В качестве примера S-функции, которая препятствует наследованию модели-ссылки своего шага расчета, рассмотрим S-функцию, которая имеет следующее mdlOutputs метод:

static void mdlOutputs(SimStruct *S, int_T tid) {
    const real_T *u = (const real_T*) 
    ssGetInputPortSignal(S,0);
    real_T       *y = ssGetOutputPortSignal(S,0);
    y[0] = ssGetSampleTime(S,tid) * u[0];
}

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

ssSetModelReferenceSampleTimeInheritanceRule
(S, DISALLOW_SAMPLE_TIME_INHERITANCE);

См. также

| |

Похожие темы