Compare commits

..

1 Commits

Author SHA1 Message Date
f9e93b88c1 优化上层 2025-06-27 21:43:58 +08:00
14 changed files with 276 additions and 446 deletions

View File

@ -479,9 +479,3 @@
[info] Log at : 2025/6/27|16:40:58|GMT+0800 [info] Log at : 2025/6/27|16:40:58|GMT+0800
[info] Log at : 2025/6/28|01:22:24|GMT+0800
[info] Log at : 2025/6/30|18:03:06|GMT+0800
[info] Log at : 2025/7/1|14:01:22|GMT+0800

View File

@ -97,7 +97,6 @@
"gimbal_task.h": "c", "gimbal_task.h": "c",
"gimgal.h": "c", "gimgal.h": "c",
"navi.h": "c", "navi.h": "c",
"up.h": "c", "up.h": "c"
"bsp_usart.h": "c"
} }
} }

View File

@ -158,47 +158,47 @@
<Ww> <Ww>
<count>0</count> <count>0</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>tar_angle</ItemText> <ItemText>NUC_send,0x0A</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>1</count> <count>1</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>huart-&gt;ErrorCode</ItemText> <ItemText>SendBuffer,0x10</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>2</count> <count>2</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>error_code</ItemText> <ItemText>chassis,0x0A</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>3</count> <count>3</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>UP,0x0A</ItemText> <ItemText>cmd_fromnuc,0x0A</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>4</count> <count>4</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>chassis,0x0A</ItemText> <ItemText>nucbuf,0x10</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>5</count> <count>5</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>\\R2\../User/task/chassis_task.c\chassis.sick_cali.sickparam</ItemText> <ItemText>UP,0x0A</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>6</count> <count>6</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>cmd,0x0A</ItemText> <ItemText>tar_angle</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>7</count> <count>7</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>nucbuf,0x0A</ItemText> <ItemText>up_cmd</ItemText>
</Ww> </Ww>
<Ww> <Ww>
<count>8</count> <count>8</count>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>cmd_fromnuc</ItemText> <ItemText>a,0x0A</ItemText>
</Ww> </Ww>
</WatchWindow1> </WatchWindow1>
<Tracepoint> <Tracepoint>

Binary file not shown.

View File

