Достоинства ложного положения.

Версия 1.2.0

© Copyright 2007 - 2010
Грибов Игорь,
e-mail: gribov@depni.sinp.msu.ru

Оглавление.

Изменения в версиях.
Управление объектом.
Алгоритм regula falsi.
Программа

Изменения в версиях.

Полная версия раздела задается в виде: версия.подверсия.выпуск.

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

Версия 1.2.0. Внесены изменения в критерий оценки потери управления (функция interpolate()).


Управление объектом.

Общая схема замкнутого контура управления обычно представляется в таком виде:




Задачей алгоритма регулирования является выработка такого управляющего воздействия S, которое позволяет установить и поддерживать на объекте управления величину выходного параметра P, максимально близкую к значению уставки P0. При этом полагается, что датчик откалиброван и снабжает алгоритм истинным значением выходного параметра.

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

При построении контура цифрового управления важно обратить внимание на согласование точности (разрядности) параметров управления и измерения. Необходимо, чтобы дискретная точность измерения выходного параметра P была как минимум не ниже разрешения управляющего воздействия S, а желательно - на 2-4 разряда (в 4-16 раз) выше.


Алгоритм regula falsi.

Метод ложного положения, он же метод секущих, он же regula falsi используется для поиска изолированных корней алгебраических уравнений. При этом во всем диапазоне поиска исследуемая функция должна вести себя монотонно, то есть ее первая производная не должна изменять знака. Математический смысл алгоритма заключается в линейной интерполяции функции С на каждом шаге исследования (см. рисунок). В контуре дискретного управления метод секущих удобно использовать для установа и поддержания долговременной стабильности выходного параметра объекта, а также компенсации нелинейности его статической характеристики.




Основанный на методе ложного положения алгоритм инициирует новый цикл подстройки выходного параметра P, когда его отклонение от уставки P0 превышает максимально допустимое. Критерием завершения цикла является итерация, в которой рассчитанное по методу секущих смещение управляющего параметра S становится менее половины минимального шага управления. Помимо основного метода алгоритм должен содержать дополнительную логику, придающую ему достаточную устойчивость при работе в управляющей среде. Как правило, программные затраты на реализацию такой логической обвязки заметно превышают объем кода, отвечающего собственно за математический метод. А итоговое качество управления решающим образом зависит от продуманности и тщательности логических решений, обрамляющих основной алгоритм.

В приведенной реализации метода секущих принимаются следующие меры повышения устойчивости управления:

  1. Алгоритм адаптивно ограничивает максимальный шаг управления в каждом цикле подстройки. Допустимое приращение S определяется в начале цикла из соотношения рассогласования управляемого параметра с уставкой (P - P0) и усредненной крутизны характеристики управления (Pmax-Pmin)/(Smax-Smin).

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

  3. Если цикл подстройки завершился с ошибкой и при этом отклонение параметра P от уставки P0 превышает допустимую величину, алгоритм восстанавливает значение управляющего воздействия S, которое было установлено до начала цикла.

  4. Когда полное число ошибок управления становится слишком большим, алгоритм прекращает работу, переходя в состояние ожидания. Такое происходит, например, при отключении или аппаратной неисправности объекта управления.

Алгоритм использует результат дискретных измерений управляемого параметра P, не приводя его к физическим величинам. Требуемое значение уставки P0 переводится в координаты каналов измерения непосредственно при ее задании. Кроме того, считается, что минимальное дискретное приращение управляющего воздействия S равно единице.

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


Программа.

typedef char            int8;
typedef unsigned char   unsigned8;
typedef short           int16;
typedef unsigned short  unsigned16;
typedef int             int32;
typedef unsigned int    unsigned32;
typedef float           real32;
typedef double          real64;

#define OFF_OK      1    // Цикл подстройки завершен успешно
#define OFF_ERROR   2    // Цикл подстройки завершен с ошибкой
#define OFF_STOP    3    // Работа алгоритма остановлена
#define ON_WORK     10   // Идет штатная работа алгоритма

