© 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 используется для поиска изолированных корней алгебраических уравнений. При этом во всем диапазоне поиска исследуемая функция должна вести себя монотонно, то есть ее первая производная не должна изменять знака. Математический смысл алгоритма заключается в линейной интерполяции функции С на каждом шаге исследования (см. рисунок). В контуре дискретного управления метод секущих удобно использовать для установа и поддержания долговременной стабильности выходного параметра объекта, а также компенсации нелинейности его статической характеристики.
Основанный на методе ложного положения алгоритм инициирует новый цикл подстройки выходного параметра P, когда его отклонение от уставки P0 превышает максимально допустимое. Критерием завершения цикла является итерация, в которой рассчитанное по методу секущих смещение управляющего параметра S становится менее половины минимального шага управления. Помимо основного метода алгоритм должен содержать дополнительную логику, придающую ему достаточную устойчивость при работе в управляющей среде. Как правило, программные затраты на реализацию такой логической обвязки заметно превышают объем кода, отвечающего собственно за математический метод. А итоговое качество управления решающим образом зависит от продуманности и тщательности логических решений, обрамляющих основной алгоритм.
В приведенной реализации метода секущих принимаются следующие меры повышения устойчивости управления:
Алгоритм адаптивно ограничивает максимальный шаг управления в каждом цикле подстройки. Допустимое приращение S определяется в начале цикла из соотношения рассогласования управляемого параметра с уставкой (P - P0) и усредненной крутизны характеристики управления (Pmax-Pmin)/(Smax-Smin).
В каждой итерации алгоритма контролируется изменение управляемого параметра P. Если оно оказывается слишком малым в нескольких итерациях, регистрируется потеря управления и цикл подстройки завершается с ошибкой.
Если цикл подстройки завершился с ошибкой и при этом отклонение параметра P от уставки P0 превышает допустимую величину, алгоритм восстанавливает значение управляющего воздействия S, которое было установлено до начала цикла.
Когда полное число ошибок управления становится слишком большим, алгоритм прекращает работу, переходя в состояние ожидания. Такое происходит, например, при отключении или аппаратной неисправности объекта управления.
Алгоритм использует результат дискретных измерений управляемого параметра 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) и алгоритм приступит к работе.