@ -3,6 +3,7 @@
#include "user_math.h" #include "user_math.h"
#include "bsp_buzzer.h" #include "bsp_buzzer.h"
#include "bsp_delay.h" #include "bsp_delay.h"
/* /*
xyyaw xyyaw
nuc (xyyaw) nuc (xyyaw)
@ -31,14 +32,9 @@ int8_t Chassis_UpdateFeedback(Chassis_t *c, const CAN_t *can) {
// //
// c->sick_cali.sick_dis[i]=can->sickfed.raw_dis[i] / 10; //没使用原值 // c->sick_cali.sick_dis[i]=can->sickfed.raw_dis[i] / 10; //没使用原值
// } // }
c->sick_cali.sick_dis[0]=(fp32)(can->sickfed.raw_dis[0]) ; c->sick_cali.sick_dis[0]=can->sickfed.raw_dis[0] ;
c->sick_cali.sick_dis[1]=(fp32)(can->sickfed.raw_dis[1]+30) ; //有点误差,手动补偿 c->sick_cali.sick_dis[1]=can->sickfed.raw_dis[1]+50 ; //有点误差,手动补偿
c->sick_cali.sick_dis[2]=(fp32)(can->sickfed.raw_dis[2] ); c->sick_cali.sick_dis[2]=can->sickfed.raw_dis[2] ;
c->vofa_send[7] =c->sick_cali.sick_dis[1]-c->sick_cali.sick_dis[2];
c->vofa_send[6] = c->sick_cali.sick_dis[0];
c->vofa_send[5] =c->sick_cali.sick_dis[1];
c->vofa_send[4] =c->sick_cali.sick_dis[2];
return CHASSIS_OK; return CHASSIS_OK;
} }
@ -62,14 +58,9 @@ int8_t Chassis_init(Chassis_t *c, const Chassis_Param_t *param, float target_fre
PID_init(&(c->pid.Chassis_AngleAdjust), PID_POSITION, &(c->param->Chassis_AngleAdjust_param)); PID_init(&(c->pid.Chassis_AngleAdjust), PID_POSITION, &(c->param->Chassis_AngleAdjust_param));
LowPassFilter2p_Init(&(c->filled[0]), target_freq, 80.0f); // 角加速度滤波 LowPassFilter2p_Init(&(c->filled[0]), target_freq, 80.0f); // 角加速度滤波
LowPassFilter2p_Init(&(c->filled[1]), target_freq, 50.0f); LowPassFilter2p_Init(&(c->filled[1]), target_freq, 80.0f); // w滤波
LowPassFilter2p_Init(&(c->filled[2]), target_freq, 80.0f); LowPassFilter2p_Init(&(c->filled[2]), target_freq, 80.0f); // y滤波
LowPassFilter2p_Init(&(c->filled[3]), target_freq, 80.0f); LowPassFilter2p_Init(&(c->filled[3]), target_freq, 80.0f); // x滤波
KalmanCreate(&c->extKalman[0],10,1);
KalmanCreate(&c->extKalman[1],10,1);
KalmanCreate(&c->extKalman[2],10,1);
c->sick_cali .sickparam=c->param ->sickparam ; c->sick_cali .sickparam=c->param ->sickparam ;
@ -80,7 +71,7 @@ fp32 pian_yaw;
void Chassis_speed_calculate(Chassis_t *c, fp32 Vx, fp32 Vy, fp32 Vw) { void Chassis_speed_calculate(Chassis_t *c, fp32 Vx, fp32 Vy, fp32 Vw) {
fp64 Nor_Vx, Nor_Vy; fp64 Nor_Vx, Nor_Vy;
normalize_vector(Vx, Vy, &Nor_Vx, &Nor_Vy); normalize_vector(Vx, Vy, &Nor_Vx, &Nor_Vy);
c->hopemotorout.OmniSpeedOut[0] = -Nor_Vx + Nor_Vy + Vw+pian_yaw; // 右前 c->hopemotorout.OmniSpeedOut[0] = -Nor_Vx + Nor_Vy + Vw+pian_yaw; // 右前
c->hopemotorout.OmniSpeedOut[1] = -Nor_Vx - Nor_Vy + Vw+pian_yaw; // 右后 c->hopemotorout.OmniSpeedOut[1] = -Nor_Vx - Nor_Vy + Vw+pian_yaw; // 右后
c->hopemotorout.OmniSpeedOut[2] = Nor_Vx - Nor_Vy + Vw +pian_yaw; // 左后 c->hopemotorout.OmniSpeedOut[2] = Nor_Vx - Nor_Vy + Vw +pian_yaw; // 左后
@ -98,17 +89,12 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
c->pos088.bmi088.filtered_gyro.z = LowPassFilter2p_Apply(&(c->filled[0]), c->pos088.bmi088.gyro.z); c->pos088.bmi088.filtered_gyro.z = LowPassFilter2p_Apply(&(c->filled[0]), c->pos088.bmi088.gyro.z);
/*初始数据*/ /*初始数据*/
c->move_vec.Vw = 0;
c->move_vec.Vx = 0;
c->move_vec.Vy = 0;
c->NUC_send.send[0] = 0; c->NUC_send.send[0] = 0;
c->sick_cali.is_reach = 0; c->sick_cali.is_reach = 0;
c->vofa_send[0]= KalmanFilter(&c->extKalman[0] , c->sick_cali.sick_dis[0]);
c->vofa_send[1]= KalmanFilter(&c->extKalman[1] , c->sick_cali.sick_dis[1]);
c->vofa_send[2]= KalmanFilter(&c->extKalman[2] , c->sick_cali.sick_dis[2]);
switch (c->chassis_ctrl.ctrl) { switch (c->chassis_ctrl.ctrl) {
case RCcontrol: case RCcontrol:
switch (c->chassis_ctrl.mode) { switch (c->chassis_ctrl.mode) {
@ -131,7 +117,9 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
sick_calibration(c, ctrl, out); sick_calibration(c, ctrl, out);
c->NUC_send.send[0] = (c->sick_cali.is_reach == 1) ? 1 : 0; c->NUC_send.send[0] = (c->sick_cali.is_reach == 1) ? 1 : 0;
break; break;
default:
break;
} }
break; break;
@ -147,12 +135,7 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
// c->NUC_send.send[0] = 1; // c->NUC_send.send[0] = 1;
break; break;
case AUTO_MID360_Pitch: case AUTO_MID360_Pitch:
c->move_vec.Vw = ctrl->cmd_MID360.posw * 1000;
c->move_vec.Vy = -ctrl->cmd_MID360.posy * 1000;
c->move_vec.Vx = -ctrl->cmd_MID360.posx * 1000;
abs_limit_fp(&c->move_vec.Vx, 5000.0f);
abs_limit_fp(&c->move_vec.Vy, 5000.0f);
abs_limit_fp(&c->move_vec.Vw, 5000.0f);
break; break;
case AUTO_MID360_Adjust: case AUTO_MID360_Adjust:
c->move_vec.Vw = ctrl->Vw * 6000; c->move_vec.Vw = ctrl->Vw * 6000;
@ -169,13 +152,9 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
switch (c->chassis_ctrl.mode) switch (c->chassis_ctrl.mode)
{ {
case PB_UP: case PB_UP:
c->move_vec.Vw = ctrl->Vw * 6000;
c->move_vec.Vx = ctrl->Vy * 6000;
c->move_vec.Vy = ctrl->Vx * 6000;
break ;
case PB_MID: case PB_MID:
case PB_DOWN: case PB_DOWN:
c->move_vec.Vw = ctrl->cmd_MID360.posw * 1000; c->move_vec.Vw = ctrl->cmd_MID360.posw * 1000;
c->move_vec.Vy = -ctrl->cmd_MID360.posy * 1000; c->move_vec.Vy = -ctrl->cmd_MID360.posy * 1000;
c->move_vec.Vx = -ctrl->cmd_MID360.posx * 1000; c->move_vec.Vx = -ctrl->cmd_MID360.posx * 1000;
abs_limit_fp(&c->move_vec.Vx, 5000.0f); abs_limit_fp(&c->move_vec.Vx, 5000.0f);
@ -183,13 +162,7 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
abs_limit_fp(&c->move_vec.Vw, 5000.0f); abs_limit_fp(&c->move_vec.Vw, 5000.0f);
break ; break ;
} }
break;
case RELAXED:
c->move_vec.Vw = 0;
c->move_vec.Vx = 0;
c->move_vec.Vy = 0;
break ;
@ -198,10 +171,9 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
break; break;
default: default:
break; break;
} }
// 电机速度限幅 // 电机速度限幅
abs_limit_fp(&c->move_vec.Vx, 6000.0f); abs_limit_fp(&c->move_vec.Vx, 6000.0f);
@ -217,7 +189,7 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
out->motor_CHASSIS3508.as_array[i] = c->final_out.final_3508out[i]; out->motor_CHASSIS3508.as_array[i] = c->final_out.final_3508out[i];
} }
// c->vofa_send[0] = (fp32)c->sick_cali.sick_dis[1] - c->sick_cali.sick_dis[2];
return CHASSIS_OK; return CHASSIS_OK;
@ -234,50 +206,32 @@ sick2,左1
*/ */
fp32 diff_yaw,diff_y,diff_x;
int8_t sick_calibration(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) int8_t sick_calibration(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out)
{ {
if (c == NULL) return CHASSIS_ERR_NULL; if (c == NULL) return CHASSIS_ERR_NULL;
if (ctrl == NULL) return CHASSIS_ERR_NULL; if (ctrl == NULL) return CHASSIS_ERR_NULL;
fp32 delta_w,delta_x,delta_y; fp32 delta_w,delta_x,delta_y;
fp32 sick0 = c->sick_cali.sick_dis[0]; fp32 sick0 = c->sick_cali.sick_dis[0] ;
fp32 sick1 = c->sick_cali.sick_dis[1]; fp32 sick1 = c->sick_cali.sick_dis[1];
fp32 sick2 = c->sick_cali.sick_dis[2]; fp32 sick2 = c->sick_cali.sick_dis[2];
const sickparam_t *param = &c->sick_cali.sickparam; const sickparam_t *param = &c->sick_cali.sickparam;
diff_yaw =LowPassFilter2p_Apply(&(c->filled[1]), -(fp32)(sick1 +10 - sick2));
diff_y = LowPassFilter2p_Apply(&(c->filled[2]),-(fp32)(sick1 - c->sick_cali.sickparam.y_set));
diff_x = LowPassFilter2p_Apply(&(c->filled[3]),(fp32)(sick0 - c->sick_cali.sickparam.x_set));
delta_w=PID_calc(&c->pid.SickCaliWzOutPID, diff_yaw, 0); fp32 diff_yaw = -(fp32)(sick1 - sick2);
delta_x=PID_calc(&c->pid.SickCaliVxOutPID, diff_x, 0); fp32 diff_y = -(fp32)(sick1 - c->sick_cali.sickparam.y_set);
delta_y=PID_calc(&c->pid.SickCaliVyOutPID, diff_y,0); fp32 diff_x = (fp32)(sick0 - c->sick_cali.sickparam.x_set);
if(fabs(diff_yaw)>param->w_error){ delta_w=(&c->pid.SickCaliWzInPID, diff_yaw, 0);
delta_x=(&c->pid.SickCaliVxInPID, diff_x, 0);
c->move_vec.Vw=PID_calc(&c->pid.SickCaliWzInPID,-delta_w,0); delta_y=(&c->pid.SickCaliVyInPID, diff_y,0);
}
// if(fabs(diff_y)>param->xy_error){
//
// c->move_vec.Vy=PID_calc(&c->pid.SickCaliVyInPID,delta_y,0);
// }
// if(fabs(diff_x)>param->xy_error){
//
// c->move_vec.Vx=PID_calc(&c->pid.SickCaliVxInPID,-delta_x,0);
// }
static uint16_t reach_cnt = 0; static uint16_t reach_cnt = 0;
if (fabsf(diff_yaw) <= param->w_error && if (fabsf(diff_yaw) <= param->w_error &&
fabsf(diff_x) <= param->xy_error && fabsf(diff_x) <= param->xy_error &&
fabsf(diff_y) <= param->xy_error) { fabsf(diff_y) <= param->xy_error) {
reach_cnt++; reach_cnt++;
if (reach_cnt >= 20) { if (reach_cnt >= 50) {
c->sick_cali.is_reach = 1; c->sick_cali.is_reach = 1;
@ -298,7 +252,7 @@ int8_t Chassis_AngleCompensate(Chassis_t *c)
{ {
pian_angel=cur_angle-AngleChange(DEGREE,c->pos088.imu_eulr.yaw); pian_angel=cur_angle-AngleChange(DEGREE,c->pos088.imu_eulr.yaw);
} }
else { else {
cur_angle=AngleChange(DEGREE,c->pos088.imu_eulr.yaw); cur_angle=AngleChange(DEGREE,c->pos088.imu_eulr.yaw);
pian_angel=0; pian_angel=0;

View File

@ -31,7 +31,6 @@
#include "can_use.h" #include "can_use.h"
#include "cmd.h" #include "cmd.h"
#include "filter.h" #include "filter.h"
#include "kalman.h"
#define CHASSIS_OK (0) #define CHASSIS_OK (0)
#define CHASSIS_ERR (-1) #define CHASSIS_ERR (-1)
@ -173,13 +172,11 @@ typedef struct{
}pid; }pid;
fp32 vofa_send[8]; fp32 vofa_send[8];
/*卡尔曼滤波*/
extKalman_t extKalman[3];
LowPassFilter2p_t filled[8]; /* 输出滤波器滤波器数组 */
LowPassFilter2p_t filled[6]; /* 输出滤波器滤波器数组 */
struct { struct {
fp32 sick_dis[4]; //获取到的sick激光值 int32_t sick_dis[4]; //获取到的sick激光值
sickparam_t sickparam; sickparam_t sickparam;
int is_reach; int is_reach;
}sick_cali; }sick_cali;

View File

@ -96,14 +96,6 @@ static const ConfigParam_t param ={
.Pitch_angle=66, .Pitch_angle=66,
.go_up_speed =12, .go_up_speed =12,
.go_down_speed =5, .go_down_speed =5,
},
.MID360Cfg={
.go_release_pos=-200, // GO电机发射位置
.go_up_speed=20, // GO电机上升速度
.go_down_speed=10, // GO电机下降速度
}, },
}, },
.chassis = {/**/ .chassis = {/**/
@ -131,102 +123,28 @@ static const ConfigParam_t param ={
.i_limit = 50.0f, .i_limit = 50.0f,
.out_limit =1000.0f, .out_limit =1000.0f,
}, },
.Sick_CaliWparam ={
.p = 4.5f,
// .SickCali_WInparam = { .i = 0.005f,
// .p = 3.0f, .d = 0.0f,
// .i = 0.000f, .i_limit = 500.0f,
// .d = 0.0f, .out_limit =1000.0f,
// .i_limit = 500.0f, },
// .out_limit = 2000.0f, .Sick_CaliYparam ={
// }, .p = 2.9f,
// .SickCali_WOutparam = { .i = 0.0051f,
// .p = 2.6f, .d = 0.0f,
// .i = 0.0f, .i_limit = 500.0f,
// .d = 0.0f, .out_limit =3000.0f,
// .i_limit = 0.0f, },
// .out_limit = 1000.0f, .Sick_CaliXparam ={
// }, .p = 2.9f,
// .SickCali_YInparam = { .i = 0.0065f,
// .p = 1.0f, .d = 0.0f,
// .i = 0.0f, .i_limit = 500.0f,
// .d = 0.0f, .out_limit =3000.0f,
// .i_limit = 0.0f, },
// .out_limit = 5000.0f, .Chassis_AngleAdjust_param={
// },
// .SickCali_YOutparam = {
// .p = 4.5f,
// .i = 0.0f,
// .d = 0.0f,
// .i_limit = 00.0f,
// .out_limit = 1000.0f,
// },
// .SickCali_XInparam = {
// .p = 1.0f,
// .i = 0.0f,
// .d = 0.0f,
// .i_limit = 0.0f,
// .out_limit = 5000.0f,
// },
// .SickCali_XOutparam = {
// .p = 4.5f,
// .i = 0.00f,
// .d = 0.0f,
// .i_limit = 500.0f,
// .out_limit = 2000.0f,
// },
.SickCali_WInparam = {
.p = 3.0f,
.i = 0.000f,
.d = 0.0f,
.i_limit = 500.0f,
.out_limit = 2000.0f,
},
.SickCali_WOutparam = {
.p = 2.6f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 0.0f,
.out_limit = 1000.0f,
},
.SickCali_YInparam = {
.p = 1.0f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 0.0f,
.out_limit = 5000.0f,
},
.SickCali_YOutparam = {
.p = 4.5f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 00.0f,
.out_limit = 1000.0f,
},
.SickCali_XInparam = {
.p = 1.0f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 0.0f,
.out_limit = 5000.0f,
},
.SickCali_XOutparam = {
.p = 4.5f,
.i = 0.00f,
.d = 0.0f,
.i_limit = 500.0f,
.out_limit = 2000.0f,
},
.Chassis_AngleAdjust_param={
.p = 10.0f, .p = 10.0f,
.i = 0.0f, .i = 0.0f,
.d = 0.0f, .d = 0.0f,
@ -235,10 +153,10 @@ static const ConfigParam_t param ={
}, },
.sickparam={ .sickparam={
.w_error=2, .w_error=5,
.xy_error=3, .xy_error=5,
.x_set=10000, .x_set=600,
.y_set=2000, .y_set=100,
}, },

View File

@ -54,7 +54,7 @@ int8_t up_init(UP_t *u,const UP_Param_t *param,float target_freq)
u->PassContext .is_init = 1; u->PassContext .is_init = 1;
} }
u->LaunchContext.LaunchCfg = u->param->LaunchCfg; u->LaunchContext.LaunchCfg = u->param->LaunchCfg;
u->MID360Context.MID360Cfg = u->param->MID360Cfg;
BSP_UART_RegisterCallback(BSP_UART_RS485, BSP_UART_RX_CPLT_CB, USART6_RxCompleteCallback);//注册串口回调函数bsp层 BSP_UART_RegisterCallback(BSP_UART_RS485, BSP_UART_RX_CPLT_CB, USART6_RxCompleteCallback);//注册串口回调函数bsp层
} }
@ -181,16 +181,13 @@ int8_t UP_control(UP_t *u,CAN_Output_t *out,CMD_t *c)
/*部分数据更新*/ /*部分数据更新*/
static int is_pitch=1; static int is_pitch=1;
posss=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->pos),3.4,4.2,&u->MID360Context.Curve); posss=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->pos),3,4,&u->PitchContext.Curve);
// if (u->PitchContext.Curve == CURVE_58) { // if (u->PitchContext.Curve == CURVE_58) {
// target->Pitch_angle = 58; // target->Pitch_angle = 58;
// } else { // } else {
// target->Pitch_angle = 66; // target->Pitch_angle = 66;
// } // }
u->vofa_send [2] = c->pos;
u->vofa_send [3] = LowPassFilter2p_Apply(&u->filled[0],c->pos);
u->vofa_send [4] =1;
switch (c->CMD_CtrlType ) switch (c->CMD_CtrlType )
{ {
case RCcontrol: //在手动模式下 case RCcontrol: //在手动模式下
@ -206,9 +203,10 @@ int8_t UP_control(UP_t *u,CAN_Output_t *out,CMD_t *c)
target->Pitch_angle = LaunchCfg->Pitch_angle; target->Pitch_angle = LaunchCfg->Pitch_angle;
is_pitch=0; is_pitch=0;
} //初始上电 } //初始上电
//LaunchCfg->go_up_speed=15; LaunchCfg->go_up_speed=15;
target->Pitch_angle =LaunchCfg->Pitch_angle; target->Pitch_angle =LaunchCfg->Pitch_angle;
target->go_pull_speed=LaunchCfg->go_up_speed;
target->Shoot_M2006_angle=LaunchCfg->m2006_init; target->Shoot_M2006_angle=LaunchCfg->m2006_init;
u->PitchContext .PitchState = PITCH_PREPARE; //状态更新 u->PitchContext .PitchState = PITCH_PREPARE; //状态更新
u->LaunchContext.LaunchState = Launch_Stop; u->LaunchContext.LaunchState = Launch_Stop;
@ -237,17 +235,54 @@ int8_t UP_control(UP_t *u,CAN_Output_t *out,CMD_t *c)
} }
break; break;
case AUTO: case AUTO:
UP_AUTO_Control(u,out,c); /*自动下数据更新,根据距离切换俯仰角,如需自动调整,放在*/
// if (u->PitchContext.Curve == CURVE_58) {
// target->Pitch_angle = 58;
// } else {
// target->Pitch_angle = 66;
// }
switch(c-> CMD_mode)
{
case AUTO_MID360_Pitch:
if (u->PitchContext .PitchState ==PITCH_PREPARE || u->PitchContext .PitchState ==PITCH_COMPLETE)
{
u->PitchContext .PitchState=PITCH_START;//置标志位用于启动投篮
}
/*根据距离实时计算所需pos*/
if(c->pos){
pitch_cfg ->go_release_pos=
CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->pos),3,4,&u->PitchContext.Curve);
}
else pitch_cfg ->go_release_pos=0 ;
Pitch_Process(u,out,c);
break ;
case AUTO_MID360:
target->Shoot_M2006_angle =LaunchCfg ->m2006_init ;
break ;
default:
break;
}
break ; break ;
case PASS_BALL: case PASS_BALL:
// if (u->PitchContext.Curve == CURVE_58) {
// target->Pitch_angle = 58;
// } else {
// target->Pitch_angle = 66;
// }
Pass_Process(u,out,c); Pass_Process(u,out,c);
break; break;
case RELAXED: case RELAXED:
// target->go_shoot= pitch_cfg . // target->go_shoot= pitch_cfg .
target->Pitch_angle = 58; target->Pitch_angle = 58;
target->go_shoot = -190.0f; target->go_shoot = -210.0f;
//失控下最好切手动手动用pitch
pitch_cfg ->go_release_pos=-190;
// target->Pitch_angle = 58; // target->Pitch_angle = 58;
@ -289,8 +324,8 @@ int8_t Pitch_Launch_Sequence(UP_t *u, LaunchContext_t *LaunchContext,fp32 StartP
if( u->motorfeedback .DJmotor_feedback [4].total_angle>-1){ //当2006的总角度小于1可以认为已经勾上,误差为1 if( u->motorfeedback .DJmotor_feedback [4].total_angle>-1){ //当2006的总角度小于1可以认为已经勾上,误差为1
u->motor_target.go_pull_speed=LaunchContext->LaunchCfg.go_down_speed; u->motor_target.go_pull_speed=LaunchContext->LaunchCfg.go_down_speed;
u->motor_target.go_shoot = EndPos ; u->motor_target.go_shoot = EndPos ;
// if(is_reached(u->motorfeedback.go_data.Pos,EndPos,1.0f)) if(is_reached(u->motorfeedback.go_data.Pos,EndPos,1.0f))
// LaunchContext->LaunchState = Launch_SHOOT_WAIT; LaunchContext->LaunchState = Launch_SHOOT_WAIT;
} break; } break;
case Launch_SHOOT_WAIT: case Launch_SHOOT_WAIT:
@ -350,14 +385,16 @@ int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c)
PassCfg_t *PassCfg = &u->PassContext.PassCfg; PassCfg_t *PassCfg = &u->PassContext.PassCfg;
PassState_t *state = &u->PassContext.PassState; PassState_t *state = &u->PassContext.PassState;
up_motor_target_t *target=&u->motor_target ; up_motor_target_t *target=&u->motor_target ;
LaunchContext_t *LaunchContext = &u->LaunchContext; LaunchContext_t *LaunchContext = &u->LaunchContext;
Pass_Sequence_Check(u,c); Pass_Sequence_Check(u,c);
if(c->pos) //
{
PassCfg ->go_release_pos = PassCfg ->go_release_pos =
CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->pos)+0.15,3,4,&u->PassContext.Curve); CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->pos),3,4,&u->PitchContext.Curve);
}
switch (*state) { //遥控器按键进行状态切换 switch (*state) { //遥控器按键进行状态切换
case PASS_STOP: case PASS_STOP:
@ -367,13 +404,13 @@ int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c)
break; break;
case PASS_PREPARE: case PASS_PREPARE:
target->go_pull_speed=PassCfg->go_up_speed; target->go_pull_speed=PassCfg->go_up_speed;
Pitch_Launch_Sequence(u,LaunchContext,u->motorfeedback.go_data.Pos,PassCfg->go_wait,out); Pitch_Launch_Sequence(u,LaunchContext,u->motorfeedback.go_data.Pos,PassCfg->go_wait,out);
break; break;
case PASS_START: case PASS_START:
if(LaunchContext->LaunchState == Launch_TRIGGER){ if(LaunchContext->LaunchState == Launch_SHOOT_WAIT){
target->go_pull_speed=PassCfg->go_down_speed; target->go_pull_speed=PassCfg->go_down_speed;
target->go_shoot = PassCfg->go_release_pos ; target->go_shoot = PassCfg->go_release_pos ;
} }
@ -389,42 +426,3 @@ int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c)
return 0; return 0;
} }
int8_t UP_AUTO_Control(UP_t *u,CAN_Output_t *out,CMD_t *c){
/*自动下数据更新,根据距离切换俯仰角,如需自动调整,放在*/
up_motor_target_t *target=&u->motor_target ;
LaunchContext_t *LaunchContext = &u->LaunchContext;
MID360Context_t *MID360Context=&u->MID360Context;
MID360Cfg_t *MID360Cfg = &u->MID360Context.MID360Cfg;
MID360Cfg->go_release_pos=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->pos)+0.15,3.2,4.3,&u->MID360Context.Curve);
if (u->MID360Context.Curve == CURVE_58) {
target->Pitch_angle = 58;
} else {
target->Pitch_angle = 66;
}
LaunchContext->LaunchCfg.go_up_speed=MID360Cfg->go_up_speed;
LaunchContext->LaunchCfg.go_down_speed=MID360Cfg->go_down_speed;
switch(c-> CMD_mode)
{
case AUTO_MID360_Pitch:
if(MID360Context->IsLaunch==0){
MID360Context->IsLaunch=1;
LaunchContext->LaunchState = Launch_PREPARE;
}
Pitch_Launch_Sequence(u,LaunchContext,u->motorfeedback.go_data.Pos,MID360Cfg->go_release_pos,out);
break ;
case AUTO_MID360:
target->Shoot_M2006_angle= LaunchContext->LaunchCfg.m2006_init;
MID360Context->IsLaunch=0;
break ;
default:
break;
}
}