#define STATUS_VALUE_ERROR      1   // Ошибка задания уставки: выходит за допустимые пределы
#define STATUS_INPUT_LIM        2   // Достигнут предел диапазона дискретного измерения P
#define STATUS_CONTROL_LIM      3   // Достигнут предел диапазона управляющего воздействия S
#define STATUS_CONTROL_LOST     4   // Потеря управления: характеристика близка к горизонтальной
#define STATUS_ITERATIONS_LIM   5   // Превышено допустимое число итераций цикла подстройки

#define WAIT_CYCLE    1     // Число тактов ожидания завершения переходного процесса
#define DUMMY_CYCLE   100   // Число тактов бездействия при успешном завершении цикла подстройки
#define ERROR_CYCLE   20    // Число тактов бездействия при возникновении ошибки

Константа WAIT_CYCLE определяет число тактов, пропускаемых алгоритмом после подачи управляющего воздействия S, когда ожидается завершение переходного процесса в объекте. Минимальное время ожидания, при WAIT_CYCLE равной нулю, несколько меньше периода тактирования алгоритма. Правильный подбор WAIT_CYCLE важен для обеспечения качественной работы алгоритма. Константа DUMMY_CYCLE задает число тактов, которые пропускаются после успешного завершения полного цикла подстройки, либо когда отклонение выходного параметра от уставки находится в допустимых пределах. Наконец, ERROR_CYCLE определяет количество тактов, пропускаемых при возниковении ошибки. Таким образом, эти две константы задают время бездействия алгоритма в соответствующих ситуациях.

#define MAX_NO_CONTROL     8    // Допустимое число итераций с потерей управления в цикле
#define MAX_ITERATIONS     30   // Максимальное число итераций в одном цикле подстройки
#define MAX_ERROR_STATUS   50   // Полное число ошибок, приводящее к останову алгоритма 

#define PARVALUE_MIN          -60.0
#define PARVALUE_MAX          125.0
#define PARVALUE_RANGE_FULL   (PARVALUE_MAX-(PARVALUE_MIN))  

Константы PARVALUE_MIN и PARVALUE_MAX задают минимальное и максимальное значения выходного параметра P в физических единицах. Эти константы используются для перевода величины уставки P0 в координаты дискретных каналов измерения.

#define VALUE_SAFE_CHAN   -11512   // “Безопасное” значение управляющего параметра S

Безопасное значение управляющего параметра S устанавливается при останове работы алгоритма. Здесь оно выбрано таким, чтобы обеспечить - в линейном приближении - близкое к нулю значение физической величины P.

#define STEP_MAX_CHAN     7000     // Максимальный шаг параметра управления S, >0

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

#define OUT_MIN_CHAN       -524280   // Минимальное дискретное значение выходного параметра P
#define OUT_MAX_CHAN       524280    // Максимальное дискретное значение выходного параметра P
#define CONTROL_MIN_CHAN   -32767    // Минимальное дискретное значение параметра управления S
#define CONTROL_MAX_CHAN   32767     // Максимальное дискретное значение параметра управления S

#define OUT_RANGE_CHAN       (OUT_MAX_CHAN-(OUT_MIN_CHAN))
#define CONTROL_RANGE_CHAN   (CONTROL_MAX_CHAN-(CONTROL_MIN_CHAN))

Минимально и максимально допустимые дискретные значения выходного параметра определяются прежде всего разрядностью преобразователя датчика, а параметра управления – разрядностью устройства управления. В нашем примере используется 20-разрядное преобразование параметра P и 16-разрядное для управляющего воздействия S. Причем крайние допустимые значения P должны быть строго меньше величин, определяемых разрядностью (-524288 и 524287 для 20-разрядного преобразования), что дает возможность контролировать достижение предела диапазона дискретного измерения выходного параметра P. Кроме того, полные диапазоны P и S должны быть более-менее согласованы, то есть установ крайнего значения управляющего воздействия S должен приводить к значению выходного параметра P также близкому к соответствующему предельному значению.

#define OUT_TO_CONT   (OUT_RANGE_CHAN / CONTROL_RANGE_CHAN)

