Files
QD4C-firmware/app/jj_motion.c
井明江 c825014599 pref:弯道速度按曲率分段控制
增加斑马线积分按键更改距离
优化按键调参加减方向
2024-08-14 14:30:32 +08:00

347 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "jj_motion.h"
#include <math.h>
#include "zf_common_headfile.h"
#include "pid.h"
#include "jj_voltage.h"
#include "jj_blueteeth.h"
#include "by_fan_control.h"
#include "by_imu.h"
#include "by_frame.h"
PID_TypeDef far_angle_pid;
PID_TypeDef pos_pid;
PID_TypeDef far_gyro_pid;
PID_TypeDef speed_pid;
PID_TypeDef cir_pos_pid;
///////////////////////////////////////////
// 直道后面风扇角度环
float an_Kp1 = 46.0f;
float an_Ki1 = 0.0f;
float an_Kd1 = 0.0f;
// 直道角速度环
float gy_Kp1 = 1.530f;
float gy_Ki1 = 0.0f;
float gy_Kd1 = 0.0f;
// 直道侧面风扇角度环
float po_Kp1 = 2.10f;
float po_Ki1 = 0.0f;
float po_Kd1 = 0.0f;
////////////////////////////////////
// 弯道后面风扇角度环
float an_Kp0 = 53.0f;
float an_Ki0 = 0.0f;
float an_Kd0 = 0.0f;
// 弯道角速度环
float gy_Kp0 = 2.2180f;
float gy_Ki0 = 0.0f;
float gy_Kd0 = 0.0f;
// 弯道侧面风扇角度环
float cn_Kp1 = 7.0f;
float cn_Ki1 = 0.f;
float cn_Kd1 = 0.0f;
////////////////////////////////////////
// 避障后面角度环
float za_Kp = 55.f;
float za_Ki = 0;
float za_Kd = 0;
float zg_Kp = 2.f;
float zg_Ki = 0;
float zg_Kd = 0;
float zp_Kp = 6.f;
float zp_Ki = 0;
float zp_Kd = 0;
///////////////////////////////////////
// 圆环后面风扇角度环
float yu_Kp0 = 58.0f;
float yu_Ki0 = 0.0f;
float yu_Kd0 = 0.0f;
// 圆环角速度环
float ygy_Kp0 = 2.20f;
float ygy_Ki0 = 0.0f;
float ygy_Kd0 = 0.0f;
// 圆环侧面角度环
float yuc_Kp = 4.4f;
// 速度环
float sp_Kp = 3.40f;
float sp_Ki = 3.6f;
float sp_Kd = 0.0f;
////////////////////////////////////////////////////
// 当前和输入量
float in_gyro;
float out_gyro;
// 期望和当前量
float in_angle;
float set_angle = 0.0f;
float out_angle;
float in_pos;
float out_pos;
float set_pos = 0.0f;
// float set_gyro = 0.0f;
float rate_K = 0;
float in_speed;
float out_speed;
float last_angle;
float set_speed;
float set_speed0 = 657.0f;
float set_speed1 = 1111.0f;
float set_speed2 = 815.f;
float set_speed3 = 666.f;
float set_speed4 = 720.f;
int cnt1 = 0;
int cnt2 = 0;
int cnt3 = 0;
int cnt4 = 0; //
int cnt5 = 0;
int cnt6 = 0; //
int cnt7 = 0;
int cnt8 = 0;
int cnt9 = 0; //
int cnt10 = 0; //
int if_start = 0;
uint8_t in_state = 0;
uint8_t in_stop = 0;
uint8_t last_state = 0;
uint8_t stop_flag = 0;
int32_t pwm_duty_ls;
int32_t pwm_duty_rs;
int32_t pwm_duty_lb;
int32_t pwm_duty_rb;
int32_t stop_cnt = 0;
int32_t last_lb = 0;
int32_t last_rb = 0;
float start_dis = 0;
float set_dis=1.f;
uint8_t go_cnt = 0; // 0 停车 1 测试侧向风扇 2 启动 3成功运行
float bug_sw = 0;
float out_sw = 0;
float sho_sw = 0;
/*
0:无状态
1:弯道
2:直道
3:入环
4:环内
5:障碍
*/
static float myclip_f(float x, float low, float up)
{
return (x > up ? up : x < low ? low
: x);
}
float sport_get_speed(void)
{
#define ALPHA (0.97f)
static float speed_now = 0;
static float speed_last = 0;
speed_now = ALPHA * (float)encoder_get_count(TIM3_ENCOEDER) + (1.0f - ALPHA) * speed_last;
speed_last = speed_now;
encoder_clear_count(TIM3_ENCOEDER);
return speed_now;
#undef ALPHA
}
void sport_motion()
{
imu660ra_get_gyro();
imu660ra_get_acc();
get_vol();
in_gyro = imu660ra_gyro_z;
////////////////////////////////////////停车任务///////////////////////////////////////////////
// 抖动停车计次50
if (imu660ra_acc_z <= 800) {
cnt7++;
} else {
cnt7 = 0;
}
if (cnt7 >= 50 && (uint8_t)sho_sw == 1) {
bt_fly_flag = bt_run_flag = 0;
bt_printf("up");
go_cnt = 0;
}
// 異常值停车
if (fabs(in_angle - last_angle) > 45.f && (uint8_t)bug_sw == 1) {
bt_fly_flag = bt_run_flag = 0;
bt_printf("bug");
go_cnt = 0;
}
// 斑马线停车,摄像头识别,屏蔽发车前的十秒钟
if (1 == in_stop && if_start == 1) {
stop_flag = 1;
}
if (stop_flag == 1) {
bt_printf("finish");
bt_fly_flag = bt_run_flag = 0;
go_cnt = 0;
}
// 出界停车,已经积分路过斑马线,保证斑马线不会触发
if (2 == in_stop && (start_dis >= set_dis|| bt_run_flag == 0) && (uint8_t)out_sw == 1) {
bt_printf("out");
go_cnt = 0;
bt_fly_flag = bt_run_flag = 0;
}
//////////////////////////////////////////////// 动力风扇设置 */////////////////////////////////////////////////////////
if (1 == bt_run_flag) {
cnt1++;
cnt2++;
cnt5++;
// 斑马线积分,系数随便给的
start_dis += in_speed * 0.0000018f;
if (if_start == 0) {
cnt8++;
if (cnt8 >= 5000) {
if_start = 1;
}
}
// pid参数切换
if ((last_state != in_state) && (in_state == 2)) { // 直道
bt_printf("to 直道");
set_speed = set_speed1;
PID_SetTunings(&far_angle_pid, an_Kp1, an_Ki1, an_Kd1);
PID_SetTunings(&far_gyro_pid, gy_Kp1, gy_Ki1, gy_Kd1);
PID_SetTunings(&pos_pid, po_Kp1, po_Ki1, po_Kd1);
} else if ((last_state != in_state) && in_state == 1) { // 弯道
bt_printf("to 入弯");
set_speed = set_speed0 - fabs(rate_K * myclip_f(in_pos, -50.f, 50.f));
PID_SetTunings(&far_angle_pid, an_Kp0, an_Ki0, an_Kd0);
PID_SetTunings(&far_gyro_pid, gy_Kp0, gy_Ki0, gy_Kd0);
PID_SetTunings(&pos_pid, cn_Kp1, cn_Ki1, cn_Kd1);
} else if ((last_state != in_state) && (in_state == 3 || in_state == 4)) { // 圆环
bt_printf("to 圆环");
if (in_state == 3)
set_speed = set_speed2;
else
set_speed = set_speed3;
PID_SetTunings(&far_angle_pid, yu_Kp0, yu_Ki0, yu_Kd0);
PID_SetTunings(&far_gyro_pid, ygy_Kp0, ygy_Ki0, ygy_Kd0);
PID_SetTunings(&pos_pid, yuc_Kp, cn_Ki1, cn_Kd1);
} else if ((last_state != in_state) && in_state == 5) { //
bt_printf("to 障碍");
set_speed = set_speed4;
PID_SetTunings(&far_angle_pid, za_Kp, za_Ki, za_Kd);
PID_SetTunings(&far_gyro_pid, zg_Kp, zg_Ki, zg_Kd);
PID_SetTunings(&pos_pid, zp_Kp, zp_Ki, zp_Kd);
}
if (in_state == 1) {
if (fabs(in_pos) <= 12.0f) {
set_speed = set_speed0 - fabs(rate_K / 3 * myclip_f(in_pos, -50.f, 50.f));
} else {
set_speed = set_speed0 - fabs(rate_K * myclip_f(in_pos, -50.f, 50.f));
}
}
// 记录上一次状态
last_state = in_state;
// pid计算
if (cnt1 >= 2) {
PID_Compute(&far_gyro_pid);
cnt1 = 0;
}
if (cnt2 >= 10) {
in_speed = sport_get_speed();
cnt2 = 0;
PID_Compute(&far_angle_pid);
}
if (cnt5 >= 20) {
PID_Compute(&pos_pid);
PID_Compute(&speed_pid);
cnt5 = 0;
}
// 并级pid限幅
pwm_duty_ls = (int32_t)myclip_f(240 - out_pos, 100.0f, 500.f);
pwm_duty_rs = (int32_t)myclip_f(240 + out_pos, 100.0f, 500.f);
// 并级pid的缺点补偿
if (out_speed >= 1000) {
pwm_duty_lb = (int32_t)myclip_f(out_speed + out_gyro, 1000.0f, 3000.f);
pwm_duty_rb = (int32_t)myclip_f(out_speed - out_gyro, 1000.0f, 3000.f);
} else {
pwm_duty_lb = (int32_t)myclip_f(out_speed + 4 * out_gyro, 1000.0f, 3000.f);
pwm_duty_rb = (int32_t)myclip_f(out_speed - 4 * out_gyro, 1000.0f, 3000.f);
}
if (pwm_duty_lb - last_lb > 1000) {
pwm_duty_lb = (pwm_duty_lb + last_lb) / 2;
}
if (pwm_duty_rb - last_rb > 1000) {
pwm_duty_rb = (pwm_duty_rb + last_rb) / 2;
}
last_rb = pwm_duty_rb;
last_lb = pwm_duty_lb;
by_pwm_power_duty(500 + pwm_duty_ls, 500 + pwm_duty_rs, 3000 + pwm_duty_lb, 3000 + pwm_duty_rb);
} else {
by_pwm_power_duty(0, 0, 0, 0);
}
///////////////////////////////////////////////////* 升力风扇设置 */ /////////////////////////////////////////////////////////////////////////////////////////////////
if (bt_fly_flag == 1) {
by_pwm_update_duty(bt_fly + 500, bt_fly + 500);
if (bt_run_flag == 0) {
// 测试状态
if (1 == go_cnt) {
by_pwm_power_duty(600, 600, 3000, 3000);
} else if (2 == go_cnt) {
cnt3++;
if (cnt3 < 2000) {
by_pwm_power_duty(600, 600, 3000, 3000);
} else if (cnt3 >= 2000 && cnt3 < 3000) {
by_pwm_power_duty(600, 600, 4000, 4000);
} else if (cnt3 >= 3000) {
bt_run_flag = 1;
go_cnt = 3;
cnt3 = 0;
}
}
}
} else {
by_pwm_update_duty(500, 500);
}
}
/**
* @brief 结构体初始化
*
*/
void sport_pid_init()
{
/* 角度控制 */
PID(&far_angle_pid, &in_angle, &out_angle, &set_angle, an_Kp1, an_Ki1, an_Kd1, _PID_P_ON_E, _PID_CD_REVERSE);
PID_SetMode(&far_angle_pid, _PID_MODE_AUTOMATIC);
PID_SetSampleTime(&far_angle_pid, 10);
PID_SetOutputLimits(&far_angle_pid, -6000.0f, 6000.0f);
// 侧面位置环
PID(&pos_pid, &in_angle, &out_pos, &set_pos, po_Kp1, po_Ki1, po_Kd1, _PID_P_ON_E, _PID_CD_REVERSE);
PID_SetMode(&pos_pid, _PID_MODE_AUTOMATIC);
PID_SetSampleTime(&pos_pid, 20);
PID_SetOutputLimits(&pos_pid, -260.0f, 260.0f);
/* 角速度控制 */
PID(&far_gyro_pid, &in_gyro, &out_gyro, &out_angle, gy_Kp1, gy_Ki1, gy_Kd1, _PID_P_ON_E, _PID_CD_REVERSE); // m是增量
PID_SetMode(&far_gyro_pid, _PID_MODE_AUTOMATIC);
PID_SetSampleTime(&far_gyro_pid, 20);
PID_SetOutputLimits(&far_gyro_pid, -2100.0f, 2100.0f);
/* 速度控制 */
PID(&speed_pid, &in_speed, &out_speed, &set_speed, sp_Kp, sp_Ki, sp_Kd, _PID_P_ON_M, _PID_CD_DIRECT);
PID_SetMode(&speed_pid, _PID_MODE_AUTOMATIC);
PID_SetSampleTime(&speed_pid, 20);
PID_SetOutputLimits(&speed_pid, -0.0f, 2500.0f);
}