diff --git a/Core/Src/main.c b/Core/Src/main.c
index 2372718..4290161 100644
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -81,6 +81,7 @@ int main(void)
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+
HAL_Init();
/* USER CODE BEGIN Init */
diff --git a/MDK-ARM/R2.uvoptx b/MDK-ARM/R2.uvoptx
index c08fbe8..0a52c45 100644
--- a/MDK-ARM/R2.uvoptx
+++ b/MDK-ARM/R2.uvoptx
@@ -168,47 +168,37 @@
3
1
- UP,0x0A
+ posss
4
1
- chassis,0x0A
+ UP,0x0A
5
1
- cmd,0x0A
+ chassis,0x0A
6
1
- nucbuf,0x0A
+ nuc_raw
7
1
- cmd_fromnuc
+ cmd_fromnuc,0x0A
8
1
- NUC_send,0x0A
+ drop_message,0x0A
9
1
- \\R2\../User/task/up_task.c\UP.MID360Context.IsLaunch
-
-
- 10
- 1
- ang_58,0x0A
-
-
- 11
- 1
- ang_66,0x0A
+ \\R2\../User/task/chassis_task.c\chassis.param->M3508_param.d
diff --git a/MDK-ARM/R2/R2.axf b/MDK-ARM/R2/R2.axf
index c50144b..f2dc0ab 100644
Binary files a/MDK-ARM/R2/R2.axf and b/MDK-ARM/R2/R2.axf differ
diff --git a/User/Module/Chassis.c b/User/Module/Chassis.c
index b0a0331..c220a4a 100644
--- a/User/Module/Chassis.c
+++ b/User/Module/Chassis.c
@@ -163,10 +163,6 @@ int8_t Chassis_Control(Chassis_t *c, CMD_t *ctrl, CAN_Output_t *out) {
switch (c->chassis_ctrl.mode)
{
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_DOWN:
c->move_vec.Vw = -ctrl->cmd_MID360.angle * 1000;
diff --git a/User/Module/config.c b/User/Module/config.c
index 34b8bbe..b95e58c 100644
--- a/User/Module/config.c
+++ b/User/Module/config.c
@@ -111,11 +111,18 @@ static const ConfigParam_t param ={
.M3508_param = {
- .p = 15.1f,
- .i = 0.02f,
+// .p = 15.1f,
+// .i = 0.02f,
+// .d = 3.2f,
+// .i_limit = 200.0f,
+// .out_limit =6000.0f,
+ .p = 20.5f,
+ .i = 0.00011f,
.d = 3.2f,
.i_limit = 200.0f,
.out_limit =6000.0f,
+
+
},
/*视觉*/
.chassis_PICKWzPID_HIGN_param ={
diff --git a/User/Module/up.c b/User/Module/up.c
index cabda56..a15f93d 100644
--- a/User/Module/up.c
+++ b/User/Module/up.c
@@ -23,6 +23,7 @@
// 定义继电器控制
#define RELAY1_TOGGLE(state) HAL_GPIO_WritePin(GPIOE, RELAY_Pin, (state) ? GPIO_PIN_SET : GPIO_PIN_RESET)
+
int8_t up_init(UP_t *u,const UP_Param_t *param,float target_freq)
{
u->param = param; /*初始化参数 */
@@ -40,6 +41,9 @@ int8_t up_init(UP_t *u,const UP_Param_t *param,float target_freq)
PID_init (&u->pid .Pitch_M2006_speed ,PID_POSITION ,&(u->param->Pitch_M2006_speed_param ));
u->go_cmd =u->param ->go_cmd ;
+
+
+
LowPassFilter2p_Init(&(u->filled[0]),target_freq,100.0f);
@@ -126,6 +130,12 @@ int8_t VESC_M5065_Control(UP_t *u,fp32 speed)
int8_t ALL_Motor_Control(UP_t *u,CAN_Output_t *out)
{
+ /*目标值限位*/
+ abs_limit_min_max_fp(&u->motor_target.go_shoot ,-215.0f,0.0f);
+ abs_limit_min_max_fp(&u->motor_target.Pitch_angle ,48.0f,67.0f);
+
+
+
//电机控制 ,传进can
DJ_Angle_Control(u,0x205,&u->motorfeedback .DJmotor_feedback[4] ,
&u->pid .Shoot_M2006angle ,
@@ -175,13 +185,9 @@ int8_t UP_control(UP_t *u,CAN_Output_t *out,CMD_t *c)
LaunchCfg_t *LaunchCfg =&u->LaunchContext.LaunchCfg;
up_motor_target_t *target=&u->motor_target ;
- /*config值限位*/
- abs_limit_min_max_fp(&u->PitchContext.PitchConfig.go_release_pos ,-215.0f,0.0f);
- abs_limit_min_max_fp(&u->PitchContext.PitchConfig.Pitch_angle ,48.0f,67.0f);
/*部分数据更新*/
static int is_pitch=1;
- posss=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis),3.4,4.2,&u->MID360Context.Curve);
switch (c->CMD_CtrlType )
{
@@ -254,7 +260,7 @@ return 0;
//复用发射,
-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,CMD_t *c, LaunchContext_t *LaunchContext,fp32 StartPos,fp32 EndPos,CAN_Output_t *out){
/*电机位置到达判断*/
bool is_GoStartReach=is_reached(u->motorfeedback.go_data.Pos,StartPos,1.0f); //go开始位置
@@ -291,8 +297,6 @@ int8_t Pitch_Launch_Sequence(UP_t *u, LaunchContext_t *LaunchContext,fp32 StartP
if( is_HookDone ){ //当2006的总角度小于1,可以认为已经勾上,误差为1
u->motor_target.go_pull_speed=LaunchContext->LaunchCfg.go_down_speed;
u->motor_target.go_shoot = EndPos ;
-// if(is_reached(u->motorfeedback.go_data.Pos,EndPos,1.0f))
-// LaunchContext->LaunchState = Launch_SHOOT_WAIT;
} break;
case Launch_SHOOT_WAIT:
@@ -315,10 +319,12 @@ int8_t Pitch_Process(UP_t *u, CAN_Output_t *out,CMD_t *c)
LaunchContext_t *LaunchContext = &u->LaunchContext;
// 可根据实际需要传入不同的起始和末位置,起始:当前位置
LaunchContext->LaunchCfg.go_up_speed= cfg->go_up_speed;
- LaunchContext->LaunchCfg.go_down_speed= cfg->go_down_speed
- ;
+ LaunchContext->LaunchCfg.go_down_speed= cfg->go_down_speed;
+ abs_limit_min_max_fp(&cfg->go_release_pos ,-215.0f,0.0f);
+ abs_limit_min_max_fp(&cfg->Pitch_angle,48.0f,67.0f);
- Pitch_Launch_Sequence(u, LaunchContext, u->motorfeedback.go_data.Pos, cfg->go_release_pos, out);
+
+ Pitch_Launch_Sequence(u, c,LaunchContext, u->motorfeedback.go_data.Pos, cfg->go_release_pos, out);
switch(*state){
@@ -354,15 +360,27 @@ int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c)
PassCfg_t *PassCfg = &u->PassContext.PassCfg;
PassState_t *state = &u->PassContext.PassState;
- up_motor_target_t *target=&u->motor_target ;
+ PassContext_t *PassContext = &u->PassContext;
+ up_motor_target_t *target=&u->motor_target ;
LaunchContext_t *LaunchContext = &u->LaunchContext;
Pass_Sequence_Check(u,c);
-
+ /*俯仰角度,力度转换*/
+ PassCfg->go_release_pos=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis),3.3,4.3,&u->PassContext.Curve);
+
+
+ if (u->PassContext.Curve == CURVE_58) {
+
+ target->Pitch_angle = 58;
+ PassCfg->Pitch_angle=58;
+ }
+ else {
+ target->Pitch_angle = 66;
+ PassCfg->Pitch_angle=66;
+
+ }
+ abs_limit_min_max_fp(&PassCfg->go_release_pos ,-215.0f,0.0f);
- PassCfg ->go_release_pos =
- CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis),3,4,&u->PassContext.Curve);
-
switch (*state) { //遥控器按键进行状态切换
case PASS_STOP:
@@ -373,7 +391,7 @@ int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c)
case PASS_PREPARE:
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,c,LaunchContext,u->motorfeedback.go_data.Pos,PassCfg->go_wait,out);
break;
@@ -384,7 +402,8 @@ int8_t Pass_Process(UP_t *u,CAN_Output_t *out,CMD_t *c)
}
break ;
case PASS_POS_PREPARE:
- target->Shoot_M2006_angle=LaunchContext->LaunchCfg.m2006_init;//发射
+ target->Shoot_M2006_angle=LaunchContext->LaunchCfg.m2006_init;//发射
+
break;
case PASS_COMPLETE:
break;
@@ -400,13 +419,14 @@ int8_t UP_AUTO_Control(UP_t *u,CAN_Output_t *out,CMD_t *c){
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->cmd_MID360.dis),3.2,4.3,&u->MID360Context.Curve);
+
+ /*俯仰角度,力度转换,加数值限位*/
if(u->MID360Context.Curve==CURVE_58){
- MID360Cfg->go_release_pos=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis),3.3,4.3,&u->MID360Context.Curve);
+ MID360Cfg->go_release_pos=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis)+0.1f,3.3,4.3,&u->MID360Context.Curve);
}
else {
- MID360Cfg->go_release_pos=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis)-0.05f,3.3,4.3,&u->MID360Context.Curve);
+ MID360Cfg->go_release_pos=CurveChange(LowPassFilter2p_Apply(&u->filled[0],c->cmd_MID360.dis),3.3,4.3,&u->MID360Context.Curve);
}
if (u->MID360Context.Curve == CURVE_58) {
@@ -414,6 +434,9 @@ int8_t UP_AUTO_Control(UP_t *u,CAN_Output_t *out,CMD_t *c){
} else {
target->Pitch_angle = 66;
}
+ abs_limit_min_max_fp(&MID360Cfg->go_release_pos ,-215.0f,0.0f);
+
+
LaunchContext->LaunchCfg.go_up_speed=MID360Cfg->go_up_speed;
LaunchContext->LaunchCfg.go_down_speed=MID360Cfg->go_down_speed;
@@ -426,13 +449,14 @@ int8_t UP_AUTO_Control(UP_t *u,CAN_Output_t *out,CMD_t *c){
MID360Context->IsLaunch=1;
LaunchContext->LaunchState = Launch_PREPARE;
}
- Pitch_Launch_Sequence(u,LaunchContext,u->motorfeedback.go_data.Pos,MID360Cfg->go_release_pos,out);
+ Pitch_Launch_Sequence(u,c,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;
+// u->cmd_from_nuc.lock=0;
break ;
default:
break;
diff --git a/User/Module/up.h b/User/Module/up.h
index 898692c..47f795b 100644
--- a/User/Module/up.h
+++ b/User/Module/up.h
@@ -190,8 +190,8 @@ typedef struct{
typedef struct{
- uint8_t up_task_run;
- const UP_Param_t *param;
+ uint8_t up_task_run;
+ const UP_Param_t *param;
LaunchContext_t LaunchContext;
/*投篮过程*/
PitchContext_t PitchContext;
@@ -215,6 +215,7 @@ typedef struct{
uint32_t ecd;
float angle;
}Encoder;
+
}motorfeedback;
@@ -234,7 +235,11 @@ typedef struct{
}final_out;
-
+// struct {
+// float angle;
+// float dis;
+// uint8_t lock;
+// }cmd_from_nuc;
LowPassFilter2p_t filled[6]; /* 输出滤波器滤波器数组 */
fp32 vofa_send[8];
@@ -254,7 +259,7 @@ int8_t DJ_Speed_Control(UP_t *u,int id,DJmotor_feedback_t *f,pid_type_def *Speed
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_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,CMD_t *c, 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);
diff --git a/User/Module/up_utils.c b/User/Module/up_utils.c
index e579749..25a6db4 100644
--- a/User/Module/up_utils.c
+++ b/User/Module/up_utils.c
@@ -68,12 +68,14 @@ int8_t GO_SendData( GO_MotorData_t *go_data,GO_MotorCmd_t *go_cmd,float pos, flo
// 计算66度曲线(偏上)
static float curve_66(float d) {
- return 2.9851104*pow(d,4) -36.164382*pow(d,3) + 159.54844*pow(d,2) -273.62856*d + 43.092452; }
-// 计算58度曲线(偏下)
+ return 2.9851104*pow(d,4) -36.164382*pow(d,3) + 159.54844*pow(d,2) -273.62856*d + 43.092452;
+ }
// 计算58度曲线(偏下)
static float curve_58(float d) {
// return 0.9242f * d * d + 19.4246f * d - 154.9055f;
- return 2.638517*pow(d,4) -47.996138*pow(d,3) + 325.38515*pow(d,2) -950.18155*d + 919.86543;
+// return 2.638517*pow(d,4) -47.996138*pow(d,3) + 325.38515*pow(d,2) -950.18155*d + 919.86543;
+ return 2.7775f * d * d - 0.5798f * d - 113.1488;
+
}
/*
@@ -84,8 +86,10 @@ static float curve_58(float d) {
fp32 ang_58;
fp32 ang_66;
+
float CurveChange(float d, float x, float y, CurveType *cs)
{
+
if (*cs == CURVE_66) {
if (d > y) {
@@ -166,3 +170,63 @@ int8_t Pass_Sequence_Check(UP_t *u, CMD_t *c) //按键顺序检测,传球,
}
+
+#define BIN_SCALE 1000 // 精度:0.001米
+#define BIN_OFFSET 3000 // 最小支持3.000米 → bin 3000
+#define BIN_COUNT 5001 // 支持3.000 ~ 8.000米,(8000-3000+1)
+#define WINDOW_SIZE 50
+
+static float window[WINDOW_SIZE] = {0};
+static int index = 0;
+static int filled = 0;
+static uint16_t freq_map[BIN_COUNT] = {0}; // 用16位计数防止溢出
+
+static float last_output = 0.0f;
+static uint8_t first_run = 1;
+
+// 四舍五入保留3位小数
+static inline float round3f(float x) {
+ return (int)(x * BIN_SCALE + 0.5f) / (float)BIN_SCALE;
+}
+
+float stable_distance_filter(float new_value) {
+ // 1. 四舍五入到0.001
+ float rounded = round3f(new_value);
+ int new_bin = (int)(rounded * BIN_SCALE + 0.5f);
+
+ // 2. 移除旧值计数
+ int old_bin = (int)(round3f(window[index]) * BIN_SCALE + 0.5f);
+ if (filled && old_bin >= BIN_OFFSET && old_bin < BIN_OFFSET + BIN_COUNT) {
+ freq_map[old_bin - BIN_OFFSET]--;
+ }
+
+ // 3. 加入新值到窗口和计数
+ window[index++] = new_value;
+ if (index >= WINDOW_SIZE) {
+ index = 0;
+ filled = 1;
+ }
+ if (new_bin >= BIN_OFFSET && new_bin < BIN_OFFSET + BIN_COUNT) {
+ freq_map[new_bin - BIN_OFFSET]++;
+ }
+
+ // 4. 找出现频率最高的桶
+ int max_bin = -1;
+ uint16_t max_freq = 0;
+ for (int i = 0; i < BIN_COUNT; ++i) {
+ if (freq_map[i] > max_freq) {
+ max_freq = freq_map[i];
+ max_bin = i + BIN_OFFSET;
+ }
+ }
+
+ float current_fixed = max_bin >= 0 ? max_bin / (float)BIN_SCALE : rounded;
+
+ // 5. 判断是否更新输出,差值超过0.1才更新
+ if (first_run || fabsf(current_fixed - last_output) > 0.1f) {
+ last_output = current_fixed;
+ first_run = 0;
+ }
+
+ return last_output;
+}
diff --git a/User/Module/up_utils.h b/User/Module/up_utils.h
index 436e403..76e73f2 100644
--- a/User/Module/up_utils.h
+++ b/User/Module/up_utils.h
@@ -53,6 +53,9 @@ int8_t GO_SendData( GO_MotorData_t *go_data,GO_MotorCmd_t *go_cmd,float pos, flo
int8_t DJ_processdata(DJmotor_feedback_t *f,fp32 ecd_to_angle);
+static inline float round3f(float x) ;
+
+float stable_distance_filter(float new_value) ;
#endif
diff --git a/User/task/chassis_task.c b/User/task/chassis_task.c
index 8997ce1..1fe1803 100644
--- a/User/task/chassis_task.c
+++ b/User/task/chassis_task.c
@@ -34,7 +34,7 @@ static Chassis_Ctrl_t ctrl;
#endif
-
+fp32 freq;
/**
* \brief 底盘任务
@@ -50,7 +50,8 @@ void Task_Chassis(void *argument)
Chassis_init(&chassis,&(task_runtime.config.config->chassis),TASK_FREQ_CHASSIS);
uint32_t tick = osKernelGetTickCount();
-
+ uint32_t last_tick=tick;
+
while(1)
{
@@ -59,6 +60,8 @@ void Task_Chassis(void *argument)
task_runtime.freq.chassis=TASK_FREQ_CHASSIS;
task_runtime.last_up_time.chassis=tick;
#endif
+ freq=(tick-last_tick)/1000.0f;
+ last_tick =tick;
/*imu数据获取*/
osMessageQueueGet(task_runtime.msgq.imu.eulr, &chassis.pos088.imu_eulr, NULL, 0);
diff --git a/User/task/nuc_task.c b/User/task/nuc_task.c
index 5be2f44..29d2c01 100644
--- a/User/task/nuc_task.c
+++ b/User/task/nuc_task.c
@@ -24,7 +24,6 @@ int a=0;
-
void Task_nuc(void *argument){
(void)argument; /**/
diff --git a/User/task/user_task.h b/User/task/user_task.h
index 52e20d5..f0a5a57 100644
--- a/User/task/user_task.h
+++ b/User/task/user_task.h
@@ -13,7 +13,7 @@
/* 所有任务都要定义自己的任务运行频率 */
-// 分配的频率该如何给定?
+
#define TASK_FREQ_CHASSIS (900u)
#define TASK_FREQ_UP (900u)