Отношение дискретных динамических диапазонов выходного и управляющего параметров задает усредненную крутизну характеристики управления C. Эта величина используется при оценке максимального шага управляющего воздействия S в цикле подстройки. Минимальная дискретная крутизна характеристики, при которой алгоритм сохраняет работоспособность, равна единице. Такое значение крутизны подразумевает, что изменение параметра управления S на один шаг в большинстве случаев приводит к смещению выходного параметра P также на один шаг. Особо отметим, что целочисленный параметр OUT_TO_CONT никогда не должен становиться равным нулю, что обеспечивается большей разрядностью измерения выходного параметра по сравнению с разрядностью управляющего воздействия.

#define DEVIATION_MAX_CHAN   OUT_TO_CONT

Константа DEVIATION_MAX_CHAN задает величину отклонения от уставки выходного параметра P, при которой начинается новый цикл подстройки. Она выбрана равной средней дискретной крутизне характеристики управления, поскольку при этом изменение управляющего воздействия S на один шаг позволяет в большинстве случаев уменьшить отклонение выходного параметра P от уставки.

int16 semaphore=0;

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

int16 tangent_flag;

Переменная tangent_flag является флагом наклона характеристики управления C (знак первой производной). С ее помощью производится выбор направления пробного шага управляющего воздействия S таким образом, чтобы уменьшать отклонение выходного параметра P от уставки.

unsigned16 action_flag=OFF_STOP;

Переменная action_flag описывает текущее функциональное состояние алгоритма (штатная работа, успешное либо ошибочное завершение цикла подстройки, останов). При инициализации устанавливается режим останова алгоритма (см. выше описание переменной semaphore).

unsigned16 contlost_limit, iteration_limit, error_limit;

Все три переменных являются декрементными счетчиками, которые инициализируются соответствующими константами. Переменная contlost_limit фиксирует число итераций с обнаружением потери управления. Если в пределах одного цикла подстройки их число превысит MAX_NO_CONTROL, цикл завершается с ошибкой потери управления. Счетчик iteration_limit ограничивает максимальное число итераций в одном цикле подстройки величиной MAX_ITERATIONS. Переменная error_limit ведет учет полного числа зафиксированных ошибок управления. Если оно превысит MAX_ERROR_STATUS, работа алгоритма будет остановлена.

unsigned16 period_tot, period_cnt;

Переменная period_tot хранит полное число тактов, которое алгоритм должен пропустить до проведения очередной итерации (время бездействия), а period_cnt является счетчиком этих тактов.

int32 contstep_max, control_step;

Переменная contstep_max задает максимальный шаг управляющего воздействия S в цикле подстройки. Ее значение положительно, отлично от нуля и оценивается, исходя из отклонения выходного параметра P от уставки и усредненной крутизны характеристики управления. Значение максимального шага дополнительно ограничивается константой STEP_MAX_CHAN. В переменной control_step рассчитывается текущее значение шага управления S.

int32 control_active, control_prev;

Переменная control_active содержит текущее значение управляющего воздействия, а в control_prev сохраняется величина S, которая была установлена до начала очередного цикла подстройки (итоговое значение предыдущего цикла).

int32 deviation_active, deviation_prev;

В переменной deviation_active содержится текущая величина отклонения от уставки выходного параметра P, а в deviation_prev – отклонение от уставки в предыдущей итерации алгоритма. Эти значения используются алгоритмом в интерполяционных расчетах, а конечной целью является сведение текущей величины отклонения deviation_active к нулю.

int32 parvalue_chan;

В переменную parvalue_chan заносится величина уставки, пересчитанная из физических единиц в дискретные (номер канала преобразователя сигнала датчика). Именно эту величину пытается установить алгоритм на выходе объекта путем regula-falsi манипуляций с управляющим воздействием S.

real64 parvalue_min, parvalue_max;

Переменные parvalue_min и parvalue_max используются для дополнительного конфигурирования алгоритма. Они задают минимальное и максимальное значения уставки, которые допустимы с точки зрения потребителя выходного сигнала объекта. Такие дополнительные ограничения полезны, если имеется определенное рассогласование возможностей объекта и потребностей его нагрузки. Например, когда объектом является источник питания, выходное напряжение либо ток которого заметно превышают величины, допустимые для конкретного потребителя. Если же упомянутого рассогласования не наблюдается, можно вполне ограничиться константами PARVALUE_MIN и PARVALUE_MAX.

