Задайте шаги расчета 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-функции могут потребовать спецификации основанных на порте или нескольких шагов расчета блока.

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

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

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

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

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

ssSetNumSampleTimes(S,numSampleTimes);

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

Установка Шагов расчета и Определение Вызовов функции в 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] 'SampleTime' .

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

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

    [discrete_sample_period, offset]
    

    где

    discrete_sample_period > 0.0
    

    и

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

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

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

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

Проверять на демонстрационный хит во время выполнения (в 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-функцию, чтобы гарантировать, что общее количество портов не переходит к нулю.

Чтобы использовать основанные на порте шаги расчета в вашей 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-функции 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, ошибка происходит. Установите шаги расчета для этих портов с помощью mdlSetInputPortSampleTime и mdlSetOutputPortSampleTime методы.

  • Установите шаг расчета порта на 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

В многоскоростном Блоке 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);

Многоскоростные S-функции и вычисления хита шага расчета

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

Этот метод расчета становится важным, если вы считаете Булеву логику выполнения основанной на временах задачи в многоскоростных 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. */
   ...
}

В этом примере запускается первый блок, когда демонстрационный хит происходит на входном уровне. Если хит также происходит при норме выработки, поблочные передачи вход к выходу 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);

Смотрите также

| |

Похожие темы