Files
QD4C-firmware/app/jj_motion.c
2024-07-09 19:32:36 +08:00

306 lines
8.5 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 = 50.0f;
float an_Ki1 = 0.0f;
float an_Kd1 = 0.0f;
// 直道角速度环
float gy_Kp1 = 6.0f;
float gy_Ki1 = 0.0f;
float gy_Kd1 = 0.0f;
// 直道侧面风扇角度环
float po_Kp1 = 13.0f;
float po_Ki1 = 0.0f;
float po_Kd1 = 0.0f;
////////////////////////////////////
// 避障后面角度环
float za_Kp = 50.f;
float za_Ki = 0;
float za_Kd = 0;
float zg_Kp = 3.f;
float zg_Ki = 0;
float zg_Kd = 0;
float zp_Kp = 30.f;
float zp_Ki = 0;
float zp_Kd = 0;
///////////////////////////////////////
// 弯道后面风扇角度环
float an_Kp0 = 60.0f;
float an_Ki0 = 0.0f;
float an_Kd0 = 0.0f;
// 弯道角速度环
float gy_Kp0 = 10.80f;
float gy_Ki0 = 0.0f;
float gy_Kd0 = 0.0f;
// 弯道侧面风扇角度环
float cn_Kp1 = 25.0f;
float cn_Ki1 = 0.f;
float cn_Kd1 = 0.0f;
////////////////////////////////////////
// 圆环后面风扇角度环
float yu_Kp0 = 60.0f;
float yu_Ki0 = 0.0f;
float yu_Kd0 = 0.0f;
// 圆环角速度环
float ygy_Kp0 = 8.40f;
float ygy_Ki0 = 0.0f;
float ygy_Kd0 = 0.0f;
// 速度环
float sp_Kp = 2.0f;
float sp_Ki = 4.f;
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 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 if_start = 0;
float shock_stop = 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;
float qd_down = 0.0f;
float last_gy = 0.0f;
/*
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;
if (fabs(out_gyro) < 900) {
PID_SetOutputLimits(&speed_pid, -0.0f, 3000.0f);
} else {
PID_SetOutputLimits(&speed_pid, -0.0f, 2100.0f);
}
////////////////////////////////////////停车任务///////////////////////////////////////////////
// 抖动停车
if (imu660ra_acc_z <= 800) {
cnt7++;
} else {
cnt7 = 0;
}
if (cnt7 >= 50 && shock_stop == 1) {
bt_fly_flag = bt_run_flag = 0;
bt_printf("up");
}
// 異常值停车
if (fabs(in_angle - last_angle) > 45.f) {
bt_fly_flag = bt_run_flag = 0;
bt_printf("bug");
}
// 斑马线停车,摄像头识别
if (1 == in_stop && if_start == 1) {
stop_flag = 1;
}
if (stop_flag == 1) {
bt_printf("finish");
bt_fly_flag = bt_run_flag = 0;
}
// 出界停车
if (2 == in_stop) {
bt_printf("over");
bt_fly_flag = bt_run_flag = 0;
}
///////////////////////////////////////////////////////////////////////////////////////
/* 动力风扇设置 */
if (1 == bt_run_flag) {
cnt1++;
cnt2++;
cnt5++;
if (if_start == 0) {
cnt8++;
if (cnt8 >= 10000) {
if_start = 1;
}
}
// pid参数切换
if ((last_state != in_state) && (in_state == 0 || 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);
}
if ((last_state != in_state) && in_state == 1) { // 弯道
bt_printf("to 入弯");
set_speed = set_speed0;
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);
}
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, cn_Kp1, cn_Ki1, cn_Kd1);
}
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);
}
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;
}
if (cnt5 >= 20) {
PID_Compute(&far_angle_pid);
PID_Compute(&pos_pid);
PID_Compute(&speed_pid);
cnt5 = 0;
}
// 并级pid限幅
pwm_duty_ls = (int32_t)myclip_f(320 - out_pos, 140.0f, 500.f);
pwm_duty_rs = (int32_t)myclip_f(320 + out_pos, 140.0f, 500.f);
pwm_duty_lb = (int32_t)myclip_f(out_speed + out_gyro, 300.0f, 3000.f);
pwm_duty_rb = (int32_t)myclip_f(out_speed - out_gyro, 300.0f, 3000.f);
by_pwm_power_duty(500 + pwm_duty_ls, 500 + pwm_duty_rs, 3600 + pwm_duty_lb, 3600 + pwm_duty_rb);
} else {
by_pwm_power_duty(0, 0, 0, 0);
}
/* 升力风扇设置 */
if (bt_fly_flag == 0) {
by_pwm_update_duty(500, 500);
} else {
if (in_state == 1) {
qd_down = 20;
} else if (in_state == 4) {
qd_down = 20;
}
by_pwm_update_duty(bt_fly + 500 - qd_down, bt_fly + 500 - qd_down);
}
}
/**
* @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, 20);
PID_SetOutputLimits(&far_angle_pid, -3000.0f, 3000.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, -180.0f, 180.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, -1500.0f, 1500.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, 2100.0f);
}