int32 int32_abs(int32 di)   // ia_0
{
   if (di < 0) return -di;
   return di;
}

Функция int32_abs(di) возвращает абсолютное значение целого длиной 32 бита.

void write_control_active(void)   // wc_0
{

// Здесь необходимо организовать вывод на исполнительное устройство дискретного
// управляющего параметра S, представленного глобальной переменной control_active.

   period_tot = WAIT_CYCLE;       // wc_2
}

Функция write_control_active() осуществляет непосредственный вывод дискретного управляющего параметра S на исполнительное устройство. Затем устанавливается число тактов, которые должны быть пропущены алгоритмом до завершение переходного процесса в объекте [wc_2].

void write_status(int16 status)
{
}

Функция write_status(status) производит вывод статуса, зарегистрированного при работе алгоритма,- на индикатор, в полевую шину, в сеть и т.п.

void stop_control(void)   // sc_0
{
   action_flag = OFF_STOP;             // sc_2
   control_active = VALUE_SAFE_CHAN;   // sc_3
   write_control_active();             // sc_4
}

Функция stop_control() полностью останавливает работу алгоритма [sc_2]. При этом устанавливается “безопасное” значение управляющего параметра S [sc_3, sc_4]. Возобновление штатной работы возможно лишь путем явного задания уставки выходного параметра P0, для чего следует обратиться к функции order_parameter_value(value).

void error_status(int16 status)   // es_0
{
   write_status(status);
   action_flag = OFF_ERROR;              // es_3
   period_tot = ERROR_CYCLE;             // es_4
   if (error_limit > 0) error_limit--;   // es_5
   else stop_control();                  // es_6
}

Функция error_status(status) регистрирует статус ошибки, устанавливая соответствующее значение флага состояния [es_3] и времени бездействия алгоритма [es_4]. Таким образом, цикл подстройки завершается с ошибкой А когда их полное число превысит MAX_ERROR_STATUS, работа алгоритма будет остановлена [es_6].

int32 read_parameter_data(void)   // rd_0
{
   int32 data;

// Здесь следует произвести физическое измерение выходного
// параметра объекта и записать его в локальную переменную data.

   if (data < OUT_MIN_CHAN || data > OUT_MAX_CHAN) {   // rd_3
      error_status(STATUS_INPUT_LIM);                  // rd_4
      data = 0;                                        // rd_5
   }
   return data;                                        // rd_7
}

Функция read_parameter_data() возвращает измеренное дискретное значение выходного параметра P. При этом контролируется его нахождение в пределах динамического диапазона преобразователя [rd_3]. Такая проверка позволяет идентифицировать ситуации, когда ошибки управления вызваны неисправностями измерительного тракта или датчика.

void finish_control(void)   // fc_0
{
   int32 next;

   deviation_prev = deviation_active;                     // fc_4
   next = control_active + control_step;                  // fc_5
   if (next < CONTROL_MIN_CHAN) {                         // fc_6
      next = CONTROL_MIN_CHAN;                            // fc_7
      control_step = CONTROL_MIN_CHAN - control_active;   // fc_8
   } else if (next > CONTROL_MAX_CHAN) {                  // fc_9
      next = CONTROL_MAX_CHAN;                            // fc_10
      control_step = CONTROL_MAX_CHAN - control_active;   // fc_11
   }                                                      // fc_12
   if (control_step == 0) {                               // fc_13
      error_status(STATUS_CONTROL_LIM);                   // fc_14
   } else {
      control_active = next;                              // fc_16
      write_control_active();                             // fc_17
   }
}

Функция finish_control() завершает текущую итерацию и задает новое значение управляющего воздействия S. В [fc_4] сохраняется величина отклонения от уставки выходного параметра P для использования в последующей итерации алгоритма. В [fc_5] проводится оценка нового значения управляющего воздействия с последующим его ограничением минимальной [fc_6...fc_8] либо максимальной [fc_9...fc_11] дискретной величиной. В случае, если минимальная или максимальная величина параметра S уже была установлена, откорректированное значение шага управления принимает нулевое значение (переменная control_step в операторах [fc_8] либо [fc_11]). Это позволяет сделать вывод о выходе за пределы диапазона управляющего воздействия, что приводит к регистрации статуса ошибки [fc_13, fc_14] и прекращению выполнения текущего цикла подстройки. Если же параметр управления находится в пределах динамического диапазона, либо впервые выходит за границы, производится его установ на исполнительное устройство объекта [fc_16, fc_17].

