diff --git a/Core/Src/main.c b/Core/Src/main.c index ab0a8b8..90070cb 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -74,7 +74,7 @@ void PeriphCommonClock_Config(void); * @retval int */ int main(void) -{ + { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/MDK-ARM/RTE/_controller-v2/RTE_Components.h b/MDK-ARM/RTE/_controller-v2/RTE_Components.h index 391636b..481bf87 100644 --- a/MDK-ARM/RTE/_controller-v2/RTE_Components.h +++ b/MDK-ARM/RTE/_controller-v2/RTE_Components.h @@ -1,6 +1,6 @@ /* - * Auto generated Run-Time-Environment Configuration File + * Auto generated Run-Time-Environment Component Configuration File * *** Do not modify ! *** * * Project: 'controller-v2' @@ -17,5 +17,4 @@ #define CMSIS_device_header "stm32l4xx.h" - #endif /* RTE_COMPONENTS_H */ diff --git a/MDK-ARM/controller-v2.uvoptx b/MDK-ARM/controller-v2.uvoptx index 090f79f..f059961 100644 --- a/MDK-ARM/controller-v2.uvoptx +++ b/MDK-ARM/controller-v2.uvoptx @@ -114,13 +114,13 @@ - STLink\ST-LINKIII-KEIL_SWO.dll + Segger\JL2CM3.dll 0 DLGUARM - (105=-1,-1,-1,-1,0) + ? 0 @@ -260,6 +260,26 @@ 1 s_watch,0x0A + + 20 + 1 + uDevice.ProcessChange_Flag,0x0A + + + 21 + 1 + Kp_watch + + + 22 + 1 + Ki_watch + + + 23 + 1 + Kd_watch + 0 @@ -305,7 +325,6 @@ 1 - 0 0 2 10000000 diff --git a/MDK-ARM/controller-v2.uvprojx b/MDK-ARM/controller-v2.uvprojx index 263e7a2..2573059 100644 --- a/MDK-ARM/controller-v2.uvprojx +++ b/MDK-ARM/controller-v2.uvprojx @@ -10,14 +10,14 @@ controller-v2 0x4 ARM-ADS - 5060960::V5.06 update 7 (build 960)::.\ARMCC + 5060061::V5.06 update 1 (build 61)::ARMCC 0 STM32L476VGTx STMicroelectronics - Keil.STM32L4xx_DFP.2.6.2 - https://www.keil.com/pack/ + Keil.STM32L4xx_DFP.2.1.0 + http://www.keil.com/pack IRAM(0x20000000,0x00018000) IRAM2(0x10000000,0x00008000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 DSP CLOCK(12000000) ELITTLE @@ -184,8 +184,6 @@ 0 0 1 - 0 - 0 1 0 8 @@ -352,7 +350,7 @@ 0 0 0 - 4 + 0 @@ -993,7 +991,7 @@ 2 2 2 - 0 + 2 @@ -1045,8 +1043,8 @@ STM32L476VGTx STMicroelectronics - Keil.STM32L4xx_DFP.2.6.2 - https://www.keil.com/pack/ + Keil.STM32L4xx_DFP.2.1.0 + http://www.keil.com/pack IRAM(0x20000000,0x00018000) IRAM2(0x10000000,0x00008000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 DSP CLOCK(12000000) ELITTLE @@ -1213,8 +1211,6 @@ 0 0 1 - 0 - 0 1 0 8 @@ -1381,7 +1377,7 @@ 0 0 0 - 4 + 0 @@ -1884,8 +1880,8 @@ STM32L476VGTx STMicroelectronics - Keil.STM32L4xx_DFP.2.6.2 - https://www.keil.com/pack/ + Keil.STM32L4xx_DFP.2.1.0 + http://www.keil.com/pack IRAM(0x20000000,0x00018000) IRAM2(0x10000000,0x00008000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 DSP CLOCK(12000000) ELITTLE @@ -2052,8 +2048,6 @@ 0 0 1 - 0 - 0 1 0 8 @@ -2220,7 +2214,7 @@ 0 0 0 - 4 + 0 @@ -2309,7 +2303,7 @@ 2 2 2 - 0 + 2 @@ -2388,7 +2382,7 @@ 2 2 2 - 0 + 2 @@ -2512,7 +2506,7 @@ 2 2 2 - 0 + 2 @@ -2646,7 +2640,7 @@ 2 2 2 - 0 + 2 @@ -2725,7 +2719,7 @@ 2 2 2 - 0 + 2 @@ -2814,7 +2808,7 @@ 2 2 2 - 0 + 2 @@ -2943,7 +2937,7 @@ 2 2 2 - 0 + 2 @@ -3052,7 +3046,7 @@ 2 2 2 - 0 + 2 @@ -3231,7 +3225,7 @@ 2 2 2 - 0 + 2 @@ -3340,7 +3334,7 @@ 2 2 2 - 0 + 2 diff --git a/MDK-ARM/controller-v2/controller-v2.4 b/MDK-ARM/controller-v2/controller-v2.4 index cb3d077..d64ddf7 100644 Binary files a/MDK-ARM/controller-v2/controller-v2.4 and b/MDK-ARM/controller-v2/controller-v2.4 differ diff --git a/User/application/inc/mode_pwmp_hd.h b/User/application/inc/mode_pwmp_hd.h index fa51f48..a69483e 100644 --- a/User/application/inc/mode_pwmp_hd.h +++ b/User/application/inc/mode_pwmp_hd.h @@ -11,12 +11,8 @@ #define TIME_CYCLE 0.01f // 定义时间周期:10ms #define FSM_WAIT(st) BIT_SET(st, BIT7) #define FSM_IS_WAIT(st) (st & BIT7) -#define DIFF_ADC_MAX 6U +#define DIFF_ADC_MAX 10U -/*阶跃信号大小*/ -#define FULL_TRIP_SIGNAL 925 // 925 2020 -#define HALF_TRIP_SIGNAL 753 -#define SMALL_TRIP_SIGNAL 650 ///////////////////////////////////////*算法整定部分宏定义END*/////////////////////////////////////////// #define EXECUTE_PLAN EXECUTE_PLAN_1 @@ -36,12 +32,13 @@ typedef struct uint8_t tuned_flag; // 是否整定过 1:整定过 0:未整定过 uint8_t tuned_state; // 自整定结果 - uint16_t bleeding; // 放气值 - uint16_t inflation; // 充气值 + uint16_t startup_value; // 阀位启动值 uint16_t arr_diff; // 控制区间 uint16_t ad_diff; // 磁条区间 uint16_t pwmp_min; // 控制最小值 uint16_t pwmp_max; // 控制最大值 + uint16_t pwmp_min_origin;// 整定控制最小值 + uint16_t pwmp_max_origin;// 整定控制最大值 uint16_t trip_0; // 磁条0位置AD uint16_t trip_100; // 词条100位置AD uint16_t trip_min0; // 小回路行程0位置AD @@ -111,6 +108,8 @@ typedef enum PWMP_HD_ADJUST_ACCURATE_POSITION0, // 精调位置0 PWMP_HD_ADJUST_ROUGH_POSITION100, // 粗调位置100 PWMP_HD_ADJUST_ACCURATE_POSITION100, // 精调位置100 + PWMP_HD_ADJUST_ALL_CLOSE_TIME, // 全关时间 + PWMP_HD_ADJUST_ALL_OPEN_TIME, // 全开时间 PWMP_HD_ADJUST_CALCULATE, // 阀门参数计算 PWMP_HD_ADJUST_PID_CALCULATE, // PID参数计算 PWMP_HD_ADJUST_PID_TUNING, // PID参数自整定过程(整定得到K、T、L) @@ -155,8 +154,9 @@ typedef struct uint16_t arr_record_1; // 最小推动阀门的ad值 uint16_t arr_record_2; // 最大位置阀门的ad值 - uint32_t all_open_time; // 全开时间 - uint32_t all_close_time; // 全关时间 + uint32_t all_open_time; // 全开时间 + uint32_t all_open_time_full; // 信号为最大输出时的全开时间 + uint32_t all_close_time; // 全关时间 BOOL all_close_time_flag; uint32_t tmp_time; // 临时用来记录全开全关/整定时间 diff --git a/User/application/src/mode_pwmp_hd.c b/User/application/src/mode_pwmp_hd.c index 0dc709f..1487a20 100644 --- a/User/application/src/mode_pwmp_hd.c +++ b/User/application/src/mode_pwmp_hd.c @@ -84,9 +84,9 @@ static void pwmp_control_update(filter_e type) } /*PID参数获取*/ -static float32 get_pwmp_control_kp(void) +static float32 get_pwmp_hd_control_kp(void) { - if (mode_pwmp_hd->pwmp_save->storage.kp < 1) + if (mode_pwmp_hd->pwmp_save->storage.kp < 2) { return mode_pwmp_hd->pwmp_save->storage.kp * 10; } @@ -96,14 +96,14 @@ static float32 get_pwmp_control_kp(void) } } -static float32 get_pwmp_control_ki(void) +static float32 get_pwmp_hd_control_ki(void) { - return mode_pwmp_hd->pwmp_save->storage.ki; + return mode_pwmp_hd->pwmp_save->storage.ki < 0.001 ? mode_pwmp_hd->pwmp_save->storage.ki * 10 : 0.018; } -static float32 get_pwmp_control_kd(void) +static float32 get_pwmp_hd_control_kd(void) { - return mode_pwmp_hd->pwmp_save->storage.kd; + return mode_pwmp_hd->pwmp_save->storage.kd < 0.01 ? mode_pwmp_hd->pwmp_save->storage.kd : 0.005; } /*将自己结构体变量中的参数保存到公共参数中*/ @@ -206,7 +206,7 @@ void execute_pid_init(execute_plan_hd_e plan) case EXECUTE_PLAN_1: _pid.type = PID_TYPE_CUSTOM_HANGDIAN; pid_constructor(&_pid); - _pid.pid_u.hd.set_ctrl_prm_position(&_pid.pid_u.hd, get_pwmp_control_kp(), get_pwmp_control_ki(), get_pwmp_control_kd()); + _pid.pid_u.hd.set_ctrl_prm_position(&_pid.pid_u.hd, get_pwmp_hd_control_kp(), get_pwmp_hd_control_ki(), get_pwmp_hd_control_kd()); break; case EXECUTE_PLAN_2: @@ -352,12 +352,6 @@ static void pid_autotune_way_set(pid_autotune_way_e state) pid_autotune_hd->autotune_way = state; } -/*阶跃信号设定*/ -static void set_step_signal(uint16_t signal_in) -{ - pdctrl_out(signal_in); -} - /*判断阀门状态:移动、停止、停止但仍在等待*/ static valve_position_change_e pwmp_adjust_hd_valve_position_change(uint8_t *state, uint8_t next_state, uint8_t diff_adc_max) { @@ -443,8 +437,8 @@ static void pwmp_adjust_hd_idle(uint8_t *state, mode_pwmp_hd_adjust_state_e next { case POSITION_NO_CHANGE_FOREVER: // 位置不再改变,记录此时阀门位置AD值 - mode_pwmp_hd_adjust->adc_record_1 = mode_pwmp_hd_adjust->psb_adc; - mode_pwmp_hd_adjust->adc_record_0 = mode_pwmp_hd_adjust->psb_adc; + mode_pwmp_hd_adjust->adc_record_1 = pid_autotune_hd->data.adjust_tmp_actual; + mode_pwmp_hd_adjust->adc_record_0 = pid_autotune_hd->data.adjust_tmp_actual; break; case POSITION_CHANGE: *state = PWMP_HD_ADJUST_IDEL; @@ -460,13 +454,11 @@ static void pwmp_adjust_hd_idle(uint8_t *state, mode_pwmp_hd_adjust_state_e next /*整定粗调0*/ static void pwmp_adjust_hd_rough_position0(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) { - // 找最小推动值arr uint16_t current_adc = 0; - if (!FSM_IS_WAIT(*state)) { // 以10%增加,提高DAC输出,找到能推动阀门的最小值 - mode_pwmp_hd_adjust->arr_current = 50; + mode_pwmp_hd_adjust->arr_current = 100; mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; pdctrl_out(mode_pwmp_hd_adjust->arr_current); mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 20; @@ -477,8 +469,8 @@ static void pwmp_adjust_hd_rough_position0(uint8_t *state, mode_pwmp_hd_adjust_s { valve_position_change_e s = pwmp_adjust_hd_valve_position_change(state, next_state, DIFF_ADC_MAX); - current_adc = mode_pwmp_hd_adjust->psb_adc; - if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_1) >= DIFF_ADC_MAX) + current_adc = pid_autotune_hd->data.adjust_tmp_actual; + if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_1) >= DIFF_ADC_MAX) // 阀位发生改变 { if (mode_pwmp_hd_adjust->arr_last > 4000) { @@ -487,14 +479,14 @@ static void pwmp_adjust_hd_rough_position0(uint8_t *state, mode_pwmp_hd_adjust_s } else { - /*修正因启动值过大而导致的信号增加过大*/ + /*得到一个粗略的,小于启动量的值*/ mode_pwmp_hd_adjust->arr_record_1 = mode_pwmp_hd_adjust->arr_last > 1000 ? mode_pwmp_hd_adjust->arr_last * 0.9 : mode_pwmp_hd_adjust->arr_last; - /**/ + /*判断位置反馈磁条是正装还是反装*/ mode_pwmp_hd_adjust->adc_0_100_flag = mode_pwmp_hd_adjust->adc_record_0 < current_adc ? TRUE : FALSE; } *state = next_state; } - else + else // 阀位未发生变化:继续增大输出 { switch (s) { @@ -507,11 +499,11 @@ static void pwmp_adjust_hd_rough_position0(uint8_t *state, mode_pwmp_hd_adjust_s mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; if (mode_pwmp_hd_adjust->arr_last < 1000) { - mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_current * 1.1; + mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_current * 1.05; } else { - mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_current * 1.05; + mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_current * 1.02; } /*若输出信号为最大值时认定为整定错误*/ if (mode_pwmp_hd_adjust->arr_current > 4000) @@ -522,7 +514,7 @@ static void pwmp_adjust_hd_rough_position0(uint8_t *state, mode_pwmp_hd_adjust_s } pdctrl_out(mode_pwmp_hd_adjust->arr_current); - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 20; + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 40; *state = PWMP_HD_ADJUST_ROUGH_POSITION0; FSM_WAIT(*state); // 设置等待状态 } @@ -546,7 +538,7 @@ static void pwmp_adjust_hd_rough_position0(uint8_t *state, mode_pwmp_hd_adjust_s } } -/*不充不放值(0信号)的整定*/ +/*放气值(0信号)的整定*/ static void pwmp_adjust_hd_bleeding_position0(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) { BOOL flag = FALSE; @@ -560,32 +552,41 @@ static void pwmp_adjust_hd_bleeding_position0(uint8_t *state, mode_pwmp_hd_adjus } else { - if (mode_pwmp_hd_adjust->adc_0_100_flag) + // if (mode_pwmp_hd_adjust->adc_0_100_flag) + // { + // if (mode_pwmp_hd_adjust->psb_adc <= mode_pwmp_hd_adjust->last_adc) + // { + // if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->last_adc) > DIFF_ADC_MAX) + // { + // mode_pwmp_hd_adjust->arr_record_0 = mode_pwmp_hd_adjust->arr_last + DIFF_ADC_MAX; + // flag = TRUE; + // } + // } + // } + // else + // { + // if (mode_pwmp_hd_adjust->psb_adc >= mode_pwmp_hd_adjust->last_adc) + // { + // if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->last_adc) > DIFF_ADC_MAX) + // { + // mode_pwmp_hd_adjust->arr_record_0 = mode_pwmp_hd_adjust->arr_last + DIFF_ADC_MAX; + // flag = TRUE; + // } + // } + // } + + if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->adc_record_1) < 6) { - if (mode_pwmp_hd_adjust->psb_adc <= mode_pwmp_hd_adjust->last_adc) - { - if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->last_adc) > DIFF_ADC_MAX) - { - mode_pwmp_hd_adjust->arr_record_0 = mode_pwmp_hd_adjust->arr_last + DIFF_ADC_MAX; - flag = TRUE; - } - } - } - else - { - if (mode_pwmp_hd_adjust->psb_adc >= mode_pwmp_hd_adjust->last_adc) - { - if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->last_adc) > DIFF_ADC_MAX) - { - mode_pwmp_hd_adjust->arr_record_0 = mode_pwmp_hd_adjust->arr_last + DIFF_ADC_MAX; - flag = TRUE; - } - } + mode_pwmp_hd_adjust->arr_record_0 = mode_pwmp_hd_adjust->arr_current; + flag = TRUE; } if (flag == TRUE) { + mode_pwmp_hd_adjust->arr_record_2 = 4095; // 给定最大值输出 *state = next_state; + pdctrl_out(0); // 这里要先放气5秒然后计算全开时间 + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 50; } else { @@ -597,13 +598,13 @@ static void pwmp_adjust_hd_bleeding_position0(uint8_t *state, mode_pwmp_hd_adjus mode_pwmp_hd_adjust->arr_current = last - 4; pdctrl_out(mode_pwmp_hd_adjust->arr_current); - if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->last_adc) > 4) + if (ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->last_adc) > 6) { - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 10; + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 10; } else { - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 30; + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 30; } mode_pwmp_hd_adjust->last_adc = mode_pwmp_hd_adjust->psb_adc; @@ -612,68 +613,69 @@ static void pwmp_adjust_hd_bleeding_position0(uint8_t *state, mode_pwmp_hd_adjus } } -/*启动值细调*/ -static void pwmp_adjust_hd_accurate_position0(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) -{ - // 精确的找到最小推动值 - uint16_t current_adc = 0; - if (!FSM_IS_WAIT(*state)) - { - mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_record_1; - mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; - mode_pwmp_hd_adjust->adjust_state = (mode_pwmp_hd_adjust_state_e)*state; - FSM_WAIT(mode_pwmp_hd_adjust->adjust_state); - *state = PWMP_HD_ADJUST_BLEEDING; - } - else - { - valve_position_change_e s = pwmp_adjust_hd_valve_position_change(state, next_state, DIFF_ADC_MAX * 10); +// /*启动值细调*/ +// static void pwmp_adjust_hd_accurate_position0(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) +// { +// uint16_t current_adc = 0; +// if (!FSM_IS_WAIT(*state)) +// { +// mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_record_1; +// mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; +// mode_pwmp_hd_adjust->adjust_state = (mode_pwmp_hd_adjust_state_e)*state; +// FSM_WAIT(mode_pwmp_hd_adjust->adjust_state); +// *state = PWMP_HD_ADJUST_BLEEDING; +// } +// else +// { +// valve_position_change_e s = pwmp_adjust_hd_valve_position_change(state, next_state, DIFF_ADC_MAX); - current_adc = mode_pwmp_hd_adjust->psb_adc; - /*执行器发生动作*/ - if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_1) >= DIFF_ADC_MAX) - { - mode_pwmp_hd_adjust->arr_record_1 = mode_pwmp_hd_adjust->arr_last; - mode_pwmp_hd_adjust->arr_record_2 = mode_pwmp_hd_adjust->arr_last + 100 < 4000 ? mode_pwmp_hd_adjust->arr_last + 100 : 100; - *state = next_state; - pdctrl_out(0); // 这里要先放气5秒然后计算全开时间 - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 50; - } - else - { - switch (s) - { - case POSITION_NO_CHANGE_FOREVER: // 位置不再改变 - { - if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_1) <= DIFF_ADC_MAX) - { - // 没有发生变化 - mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; - mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_current + DIFF_ADC_MAX; - pdctrl_out(mode_pwmp_hd_adjust->arr_current); - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 5; - *state = PWMP_HD_ADJUST_ACCURATE_POSITION0; - FSM_WAIT(*state); // 设置等待状态 - } - else - { - DBG_ASSERT(FALSE __DBG_LINE); - } - break; - } - case POSITION_CHANGE: - DBG_ASSERT(FALSE __DBG_LINE); - break; - default: - break; - } - } - } -} +// current_adc = pid_autotune_hd->data.adjust_tmp_actual; +// /*执行器发生动作*/ +// if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_1) >= DIFF_ADC_MAX) +// { +// mode_pwmp_hd_adjust->arr_record_1 = mode_pwmp_hd_adjust->arr_last; +// mode_pwmp_hd_adjust->arr_record_2 = 4095; // 给定最大值输出 +// *state = next_state; +// pdctrl_out(0); // 这里要先放气5秒然后计算全开时间 +// mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 50; +// } +// else +// { +// switch (s) +// { +// case POSITION_NO_CHANGE_FOREVER: // 位置不再改变 +// { +// /*若执行器在0位置*/ +// if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_1) <= DIFF_ADC_MAX) +// { +// // 阀位没有发生变化,以每6增大信号输出 +// mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; +// mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_current + 6; +// pdctrl_out(mode_pwmp_hd_adjust->arr_current); +// mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 30; +// *state = PWMP_HD_ADJUST_ACCURATE_POSITION0; +// FSM_WAIT(*state); // 设置等待状态 +// } +// else +// { +// DBG_ASSERT(FALSE __DBG_LINE); +// } +// break; +// } +// case POSITION_CHANGE: +// DBG_ASSERT(FALSE __DBG_LINE); +// break; +// default: +// break; +// } +// } +// } +// } -/*粗略整定冲顶值*/ +/*粗略整定得到满位置adc位置反馈*/ static void pwmp_adjust_hd_rough_position100(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) { + uint16_t current_adc = 0; // 找最大推动值arr if (!FSM_IS_WAIT(*state)) { @@ -685,24 +687,25 @@ static void pwmp_adjust_hd_rough_position100(uint8_t *state, mode_pwmp_hd_adjust } sys_millis_reset(); - mode_pwmp_hd_adjust->all_open_time = sys_millis(); // 记录全开起始时间 + mode_pwmp_hd_adjust->all_open_time_full = sys_millis(); // 记录全开起始时间 mode_pwmp_hd_adjust->tmp_time = 0; - pdctrl_out(mode_pwmp_hd_adjust->arr_record_2); // 以上一步求出的冲顶值进行输出 - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 100; + pdctrl_out(mode_pwmp_hd_adjust->arr_record_2); // 以最大值进行输出 + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 50; // 等待时间设置为5s mode_pwmp_hd_adjust->adjust_state = (mode_pwmp_hd_adjust_state_e)*state; FSM_WAIT(*state); // 设置等待状态 } else { valve_position_change_e s = pwmp_adjust_hd_valve_position_change(state, next_state, DIFF_ADC_MAX); + current_adc = pid_autotune_hd->data.adjust_tmp_actual; switch (s) { case POSITION_NO_CHANGE_FOREVER: // 位置不再改变,记录此时阀门位置AD值 - mode_pwmp_hd_adjust->adc_record_2 = mode_pwmp_hd_adjust->psb_adc; - mode_pwmp_hd_adjust->all_open_time = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_open_time; + mode_pwmp_hd_adjust->adc_record_2 = current_adc; + mode_pwmp_hd_adjust->all_open_time_full = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_open_time_full; break; case POSITION_CHANGE: mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 50; @@ -723,13 +726,10 @@ static void pwmp_adjust_hd_rough_position100(uint8_t *state, mode_pwmp_hd_adjust /*精调冲顶值*/ static void pwmp_adjust_hd_accurate_position100(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) { - // 精确找最大推动值arr - uint16_t current_adc = 0; if (!FSM_IS_WAIT(*state)) { mode_pwmp_hd_adjust->all_close_time_flag = TRUE; - - mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_record_1; + mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_record_1; // 初始值为前一步整定出的最小启动值 mode_pwmp_hd_adjust->arr_last = mode_pwmp_hd_adjust->arr_current; mode_pwmp_hd_adjust->adjust_state = (mode_pwmp_hd_adjust_state_e)*state; mode_pwmp_hd_adjust->preheat = TRUE; @@ -739,9 +739,10 @@ static void pwmp_adjust_hd_accurate_position100(uint8_t *state, mode_pwmp_hd_adj else { valve_position_change_e s = pwmp_adjust_hd_valve_position_change(state, next_state, DIFF_ADC_MAX); + mode_pwmp_hd_adjust->psb_adc = pid_autotune_hd->data.adjust_tmp_actual; - current_adc = mode_pwmp_hd_adjust->psb_adc; - uint16_t adc_diff = ABS(current_adc - mode_pwmp_hd_adjust->adc_record_2); + /*当前反馈AD值与最大位置AD值的差值*/ + uint16_t adc_diff = ABS(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->adc_record_2); if (mode_pwmp_hd_adjust->arr_current == 0 && mode_pwmp_hd_adjust->preheat == TRUE) { @@ -775,7 +776,7 @@ static void pwmp_adjust_hd_accurate_position100(uint8_t *state, mode_pwmp_hd_adj } else { - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 10; + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 20; } mode_pwmp_hd_adjust->last_adc = mode_pwmp_hd_adjust->psb_adc; @@ -796,7 +797,7 @@ static void pwmp_adjust_hd_accurate_position100(uint8_t *state, mode_pwmp_hd_adj } else { - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 3; + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 20; } break; @@ -806,19 +807,100 @@ static void pwmp_adjust_hd_accurate_position100(uint8_t *state, mode_pwmp_hd_adj } } +/*计算控制的全关时间:以ATO类型角度命名*/ +static void pwmp_adjust_hd_all_close_time(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) +{ + if (!FSM_IS_WAIT(*state)) + { + mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_record_0 - 100; // 此处的输入信号大小根据实际控制的最小值来设定 + + /*记录起始的全开时间*/ + sys_millis_reset(); + mode_pwmp_hd_adjust->all_close_time = sys_millis(); + mode_pwmp_hd_adjust->tmp_time = 0; + + pdctrl_out(mode_pwmp_hd_adjust->arr_current); + FSM_WAIT(*state); // 设置等待状态 + } + else + { + mode_pwmp_hd_adjust->psb_adc = get_actual_travel_adc(); + if (abs(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->adc_record_0) < DIFF_ADC_MAX) + { + if (uDevice.eAirAction == ATO) // 若调节阀为气开阀 + { + mode_pwmp_hd_adjust->tmp_time = sys_millis(); + mode_pwmp_hd_adjust->all_close_time = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_close_time; + } + else // 若调节阀为气关阀 + { + mode_pwmp_hd_adjust->tmp_time = sys_millis(); + mode_pwmp_hd_adjust->all_open_time = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_close_time; + } + *state = next_state; + } + } +} + +/*计算控制的全开时间*/ +static void pwmp_adjust_hd_all_open_time(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) +{ + if (!FSM_IS_WAIT(*state)) + { + mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_record_2 + 100; // 此处的输入信号大小根据实际控制的最大值来设定 + + /*记录起始的全开时间*/ + sys_millis_reset(); + mode_pwmp_hd_adjust->all_open_time = sys_millis(); + mode_pwmp_hd_adjust->tmp_time = 0; + + pdctrl_out(mode_pwmp_hd_adjust->arr_current); + FSM_WAIT(*state); // 设置等待状态 + } + else + { + mode_pwmp_hd_adjust->psb_adc = get_actual_travel_adc(); + if (abs(mode_pwmp_hd_adjust->psb_adc - mode_pwmp_hd_adjust->adc_record_2) < DIFF_ADC_MAX) + { + if (uDevice.eAirAction == ATO) + { + mode_pwmp_hd_adjust->tmp_time = sys_millis(); + mode_pwmp_hd_adjust->all_open_time = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_open_time; + } + else + { + mode_pwmp_hd_adjust->tmp_time = sys_millis(); + mode_pwmp_hd_adjust->all_close_time = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_open_time; + } + *state = next_state; + } + } +} + /*计算阀门自整定参数*/ static void pwmp_adjust_hd_calculate(uint8_t *state, mode_pwmp_hd_adjust_state_e next_state) { if (!FSM_IS_WAIT(*state)) { + /*行程上下限*/ mode_pwmp_hd->pwmp_save->storage.trip_0 = mode_pwmp_hd_adjust->adc_record_0; mode_pwmp_hd->pwmp_save->storage.trip_100 = mode_pwmp_hd_adjust->adc_record_2; mode_pwmp_hd->pwmp_save->storage.ad_diff = ABS(mode_pwmp_hd->pwmp_save->storage.trip_0 - mode_pwmp_hd->pwmp_save->storage.trip_100); - mode_pwmp_hd->pwmp_save->storage.pwmp_max = mode_pwmp_hd_adjust->arr_record_2; - mode_pwmp_hd->pwmp_save->storage.pwmp_min = mode_pwmp_hd_adjust->arr_record_0; - mode_pwmp_hd->pwmp_save->storage.arr_diff = ABS(mode_pwmp_hd->pwmp_save->storage.pwmp_max - mode_pwmp_hd->pwmp_save->storage.pwmp_min); + /*控制区间*/ + mode_pwmp_hd->pwmp_save->storage.pwmp_max_origin = mode_pwmp_hd_adjust->arr_record_2; + mode_pwmp_hd->pwmp_save->storage.pwmp_min_origin = mode_pwmp_hd_adjust->arr_record_0; + mode_pwmp_hd->pwmp_save->storage.arr_diff = ABS(mode_pwmp_hd_adjust->arr_record_2 - mode_pwmp_hd_adjust->arr_record_0); + mode_pwmp_hd->pwmp_save->storage.pwmp_max = mode_pwmp_hd_adjust->arr_record_2 + (mode_pwmp_hd->pwmp_save->storage.arr_diff * 0.2); + mode_pwmp_hd->pwmp_save->storage.pwmp_min = mode_pwmp_hd_adjust->arr_record_0 - (mode_pwmp_hd->pwmp_save->storage.arr_diff * 0.2); + /*启动值*/ + mode_pwmp_hd->pwmp_save->storage.startup_value = mode_pwmp_hd_adjust->adc_record_1; + + /*全开及全关时间*/ + mode_pwmp_hd->pwmp_save->storage.all_open_time = mode_pwmp_hd_adjust->all_open_time; + mode_pwmp_hd->pwmp_save->storage.all_close_time = mode_pwmp_hd_adjust->all_close_time; + /*判断调节阀类型(气开/气关),对最低行程和最高行程进行标定*/ if (uDevice.eAirAction == ATO) { mode_pwmp_hd->pwmp_save->storage.trip_100 = mode_pwmp_hd->pwmp_save->storage.trip_100; @@ -859,15 +941,8 @@ static void pwmp_adjust_hd_calculate(uint8_t *state, mode_pwmp_hd_adjust_state_e /*排气状态*/ static void pwmp_adjust_hd_bleeding(uint8_t *state) { - uint16_t current_adc = 0; if (!FSM_IS_WAIT(*state)) { - if (mode_pwmp_hd_adjust->all_close_time_flag == TRUE) - { - sys_millis_reset(); - mode_pwmp_hd_adjust->all_close_time = sys_millis(); // 记录全关起始时间 - mode_pwmp_hd_adjust->tmp_time = 0; - } mode_pwmp_hd_adjust->arr_current = mode_pwmp_hd_adjust->arr_default; mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 80; pdctrl_out(0); @@ -876,22 +951,17 @@ static void pwmp_adjust_hd_bleeding(uint8_t *state) else { valve_position_change_e s = pwmp_adjust_hd_valve_position_change(state, mode_pwmp_hd_adjust->adjust_state, DIFF_ADC_MAX); - current_adc = mode_pwmp_hd_adjust->psb_adc; + mode_pwmp_hd_adjust->psb_adc = mode_pwmp_hd_adjust->psb_adc; switch (s) { case POSITION_NO_CHANGE_FOREVER: - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 30; // 排气状态结束后在跳转后的状态中等待3s + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 50; // 排气状态结束后在跳转后的状态中等待5s mode_pwmp_hd_adjust->arr_current = 0; - if (current_adc != mode_pwmp_hd_adjust->adc_record_1) - { - mode_pwmp_hd_adjust->adc_record_1 = current_adc; - mode_pwmp_hd->pwmp_save->storage.trip_0 = current_adc; - } - if (mode_pwmp_hd_adjust->all_close_time_flag == TRUE) - { - mode_pwmp_hd_adjust->all_close_time = mode_pwmp_hd_adjust->tmp_time - mode_pwmp_hd_adjust->all_close_time; - mode_pwmp_hd_adjust->all_close_time_flag = FALSE; - } + // if (mode_pwmp_hd_adjust->psb_adc != mode_pwmp_hd_adjust->adc_record_1) + // { + // mode_pwmp_hd_adjust->adc_record_1 = mode_pwmp_hd_adjust->psb_adc; + // mode_pwmp_hd->pwmp_save->storage.trip_0 = mode_pwmp_hd_adjust->psb_adc; + // } break; case POSITION_CHANGE: if (mode_pwmp_hd_adjust->adc_record_0 == 0) @@ -905,18 +975,6 @@ static void pwmp_adjust_hd_bleeding(uint8_t *state) mode_pwmp_hd_adjust->tmp_time = 0; break; case POSITION_NO_CHANGE: - if (mode_pwmp_hd_adjust->all_close_time_flag == TRUE) - { - if (mode_pwmp_hd_adjust->tmp_time == 0) - { - mode_pwmp_hd_adjust->tmp_time = sys_millis(); - } - - if (ABS(current_adc - mode_pwmp_hd_adjust->adc_record_0) > 50) - { - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 80; - } - } break; default: *state = PWMP_HD_ADJUST_STOP; @@ -967,8 +1025,9 @@ static void pwmp_adjust_hd_PID_tuning(uint8_t *state, mode_pwmp_hd_adjust_state_ /*整定方法选择*/ pid_autotune_way_set(PID_AUTOTUNE_WAY_ZN); /*阶跃信号设置*/ - set_step_signal(FULL_TRIP_SIGNAL); - mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 40; // 等待八秒 + pid_autotune_hd->data.step_signal = mode_pwmp_hd_adjust->arr_record_2; + pdctrl_out(pid_autotune_hd->data.step_signal); + mode_pwmp_hd_adjust->wait_count = mode_pwmp_hd->wait_count_max * 40; // 等待四秒 FSM_WAIT(*state); // 设置等待状态 } else @@ -987,8 +1046,6 @@ static void pwmp_adjust_hd_PID_tuning(uint8_t *state, mode_pwmp_hd_adjust_state_ { pid_autotune_hd->data.slope = pid_autotune_hd->data.actual_error / TIME_CYCLE; } - /*K的计算*/ - pid_autotune_hd->k_hd = 1; /*记录下变化率最大点值及行程坐标、时间*/ if (pid_autotune_hd->data.slope > pid_autotune_hd->data.slope_Max) { @@ -1014,6 +1071,9 @@ static void pwmp_adjust_hd_PID_tuning(uint8_t *state, mode_pwmp_hd_adjust_state_ pid_autotune_hd->l_hd = get_time_tangent(0); /*求得时间系数T*/ pid_autotune_hd->t_hd = get_time_tangent(pid_autotune_hd->data.actual_stable) - pid_autotune_hd->l_hd; + /*K的计算*/ + pid_autotune_hd->k_hd = ((pid_autotune_hd->data.actual_stable) / (mode_pwmp_hd_adjust->adc_record_2 - mode_pwmp_hd_adjust->adc_record_0)) / ((pid_autotune_hd->data.step_signal) / (mode_pwmp_hd_adjust->arr_record_2 - mode_pwmp_hd_adjust->arr_record_0)); + *state = next_state; break; case POSITION_CHANGE: @@ -1062,9 +1122,9 @@ static void pwmp_adjust_hd_pid_calculate(uint8_t *state, mode_pwmp_hd_adjust_sta default: break; } - mode_pwmp_hd->pwmp_save->storage.kp = pid_autotune_hd->p_auto_hd; - mode_pwmp_hd->pwmp_save->storage.ki = pid_autotune_hd->i_auto_hd; - mode_pwmp_hd->pwmp_save->storage.kd = pid_autotune_hd->d_auto_hd; + mode_pwmp_hd->pwmp_save->storage.kp = fabs(pid_autotune_hd->p_auto_hd); + mode_pwmp_hd->pwmp_save->storage.ki = fabs(pid_autotune_hd->i_auto_hd); + mode_pwmp_hd->pwmp_save->storage.kd = fabs(pid_autotune_hd->d_auto_hd); *state = next_state; // 将状态切换 } @@ -1103,16 +1163,22 @@ void pwmp_adjust(uint8_t *state) pwmp_adjust_hd_rough_position0(state, PWMP_HD_ADJUST_BLEEDING_POSITION0); break; case PWMP_HD_ADJUST_BLEEDING_POSITION0: - pwmp_adjust_hd_bleeding_position0(state, PWMP_HD_ADJUST_ACCURATE_POSITION0); - break; - case PWMP_HD_ADJUST_ACCURATE_POSITION0: - pwmp_adjust_hd_accurate_position0(state, PWMP_HD_ADJUST_ROUGH_POSITION100); + pwmp_adjust_hd_bleeding_position0(state, PWMP_HD_ADJUST_ROUGH_POSITION100); break; + // case PWMP_HD_ADJUST_ACCURATE_POSITION0: + // pwmp_adjust_hd_accurate_position0(state, PWMP_HD_ADJUST_ROUGH_POSITION100); + // break; case PWMP_HD_ADJUST_ROUGH_POSITION100: pwmp_adjust_hd_rough_position100(state, PWMP_HD_ADJUST_ACCURATE_POSITION100); break; case PWMP_HD_ADJUST_ACCURATE_POSITION100: - pwmp_adjust_hd_accurate_position100(state, PWMP_HD_ADJUST_CALCULATE); + pwmp_adjust_hd_accurate_position100(state, PWMP_HD_ADJUST_ALL_CLOSE_TIME); + break; + case PWMP_HD_ADJUST_ALL_CLOSE_TIME: + pwmp_adjust_hd_all_close_time(state, PWMP_HD_ADJUST_ALL_OPEN_TIME); + break; + case PWMP_HD_ADJUST_ALL_OPEN_TIME: + pwmp_adjust_hd_all_open_time(state, PWMP_HD_ADJUST_CALCULATE); break; case PWMP_HD_ADJUST_CALCULATE: pwmp_adjust_hd_calculate(state, PWMP_HD_ADJUST_PID_TUNING); @@ -1130,7 +1196,7 @@ void pwmp_adjust(uint8_t *state) pwmp_adjust_hd_bleeding(state); break; case PWMP_HD_ADJUST_IDEL: - pwmp_adjust_hd_idle(state, PWMP_HD_ADJUST_PID_TUNING); + pwmp_adjust_hd_idle(state, PWMP_HD_ADJUST_ROUGH_POSITION0); break; case PWMP_HD_ADJUST_STOP: pwmp_adjust_hd_stop(state); @@ -1203,7 +1269,7 @@ void mode_pwmp_hd_process(void) } else { - sprintf(ble_data, "%f\r\n", mode_pwmp_hd->control.ctrl_feedback); + sprintf(ble_data, "%f,%f,%f\r\n", mode_pwmp_hd->control.ctrl_feedback, mode_pwmp_hd->control.ctrl_target, mode_pwmp_hd->control.real_error); } ble_len = osel_mstrlen((unsigned char *)ble_data); if (ble_len != 0) @@ -1289,25 +1355,34 @@ void mode_pwmp_hd_init(uint16_t positioner_model, mode_pwmp_hd_params_u *params, mode_pwmp_hd->pwmp_save = params; mode_pwmp_hd->params_save_cb = params_save_cb; /*设定PWMP方式的工作模式*/ - pwmp_hd_process_state_set(PWMP_HD_PROCESS_TEST); + pwmp_hd_process_state_set(PWMP_HD_PROCESS_CONTROL); /*PID初始化*/ execute_pid_init(EXECUTE_PLAN); /*计数最大值*/ - mode_pwmp_hd->wait_count_max = 100 / ((MODE_DEFAULT_AUTOLOAD + 1) * 0.1); // (=10,每减一消耗10ms) + mode_pwmp_hd->wait_count_max = 100 / ((MODE_DEFAULT_AUTOLOAD + 1) * 0.1); // (=10,每减一消耗10ms,总消耗时间100ms) +#if 0 // 手动控制接口 /*临时参数设置(后续整定)*/ - mode_pwmp_hd->pwmp_save->storage.trip_0 = 2583; - mode_pwmp_hd->pwmp_save->storage.trip_100 = 1722; + mode_pwmp_hd->pwmp_save->storage.trip_0 = 2579; + mode_pwmp_hd->pwmp_save->storage.trip_100 = 1727; #if VIP_H_EN_HD == 1 - mode_pwmp_hd->pwmp_save->storage.pwmp_min = 500; - mode_pwmp_hd->pwmp_save->storage.pwmp_max = 925; + // /*大电流输出模式控制范围(fisher)*/ + // mode_pwmp_hd->pwmp_save->storage.pwmp_min = 500; + // mode_pwmp_hd->pwmp_save->storage.pwmp_max = 925; + /*大电流输出模式控制范围(自制)*/ + mode_pwmp_hd->pwmp_save->storage.pwmp_min = 518; + mode_pwmp_hd->pwmp_save->storage.pwmp_max = 716; #else + /*小电流输出模式控制范围*/ mode_pwmp_hd->pwmp_save->storage.pwmp_min = 1025; mode_pwmp_hd->pwmp_save->storage.pwmp_max = 2050; #endif mode_pwmp_hd->pwmp_save->storage.valve_type = ATO; // 气开阀 #if INTEGRAL_SEPARATION == 1 #if 1 - mode_pwmp_hd->pwmp_save->storage.kp = 5; + // mode_pwmp_hd->pwmp_save->storage.kp = 5; + // mode_pwmp_hd->pwmp_save->storage.ki = 0.02; + // mode_pwmp_hd->pwmp_save->storage.kd = 0.005; + mode_pwmp_hd->pwmp_save->storage.kp = 0.9; mode_pwmp_hd->pwmp_save->storage.ki = 0.02; mode_pwmp_hd->pwmp_save->storage.kd = 0.005; #else @@ -1320,8 +1395,9 @@ void mode_pwmp_hd_init(uint16_t positioner_model, mode_pwmp_hd_params_u *params, mode_pwmp_hd->pwmp_save->storage.ki = 0.5619; mode_pwmp_hd->pwmp_save->storage.kd = 0.5504; #endif - /*阀门参数校准*/ - // calib_parapos_perent(); + +#endif + /*保存参数*/ mode_pwmp_hd->params_save_cb(); /*更新公共参数*/ diff --git a/User/lib/control/custom/pid_hd.c b/User/lib/control/custom/pid_hd.c index 2b30066..8fe4aa5 100644 --- a/User/lib/control/custom/pid_hd.c +++ b/User/lib/control/custom/pid_hd.c @@ -3,6 +3,8 @@ float32 out_pos; // 位置式pid输出 float32 Kp_watch; // 观测Kp的大小 +float32 Ki_watch; // 观测Kp的大小 +float32 Kd_watch; // 观测Kp的大小 /// /// 杭电:设置增量式PID参数 @@ -16,6 +18,11 @@ static void _set_ctrl_prm_position(struct PID_HD *self, float32 kp, float32 ki, pid_hd_position_t *pri = &self->pri_u.position; osel_memset((uint8_t *)pri, 0, sizeof(pid_hd_position_t)); + /*观测传进来的Kp、Ki、Kd*/ + Kp_watch = kp; + Ki_watch = ki; + Kd_watch = kd; + pri->kp = kp; pri->ki = ki; pri->kd = kd;