View File

@ -51,7 +51,6 @@ typedef enum {
}LaunchState_t; }LaunchState_t;
typedef struct { typedef struct {
LaunchCfg_t LaunchCfg; LaunchCfg_t LaunchCfg;
LaunchState_t LaunchState; LaunchState_t LaunchState;
} LaunchContext_t; } LaunchContext_t;
@ -61,7 +60,8 @@ typedef struct {
typedef enum { typedef enum {
PITCH_PREPARE, // 准备阶段 PITCH_PREPARE, // 准备阶段
PITCH_START, //启动,拉扳机 PITCH_START, //启动,拉扳机
PITCH_WAIT, // 发射等待 PITCH_WAIT, // 发射等待
PITCH_COMPLETE // 完成 PITCH_COMPLETE // 完成
@ -79,6 +79,7 @@ typedef struct {
typedef struct { typedef struct {
PitchState_t PitchState; PitchState_t PitchState;
PitchCfg_t PitchConfig; PitchCfg_t PitchConfig;
CurveType Curve; //当前函数,雷达距离->pos
uint8_t is_init ; uint8_t is_init ;
} PitchContext_t; } PitchContext_t;
@ -107,26 +108,6 @@ typedef struct {
uint8_t is_init ; uint8_t is_init ;
} PassContext_t; } PassContext_t;
/*雷达自动*/
typedef struct {
fp32 go_release_pos; // GO电机发射位置
fp32 go_up_speed; // GO电机上升速度
fp32 go_down_speed; // GO电机下降速度
} MID360Cfg_t;
typedef struct {
MID360Cfg_t MID360Cfg;
CurveType Curve; //当前函数,雷达距离->pos
int IsLaunch; //是否在发射过程
} MID360Context_t;
typedef struct { typedef struct {
BMI088_t bmi088; BMI088_t bmi088;
@ -152,7 +133,7 @@ typedef struct
LaunchCfg_t LaunchCfg; LaunchCfg_t LaunchCfg;
PitchCfg_t PitchCfg; PitchCfg_t PitchCfg;
PassCfg_t PassCfg; PassCfg_t PassCfg;
MID360Cfg_t MID360Cfg;
GO_MotorCmd_t go_cmd; GO_MotorCmd_t go_cmd;
}UP_Param_t; }UP_Param_t;
@ -194,9 +175,7 @@ typedef struct{
/*投篮过程*/ /*投篮过程*/
PitchContext_t PitchContext; PitchContext_t PitchContext;
/*传球过程*/ /*传球过程*/
PassContext_t PassContext; PassContext_t PassContext;
/*自动过程*/
MID360Context_t MID360Context;
CMD_t *cmd; CMD_t *cmd;
struct{ struct{
@ -253,7 +232,6 @@ int8_t Pitch_Process(UP_t *u, CAN_Output_t *out,CMD_t *c);
int8_t Pass_Sequence_Check(UP_t *u,CMD_t *c); int8_t Pass_Sequence_Check(UP_t *u,CMD_t *c);
int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c); int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c);
int8_t Pitch_Launch_Sequence(UP_t *u, LaunchContext_t *LaunchContext,fp32 StartPos,fp32 EndPos,CAN_Output_t *out); int8_t Pitch_Launch_Sequence(UP_t *u, LaunchContext_t *LaunchContext,fp32 StartPos,fp32 EndPos,CAN_Output_t *out);
int8_t UP_AUTO_Control(UP_t *u,CAN_Output_t *out,CMD_t *c);
#endif #endif

View File

@ -62,27 +62,25 @@ int8_t GO_SendData( GO_MotorData_t *go_data,GO_MotorCmd_t *go_cmd,float pos, flo
} }
// 计算66度曲线偏上 // 计算58度曲线
// 计算66度曲线偏上 static float curve_58(float d) {
static float curve_66(float d) { return 0.448f * d * d + 24.8604f * d - 177.99552f;
return 4.0310f * d * d + 8.9026f * d -139.5156;
} }
// 计算58度曲线偏下 // 计算66度曲线
// 计算58度曲线偏下 static float curve_66(float d) {
static float curve_58(float d) { return 8.84935f * d * d - 10.5424f * d - 126.791f;
return -1.9776f * d * d + 42.8499f * d - 204.2442f;
} }
/* /*
线,pos拟合 线,pos拟合
x-y x-y
线x重合区 线x重合区
*/ */
int abdddd=0;
float CurveChange(float d, float x, float y, CurveType *cs) float CurveChange(float d, float x, float y, CurveType *cs)
{ {
if (d<3.2) abdddd++;
if (*cs == CURVE_66) { if (*cs == CURVE_66) {
if (d > y) { if (d > y) {
*cs = CURVE_58; *cs = CURVE_58;

View File

@ -2,181 +2,177 @@
#include "crc16.h" #include "crc16.h"
#include <string.h> #include <string.h>
#include "error_detect.h" #include "error_detect.h"
volatile uint32_t drop_message = 0; static volatile uint32_t drop_message = 0;
static osThreadId_t thread_alert; static osThreadId_t thread_alert;
uint8_t nucbuf[25]; uint8_t nucbuf[31];
char SendBuffer[7]; char SendBuffer[7];
static void NUC_CBLTCallback(void)
{ static void NUC_IdleCallback(void) {
osThreadFlagsSet(thread_alert, SIGNAL_NUC_RAW_REDY); osThreadFlagsSet(thread_alert,SIGNAL_NUC_RAW_REDY);
// detect_hook(NUC_TOE); detect_hook(NUC_TOE);
} }
static void NUC_ERRORCALLBACK(void) int8_t NUC_Init(NUC_t *nuc){
{ if(nuc == NULL) return DEVICE_ERR_NULL;
NUC_Restart(); if((thread_alert = osThreadGetId()) == NULL ) return DEVICE_ERR_NULL;
uint32_t error_code = HAL_UART_GetError(BSP_UART_GetHandle(BSP_UART_NUC)); BSP_UART_RegisterCallback(BSP_UART_NUC,BSP_UART_IDLE_LINE_CB,
// osThreadFlagsSet(thread_alert, SIGNAL_NUC_ERROR); NUC_IdleCallback);
return DEVICE_OK;
} }
int8_t NUC_Init(NUC_t *nuc) int8_t NUC_StartReceiving() {
{ if (HAL_UARTEx_ReceiveToIdle_DMA(BSP_UART_GetHandle(BSP_UART_NUC),
if (nuc == NULL)
return DEVICE_ERR_NULL;
if ((thread_alert = osThreadGetId()) == NULL)
return DEVICE_ERR_NULL;
BSP_UART_RegisterCallback(BSP_UART_NUC, BSP_UART_RX_CPLT_CB,
NUC_CBLTCallback);
BSP_UART_RegisterCallback(BSP_UART_NUC, BSP_UART_ERROR_CB,
NUC_ERRORCALLBACK);
return DEVICE_OK;
}
int8_t NUC_StartReceiving()
{
if (HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_NUC),
(uint8_t *)nucbuf, (uint8_t *)nucbuf,
sizeof(nucbuf)) == HAL_OK) sizeof(nucbuf)) == HAL_OK)
return DEVICE_OK; return DEVICE_OK;
return DEVICE_ERR; return DEVICE_ERR;
} }
int8_t NUC_StartSending(fp32 *data) int8_t NUC_StartSending(fp32 *data) {
{
union union
{
float x[1];
char data[4];
}instance;
// for (int i = 0; i < 1; i++) {
instance.x[0] = data[0];
// }
SendBuffer[0] = 0xFC; //帧头
SendBuffer[1] = 0x01; //控制帧
for(int i = 2; i < 6; i++)
{ {
float x[1]; SendBuffer[i] = instance.data[i-2];
char data[4];
} instance;
// for (int i = 0; i < 1; i++) {
instance.x[0] = data[0];
// }
SendBuffer[0] = 0xFC; // 帧头
SendBuffer[1] = 0x01; // 控制帧
for (int i = 2; i < 6; i++)
{
SendBuffer[i] = instance.data[i - 2];
} }
SendBuffer[6] = 0xFD; // 帧尾 SendBuffer[6] = 0xFD; //帧尾
if (HAL_UART_Transmit_DMA(BSP_UART_GetHandle(BSP_UART_NUC), if (HAL_UART_Transmit_DMA(BSP_UART_GetHandle(BSP_UART_NUC),
(uint8_t *)SendBuffer, (uint8_t *)SendBuffer,
sizeof(SendBuffer)) == HAL_OK) sizeof(SendBuffer)) == HAL_OK)
return DEVICE_OK; return DEVICE_OK;
return DEVICE_ERR; return DEVICE_ERR;
} }
int8_t NUC_Restart(void) int8_t NUC_Restart(void) {
{
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_NUC)); __HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_NUC));
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_NUC)); __HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_NUC));
return DEVICE_OK; return DEVICE_OK;
} }
bool_t NUC_WaitDmaCplt(void) bool_t NUC_WaitDmaCplt(void) {
{
return (osThreadFlagsWait(SIGNAL_NUC_RAW_REDY, osFlagsWaitAll, 20) == return (osThreadFlagsWait(SIGNAL_NUC_RAW_REDY, osFlagsWaitAll,50) ==
SIGNAL_NUC_RAW_REDY); SIGNAL_NUC_RAW_REDY);
} }
int8_t NUC_RawParse(CMD_NUC_t *n)
{ int8_t NUC_RawParse(CMD_NUC_t *n){
if (n == NULL) if(n ==NULL) return DEVICE_ERR_NULL;
return DEVICE_ERR_NULL; union
union {
{ float x[5];
float x[5]; char data[20];
char data[20]; }instance;
} instance; if(nucbuf[0]!=HEAD) goto error; //发送ID不是底盘
if (nucbuf[0] != HEAD) else{
goto error; // 发送ID不是底盘 n->status_fromnuc =nucbuf[1];
else n->ctrl_status =nucbuf[2];
{
n->status_fromnuc = nucbuf[1];
n->ctrl_status = nucbuf[2];
switch (n->status_fromnuc) switch (n->status_fromnuc)
{ {
case VISION: // 控制帧0x02 case VISION://控制帧0x02
/* 协议格式 /* 协议格式
0xFF HEAD 0xFF HEAD
0x02 0x02
0x01 0x01
vx fp32 vx fp32
vy fp32 vy fp32
wz fp32 wz fp32
0xFE TAIL 0xFE TAIL
*/ */
instance.data[3] = nucbuf[3];
instance.data[2] = nucbuf[4]; instance.data[3] = nucbuf[3];
instance.data[1] = nucbuf[5]; instance.data[2] = nucbuf[4];
instance.data[0] = nucbuf[6]; instance.data[1] = nucbuf[5];
n->camera.data1 = instance.x[0]; // instance.data[0] = nucbuf[6];
instance.data[7] = nucbuf[7]; n->camera .data1 = instance.x[0]; //
instance.data[6] = nucbuf[8]; instance.data[7] = nucbuf[7];
instance.data[5] = nucbuf[9]; instance.data[6] = nucbuf[8];
instance.data[4] = nucbuf[10]; instance.data[5] = nucbuf[9];
n->camera.data2 = instance.x[1]; // instance.data[4] = nucbuf[10];
instance.data[11] = nucbuf[11]; n->camera .data2 = instance.x[1];//
instance.data[10] = nucbuf[12]; instance.data[11] = nucbuf[11];
instance.data[9] = nucbuf[13]; instance.data[10] = nucbuf[12];
instance.data[8] = nucbuf[14]; instance.data[9] = nucbuf[13];
n->camera.data3 = instance.x[2]; // instance.data[8] = nucbuf[14];
n->camera .data3 = instance.x[2];//
break; break;
case MID: // 控制帧0x08 case MID ://控制帧0x08
/* 协议格式 /* 协议格式
0xFF HEAD 0xFF HEAD
0x09 0x09
0x01 0x01
vx fp32 vx fp32
vy fp32 vy fp32
wz fp32 wz fp32
0xFE TAIL 0xFE TAIL
*/ */
if (nucbuf[24] != TAIL) if(nucbuf[24]!=TAIL)goto error;
goto error; instance.data[3] = nucbuf[6];
instance.data[3] = nucbuf[6]; instance.data[2] = nucbuf[5];
instance.data[2] = nucbuf[5]; instance.data[1] = nucbuf[4];
instance.data[1] = nucbuf[4]; instance.data[0] = nucbuf[3];
instance.data[0] = nucbuf[3];
n->MID360.vx = instance.x[0]; // n->MID360.vx = instance.x[0]; //
instance.data[7] = nucbuf[10]; instance.data[7] = nucbuf[10];
instance.data[6] = nucbuf[9]; instance.data[6] = nucbuf[9];
instance.data[5] = nucbuf[8]; instance.data[5] = nucbuf[8];
instance.data[4] = nucbuf[7]; instance.data[4] = nucbuf[7];
n->MID360.vy = instance.x[1]; // n->MID360.vy = instance.x[1];//
instance.data[11] = nucbuf[14]; instance.data[11] = nucbuf[14];
instance.data[10] = nucbuf[13]; instance.data[10] = nucbuf[13];
instance.data[9] = nucbuf[12]; instance.data[9] = nucbuf[12];
instance.data[8] = nucbuf[11]; instance.data[8] = nucbuf[11];
n->MID360.wz = instance.x[2]; // n->MID360.wz = instance.x[2];//
instance.data[15] = nucbuf[18]; instance.data[15] = nucbuf[18];
instance.data[14] = nucbuf[17]; instance.data[14] = nucbuf[17];
instance.data[13] = nucbuf[16]; instance.data[13] = nucbuf[16];
instance.data[12] = nucbuf[15]; instance.data[12] = nucbuf[15];
n->MID360.pos = instance.x[3]; // n->MID360.pos = instance.x[3];//
instance.data[19] = nucbuf[22]; instance.data[19] = nucbuf[22];
instance.data[18] = nucbuf[21]; instance.data[18] = nucbuf[21];
instance.data[17] = nucbuf[20]; instance.data[17] = nucbuf[20];
instance.data[16] = nucbuf[19]; instance.data[16] = nucbuf[19];
n->MID360.angle = instance.x[4]; // n->MID360.angle = instance.x[4];//
n->MID360.flag = nucbuf[23]; //
n->MID360.flag = nucbuf[23];//
break; break;
} }
return DEVICE_OK; return DEVICE_OK;
} }
error: error:
drop_message++; drop_message++;
NUC_Restart(); return DEVICE_ERR;
return DEVICE_ERR;
} }
int8_t NUC_HandleOffline(CMD_NUC_t *cmd) int8_t NUC_HandleOffline(CMD_NUC_t *cmd)
{ {
if (cmd == NULL) if(cmd == NULL) return DEVICE_ERR_NULL;
return DEVICE_ERR_NULL; // memset(cmd, 0, sizeof(*cmd));
// memset(cmd, 0, sizeof(*cmd)); return 0;
return 0;
} }