void interpolate(void)   // ip_0
{
   int32 dev;
   real64 ra;

   dev = deviation_active - deviation_prev;                               // ip_5
   if (int32_abs(dev) <= int32_abs(control_step) / 2) {                   // ip_6
      if (contlost_limit > 0) {                                           // ip_7
         contlost_limit--;                                                // ip_8
         finish_control();                                                // ip_9
      } else {                                                            // ip_10
         error_status(STATUS_CONTROL_LOST);                               // ip_11
      }                                                                   // ip_12
      return;                                                             // ip_13
   }                                                                      // ip_14
   ra = -(real64)deviation_active * control_step / dev;                   // ip_15
   if (ra > -0.501 && ra < 0.501) {                                       // ip_16
      action_flag = OFF_OK;                                               // ip_17
      return;                                                             // ip_18
   }
   if (ra > 0.0) ra += 0.5;                                               // ip_20
   else ra -= 0.5;                                                        // ip_21
   control_step = (int32)ra;                                              // ip_22
   if (control_step > contstep_max) control_step = contstep_max;          // ip_23
   else if (control_step < -contstep_max) control_step = -contstep_max;   // ip_24
   if (dev * control_step > 0) tangent_flag = 1;                          // ip_25
   else tangent_flag = -1;                                                // ip_26
   finish_control();                                                      // ip_27
}

Функция interpolate() выполняет основные математические операции метода секущих. В переменой dev (строка [ip_5]) фиксируется итог выполнения предшествующей итерации алгоритма: изменение отклонения выходного параметра P от уставки. Именно отношение текущего шага управления к такому изменению (control_step/dev) определяет локальную крутизну характеристики C, на основе которой производится линейная интерполяция управляющего параметра.

В строках [ip_6...ip_14] контролируется ситуация потери управления. Ее признаком является снижение дискретной крутизны характеристики C ниже минимального (единичного) значения. Условие [ip_6] допускает снижение крутизны до половины от минимального значения, что гарантирует корректный расчет очередного шага управления [ip_15], [ip_22]. Вследствие локальной дифференциальной нелинейности характеристики C потеря управления может быть зарегистрирована в одной либо нескольких итерациях цикла подстройки. Это является допустимым и вызывает завершение текущей итерации с прежним шагом управляющего воздействия [ip_9]. Таким образом предпринимаются попытки выйти за пределы зоны потери управления. Если же допустимое число не управляемых итераций исчерпано, регистрируется статус ошибки [ip_11], что приводит к прекращению выполнения цикла подстройки.

В строке [ip_15] производится расчет шага управления для очередной итерации. Когда его значение становится менее либо равным ½, достигается предел по дискретности управляющего воздействия, что делает невозможным дальнейшее приближение выходного параметра к уставке. Это, в свою очередь, означает, что цикл подстройки можно завершать [ip_16..ip_18]. Поскольку шаг рассчитывается в формате реальных чисел, условие его проверки [ip_16] записано с небольшим запасом, что также гарантирует не нулевое значение нового шага управления [ip_22]. В строках [ip_20...ip_22] выполняется округление значения шага в предположении, что преобразование [ip_22] выполняется путем усечения реального значения до целого. Операторы [ip_23, ip_24] ограничивают величину шага максимальными для данного цикла подстройки значениями. В строках [ip_25, ip_26] определяется флаг наклона характеристики управления C. Он используется в начале каждого цикла подстройки для выбора такого знака пробного шага управляющего воздействия, подача которого приводила бы к уменьшению отклонения выходного параметра P от уставки. И хотя алгоритм предназначен для работы с монотонными характеристиками управления, наклон которых можно было бы установить однократно или даже задать константой, такое автоматическое определение не накладно и вполне удобно. Наконец, оператор [ip_27] завершает текущую итерацию, задавая новое значение управляющего воздействия S.

