Можно задать поведение шага расчета 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-функции могут потребовать спецификации основанных на порте или нескольких шагов расчета блока.
C S-функции MEX указывают основанную на блоке информацию шага расчета в
Следующие два раздела обсуждают, как задать основанные на блоке шаги расчета для S-функций MEX C. Третий раздел представляет простой пример, который показывает, как задать шаги расчета в mdlInitializeSampleTimes
. Для подробного примера смотрите mixedm.c
.
Чтобы сконфигурировать вашу S-функцию для основанных на блоке шагов расчета, использовать
ssSetNumSampleTimes
(S,numSampleTimes);
где numSampleTimes > 0
. Это говорит механизму Simulink®, что ваша S-функция имеет основанные на блоке шаги расчета. механизм вызывает mdlInitializeSampleTimes
, который в свою очередь устанавливает шаги расчета.
mdlInitializeSampleTimes
задает две части информации о выполнении:
Демонстрационный и времена смещения — В mdlInitializeSampleTimes
, необходимо задать период выборки и смещение для каждого шага расчета с помощью ssSetSampleTime
и ssSetOffsetTime
. Если применимо можно вычислить соответствующий период выборки и смещение до установки их, например, путем вычисления лучшего шага расчета для блока на основе диалоговых параметров S-функции, полученных с помощью ssGetSFcnParam
.
Вызовы функции — В mdlInitializeSampleTimes
, используйте ssSetCallSystemOutput
, чтобы указать выходные элементы, которые выполняют вызовы функции. Seesfun_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
вызвана, чтобы получить время следующего демонстрационного хита для переменного шага дискретная задача. VARIABLE_SAMPLE_TIME
может использоваться с решателями переменного шага только.
Если ваша функция не имеет никакого внутреннего шага расчета, необходимо указать, что она наследована согласно следующим инструкциям:
Функция, которая изменяется как ее вход изменения, даже во время незначительных этапов интеграции, должна указать шаг расчета [INHERITED_SAMPLE_TIME, 0.0]
.
Функция, которая изменяется как ее вход, изменяется, но не изменяется во время незначительных этапов интеграции (значение, сохранен во время незначительных шагов), должен указать шаг расчета [INHERITED_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET]
.
Чтобы проверять на демонстрационный хит во время выполнения (в mdlOutputs
или mdlUpdate
), используйте макрос ssIsContinuousTask
или ssIsSampleHit
. Например, используйте следующий фрагмент кода, чтобы проверять на хит непрерывной выборки:
if (ssIsContinuousTask
(S,tid)) {
}
Чтобы определить, имеет ли третья (дискретная) задача хит, используйте следующий фрагмент кода:
if (ssIsSampleHit
(S,2,tid) {
}
Механизм Simulink всегда присваивает индекс 0
к уровню непрерывной выборки, если это существует, однако вы получаете неправильные результаты, если вы используете ssIsSampleHit(S,0,tid)
.
Этот пример указывает, что существует два дискретных шага расчета с периодами 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-функцию, чтобы гарантировать, что общее количество портов не переходит к нулю.
Чтобы использовать основанные на порте шаги расчета в вашей S-функции MEX C, необходимо задать количество шагов расчета как основанное на порте в 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-функции первый входной порт к 0.1
и время смещения к 0
.
ssSetInputPortSampleTime(S, 0, 0.1); ssSetInputPortOffsetTime(S, 0, 0);
Наследованный шаг расчета (-1
), т.е. порт наследовал свой шаг расчета от порта, до которого это соединяется (см. Определение Наследованный Шаг расчета для Порта),
Постоянный шаг расчета (Inf
), т.е. сигнал, прибывающий из порта, является постоянным (см. Задающий Постоянный Шаг расчета (Inf) для Порта),
Чтобы быть применимыми в инициированной подсистеме, все ваши порты S-функции, должно быть, или наследовались (–1
) или постоянный шаг расчета (Inf
). Для получения дополнительной информации смотрите Конфигурирующие Основанные на порте Шаги расчета для Использования в Инициированных Подсистемах.
Чтобы указать, что шаг расчета порта наследован в S-функции MEX C, метод mdlInitializeSizes
должен установить свой период на -1
и свое смещение к 0
. Например, следующий код задает наследованный шаг расчета для S-функции MEX 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, чтобы сгенерировать встроенный код от 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
, ошибка происходит. Установите шаги расчета для этих портов с помощью методов mdlSetOutputPortSampleTime
и mdlSetInputPortSampleTime
.
Установите шаг расчета порта на Inf
и его смещение к 0
, например,
ssSetInputPortSampleTime(S,0,mxGetInf()); ssSetInputPortOffsetTime(S,0,0);
Зарегистрируйтесь в mdlOutputs
, равняется ли аргумент tid
метода CONSTANT_TID
и если так, установил значение вывода порта, если это - выходной порт.
Чтобы видеть пример того, как создать порты, которые выводят постоянное значение, смотрите sfun_port_constant.c
, исходный файл для примера sfcndemo_port_constant
.
Если вы пишете код TLC, чтобы сгенерировать встроенный код от S-функции, и если код TLC содержит функцию Outputs
, измените код TLC, если все эти условия верны:
Выходной порт имеет постоянное значение. Это использует или наследовало шаг расчета Inf
.
S-функция является многоскоростной S-функцией или использует основанные на порте шаги расчета.
В этом случае код TLC должен сгенерировать код для выходного порта с постоянным знаком при помощи функционального OutputsForTID
вместо функционального Outputs
. Функциональный OutputsForTID
генерирует выходной код для компонента с постоянным знаком S-функции. Если вы конфигурируете модель, чтобы сгенерировать многозадачный код, OutputsForTID
также генерирует выходной код для периодических компонентов S-функции.
Например, просмотрите файл TLC sfun_port_constant.tlc
для S-функции C sfun_port_constant.c
в модели sfcndemo_port_constant
. В модели вход блока S-Function2 имеет постоянное значение в течение симуляции. В коде S-функции первый выходной порт наследовал шаг расчета входного порта, таким образом, выходной порт также имеет постоянное значение. Код S-функции непосредственно задает постоянное значение для второго выходного порта.
В коде TLC, если порт имеет постоянное значение, функциональный Outputs
не генерирует код для первого выходного порта. Функция не генерирует код для второго выходного порта ни при каких обстоятельствах, потому что порт всегда имеет постоянное значение.
Для этой S-функции OutputsForTID
генерирует код для выходных портов, которые имеют постоянное значение. Генератор кода вызывает функциональный OutputsForTID
и устанавливает аргумент tid
на идентификатор задачи, который соответствует постоянным значениям. Только если идентификатор задачи выходного порта соответствует постоянным значениям, делает, OutputsForTID
затем генерируют код для порта.
Чтобы использовать S-функцию MEX C в инициированной подсистеме, ваша основанная на порте 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 можно инкапсулировать код, который задает каждое поведение в mdlOutputs
и функциях mdlUpdate
с оператором, который определяет, произошел ли демонстрационный хит. В S-функции MEX C макрос ssIsSampleHit
определяет, является ли текущее время демонстрационным хитом для заданного шага расчета. Макрос имеет этот синтаксис:
ssIsSampleHit(S, st_index, tid)
где S
является SimStruct
, st_index
идентифицирует определенный индекс шага расчета, и tid
является ID задачи (tid
является аргументом к mdlOutputs
и функциям mdlUpdate
).
Например, эти операторы в S-функции MEX C задают три шага расчета: один для непрерывного поведения и два для дискретного поведения.
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);
Для решателей фиксированного шага Simulink использует целочисленную арифметику, а не арифметику с плавающей точкой, чтобы вычислить хиты шага расчета. Следовательно, времена задачи являются целочисленными множителями своих соответствующих периодов шага расчета.
Этот метод расчета становится важным, если вы считаете Булеву логику выполнения основанной на временах задачи в многоскоростных S-функциях. Например, рассмотрите S-функцию, которая имеет два шага расчета. То, что (ssIsSampleHit (S, idx1) == истинный && ssIsSampleHit (S, idx2) == верный, не гарантирует что ssGetTaskTime (S, idx1) == ssGetTaskTime (S, idx2).
Если задачи, запускающиеся на различных уровнях, должны осуществлять обмен данными, необходимо гарантировать, что данные, сгенерированные одной задачей, допустимы, когда получено доступ другой задачей, запускающейся на различном уровне. Можно использовать макрос 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. */ ... }
В этом примере запускается первый блок, когда демонстрационный хит происходит на входном уровне. Если хит также происходит при норме выработки, поблочные передачи вход к выводу memory. Второй блок запускается, когда демонстрационный хит происходит при норме выработки. Это передает вывод в своей области памяти к выводу блока.
Обратите внимание на то, что задачи более высокого уровня, всегда запускаемые перед задачами более медленного уровня. Таким образом входная задача в предыдущем примере всегда запускается перед выходной задачей, гарантируя, что допустимые данные всегда присутствуют в выходном порту.
Если ваша S-функция MEX C наследовала свои шаги расчета от блоков, которые управляют ею, ваша 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
ssGetSampleTimePtr
ssGetInputPortSampleTimeIndex
ssGetOutputPortSampleTimeIndex
ssGetSampleTimeTaskID
ssGetSampleTimeTaskIDPtr
или функции 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);
ssGetSampleTime
| ssSetInputPortSampleTime
| ssSetSampleTime