View File

@ -33,7 +33,5 @@ int8_t NUC_StartSending(fp32 *data) ;
bool_t NUC_WaitDmaCplt(void); bool_t NUC_WaitDmaCplt(void);
int8_t NUC_RawParse(CMD_NUC_t *n); int8_t NUC_RawParse(CMD_NUC_t *n);
int8_t NUC_HandleOffline(CMD_NUC_t *cmd); int8_t NUC_HandleOffline(CMD_NUC_t *cmd);
int8_t NUC_Restart(void);
#endif #endif

View File

@ -18,7 +18,7 @@ int a=0;
void Task_nuc(void *argument){ void Task_nuc(void *argument){
(void)argument; /**/ (void)argument; /**/
osDelay(TASK_INIT_DELAY_NUC); // osDelay(TASK_INIT_DELAY_NUC);
const uint32_t delay_tick = osKernelGetTickFreq() / TASK_FREQ_NUC; const uint32_t delay_tick = osKernelGetTickFreq() / TASK_FREQ_NUC;
NUC_Init(&nuc_raw); NUC_Init(&nuc_raw);
@ -35,8 +35,8 @@ void Task_nuc(void *argument){
#endif #endif
a++; a++;
NUC_StartReceiving(); NUC_StartReceiving();
// NUC_StartSending(NUC_send.send); NUC_StartSending(NUC_send.send);
// NUC_StartSending (send); NUC_StartSending (send);
if (NUC_WaitDmaCplt()){ if (NUC_WaitDmaCplt()){
NUC_RawParse(&cmd_fromnuc); NUC_RawParse(&cmd_fromnuc);
} }

View File

@ -18,7 +18,7 @@
#define TASK_FREQ_UP (900u) #define TASK_FREQ_UP (900u)
#define TASK_FREQ_CTRL_CMD (500u) #define TASK_FREQ_CTRL_CMD (500u)
#define TASK_FREQ_NUC (500u) #define TASK_FREQ_NUC (200u)
#define TASK_FREQ_CAN (1000u) #define TASK_FREQ_CAN (1000u)
#define TASK_FREQ_RC (1000u) #define TASK_FREQ_RC (1000u)