void first_iteration(void)   // fi_0
{
   action_flag = ON_WORK;              // fi_2
   iteration_limit = MAX_ITERATIONS;   // fi_3
   contlost_limit = MAX_NO_CONTROL;    // fi_4
   control_prev = control_active;      // fi_5
   contstep_max = int32_abs(deviation_active / OUT_TO_CONT);                // fi_6
   if (contstep_max == 0) contstep_max = 1;                                 // fi_7
   else if (contstep_max > STEP_MAX_CHAN) contstep_max = STEP_MAX_CHAN;     // fi_8
   if (tangent_flag * deviation_active > 0) control_step = -contstep_max;   // fi_9
   else control_step = contstep_max;                                        // fi_10
   finish_control();                                                        // fi_11
}

Функция first_iteration() инициирует новый цикл подстройки и выполняет его первую итерацию. В строках [fi_2...fi_4] устанавливаются начальные значения флагов и счетчиков. Оператор [fi_5] сохраняет значение управляющего воздействия на момент начала цикла, что позволит алгоритму восстановить прежнее значение параметра S случае, если подстройка завершится не удачно. В [fi_6] оценивается с усечением, а в [fi_7] и [fi_8] дополнительно ограничивается минимальное или максимальное положительное значение шага управления для нового цикла подстройки. Оценка исходит из соотношения отклонения выходного параметра от уставки и средней крутизны характеристики управления, что обеспечивает близкое к P0 значение выходного параметра после подачи максимального шага требуемого знака. Соответственно, абсолютная величина первого шага цикла приравнивается максимальной, а знак шага выбирается таким, чтобы его подача привела к уменьшению отклонения выходного параметра от уставки [fi_9, fi_10].

void process_parameter(void)   // pp_0
{
   deviation_active = read_parameter_data() - parvalue_chan;      // pp_2
   if (action_flag != ON_WORK) {                                  // pp_3
      if (int32_abs(deviation_active) > DEVIATION_MAX_CHAN) first_iteration();   // pp_4
      else period_tot = DUMMY_CYCLE;                              // pp_5
      return;                                                     // pp_6
   }                                                              // pp_7        
   interpolate();                                                 // pp_8
   if (action_flag == OFF_OK) {                                   // pp_9
      period_tot = DUMMY_CYCLE;                                   // pp_10
      return;                                                     // pp_11
   }
   if (iteration_limit > 0) iteration_limit--;                    // pp_13
   else error_status(STATUS_ITERATIONS_LIM);                      // pp_14
   if (action_flag == OFF_ERROR) {                                // pp_15
      if (int32_abs(deviation_active) > 2*DEVIATION_MAX_CHAN) {   // pp_16
         control_active = control_prev;                           // pp_17
         write_control_active();                                  // pp_18
      }                                                           // pp_19
   }
}                                                                 // pp_21

Функция process_parameter() выполняет логическую диспетчеризацию алгоритма. В [pp_2] определяется величина отклонения выходного параметра P от уставки, минимизация которого является основной задачей алгоритма. Операторы [pp_3...pp_7] анализируют необходимость запуска подстройки, когда алгоритма находится в состоянии бездействия (условие [pp_3]), Если отклонение выходного параметра от уставки превышает допустимое, осуществляется инициализация нового цикла подстройки [pp_4]. Если это отклонение оказывается в допустимых пределах, пере-устанавливается штатное время бездействия алгоритма [pp_5].

Последующие операторы ([pp_8] и далее) обслуживают итерации текущего цикла. Если очередная итерация привела к успешному завершению цикла подстройки [pp_9], устанавливается штатное время бездействия алгоритма [pp_10]. В противном случае подстройка будут продолжена. Оператор [pp_13, pp_14] контролирует возможное исчерпание полного числа итераций текущего цикла. А в [pp_15...pp_21] обрабатывается ситуация, когда цикл подстройки завершается с ошибкой. Если в результате такого цикла не удалось осуществить подстройку выходного параметра с достаточной точностью [pp_16], восстанавливается значение управляющего воздействия S, которое было установлено до начала безуспешного цикла подстройки [pp_17, pp_18].

void regula_falsi_main(void)   // rm_0
{
   if (action_flag == OFF_STOP) return;   // rm_2
   if (period_cnt > 0) {                  // rm_3
      period_cnt--;                       // rm_4
   } else {                               // rm_5
      process_parameter();                // rm_6
      period_cnt = period_tot;            // rm_7
   }
}

Функция regula_falsi_main() является временным диспетчером алгоритма. Оператор [rm_2] отрабатывает режим останова, а [rm_3, rm_4] отсчитывают время бездействия алгоритма. Последовательность операторов [rm_6, rm_7] существенна, поскольку значение переменной period_tot может изменяться в каждой итерации алгоритма.

void regula_falsi_periodic(void)   // rp_0
{
   semaphore++;
   if (semaphore == 0) regula_falsi_main();
   semaphore--;
}

Функция regula_falsi_periodic() служит источником тактирования алгоритма, временные циклы которого привязаны к периоду вызова этой функции. Cемафор semaphore обеспечивает сигналобезопасное исполнение итераций алгоритма (защиту от повторной входимости). Его использование необходимо, если алгоритм непосредственно тактируется асинхронными событиями, например, прерываниями таймера, не защищенными от взаимного наложения.

void order_parameter_value(real64 value)   // op_0
{
   if (value < parvalue_min || value > parvalue_max) {      // op_2
       write_status(STATUS_VALUE_ERROR);
       return;
   }                                                        // op_5
   action_flag = OFF_STOP;                                  // op_6
   parvalue_chan = OUT_MIN_CHAN + (int32)((value - PARVALUE_MIN) * \
                   OUT_RANGE_CHAN / PARVALUE_RANGE_FULL);   // op_7
   period_tot = WAIT_CYCLE;                                 // op_8
   period_cnt = period_tot;                                 // op_9
   error_limit = MAX_ERROR_STATUS;                          // op_10
   action_flag = OFF_OK;                                    // op_11
}

Функция order_parameter_value(value) принимает новое значение уставки выходного параметра P0. В строках [op_2...op_5] проверяется нахождение уставки в пределах диапазона ограничения. При успешном завершении проверки работа алгоритма приостанавливается [op_6], чтобы состоятельность его параметров не могла быть нарушена вследствие возможного прохождения итерации алгоритма во время задания уставки. Оператор [op_7] выполняет функцию калибровки датчика, то есть пересчитывает значение уставки, заданое в физических единицах в соответствующий этому значению номер канала дискретного преобразователя. В нашем примере расчет выполняется, исходя из линейного отображения полного диапазона физических значений в полный диапазон дискретных каналов. Далее инициализируются переменные, управляющие работой алгоритма: число и счетчик тактов [op_8, op_9] и предельное число ошибок управления [op_10]. Затем алгоритм запускается в штатную работу [op_11]. Таким образом, если работа алгоритма была остановлена вследствие превышения допустимого числа ошибок управления, для его запуска достаточно вновь задать значение уставки. Если функция order_parameter_value(value) может вызываться асинхронно, в том числе непосредственно во время выполнения итераций алгоритма, целесообразно использовать в качестве счетчика тактов алгоритма period_cnt переменную со знаком (см. главу «Счетчики» раздела Малые замечания).

void init_regula_falsi(void)   // ir_0
{
   stop_control();                // ir_2
   parvalue_min = PARVALUE_MIN;   // ir_3
   parvalue_max = PARVALUE_MAX;   // ir_4
   tangent_flag = 1;              // ir_5
   semaphore = -1;                // ir_6
}

Функция начальной инициализации init_regula_falsi() устанавливает состояние останова алгоритма [ir_2]. Затем инициализируются переменные-ограничители диапазона уставки [ir_3, ir_4], устанавливается наобум одно из возможных значений флага наклона характеристики управления (оно будет откорректировано в [ip_25, ip_26] функции interpolate()) и, наконец, открывается семафор тактирования алгоритма [ir_6]. Теперь достаточно задать уставку выходного параметра P0, обратившись к функции order_parameter_value(value) и алгоритм приступит к работе.