第一次调试

This commit is contained in:
zyx 2024-12-27 15:11:13 +08:00
parent 7f3510c085
commit bb37061e2e
14 changed files with 9567 additions and 9526 deletions

914
Src/tim.c

File diff suppressed because it is too large Load Diff

View File

@ -183,16 +183,13 @@ static void auto_aim_mode() {
*/
static void RemoteControlSet() {
// 控制底盘和云台运行模式,云台待添加,云台是否始终使用IMU数据?
if (switch_is_down(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[下],小陀螺
if (switch_is_down(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[下],
{
chassis_cmd_send.chassis_mode = CHASSIS_ROTATE;
gimbal_cmd_send.gimbal_mode = GIMBAL_GYRO_MODE;
} else if (switch_is_mid(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[中],,底盘跟随云台
} else if (switch_is_mid(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[中],
{
chassis_cmd_send.chassis_mode = CHASSIS_FOLLOW_GIMBAL_YAW;
gimbal_cmd_send.gimbal_mode = GIMBAL_GYRO_MODE;
shoot_cmd_send.lid_mode = LID_CLOSE;
} else if (switch_is_up(rc_data[TEMP].rc.switch_right))// 右侧开关状态[上]
{
shoot_cmd_send.lid_mode = LID_OPEN;
@ -224,21 +221,18 @@ static void RemoteControlSet() {
}
// 云台软件限位
// 底盘参数,目前没有加入小陀螺(调试似乎暂时没有必要),系数需要调整,遥控器输入灵敏度
chassis_cmd_send.vx = 0.001f * (float) rc_data[TEMP].rc.rocker_r_; // _水平方向
chassis_cmd_send.vy = 0.001f * (float) rc_data[TEMP].rc.rocker_r1; // 1数值方向
// 发射参数
if (switch_is_up(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[上],弹舱打开
; // 弹舱舵机控制,待添加servo_motor模块,开启
else; // 弹舱舵机控制,待添加servo_motor模块,关闭
// 摩擦轮控制,拨轮向上打为负,向下为正
if (rc_data[TEMP].rc.dial < -100) // 向上超过100,打开摩擦轮
{
shoot_cmd_send.shoot_mode = SHOOT_ON;
shoot_cmd_send.friction_mode = FRICTION_ON;
else
}
else{
shoot_cmd_send.shoot_mode = SHOOT_OFF;
shoot_cmd_send.friction_mode = FRICTION_OFF;
}
// 拨弹控制,遥控器固定为一种拨弹模式,可自行选择
if (rc_data[TEMP].rc.dial < -500)//
@ -493,8 +487,8 @@ static void EmergencyHandler() {
robot_state = ROBOT_READY;
gimbal_cmd_send.gimbal_mode = GIMBAL_ZERO_FORCE;
chassis_cmd_send.chassis_mode = CHASSIS_ZERO_FORCE;
shoot_cmd_send.shoot_mode = SHOOT_ON;
shoot_cmd_send.friction_mode = FRICTION_ON;
shoot_cmd_send.shoot_mode = SHOOT_OFF;
shoot_cmd_send.friction_mode = FRICTION_OFF;
shoot_cmd_send.loader_mode = LOAD_STOP;
LOGERROR("[CMD] emergency stop!");
}
@ -538,21 +532,17 @@ void RobotCMDTask() {
// 设置视觉发送数据,还需增加加速度和角速度数据
VisionSetFlag(!referee_data->referee_id.Robot_Color);
//根据裁判系统反馈确定底盘功率上限
chassis_cmd_send.chassis_power_limit = referee_data->GameRobotState.chassis_power_limit;
//根据裁判系统反馈确定缓冲功率
chassis_cmd_send.buffer_energy = referee_data->PowerHeatData.buffer_energy;
//根据裁判系统反馈确定枪管热量控制
shoot_cmd_send.heat = referee_data->PowerHeatData.shooter_17mm_1_barrel_heat;
shoot_cmd_send.heat_limit = referee_data->GameRobotState.shooter_barrel_heat_limit;
shoot_cmd_send.heat_cool = referee_data->GameRobotState.shooter_barrel_cooling_value;
if (referee_data->GameRobotState.power_management_chassis_output == 0) {
chassis_cmd_send.chassis_mode = CHASSIS_ZERO_FORCE;
}
if (referee_data->GameRobotState.power_management_gimbal_output == 0) {
gimbal_cmd_send.gimbal_mode = GIMBAL_ZERO_FORCE;
}
// if (referee_data->GameRobotState.power_management_chassis_output == 0) {
// chassis_cmd_send.chassis_mode = CHASSIS_ZERO_FORCE;
// }
// if (referee_data->GameRobotState.power_management_gimbal_output == 0) {
// gimbal_cmd_send.gimbal_mode = GIMBAL_ZERO_FORCE;
// }
// if (referee_data->GameRobotState.power_management_shooter_output == 0) {
// shoot_cmd_send.shoot_mode = SHOOT_ON;
// }

View File

@ -9,7 +9,8 @@
#include "vofa.h"
static attitude_t *gimba_IMU_data; // 云台IMU数据
static DJIMotorInstance *yaw_motor, *pitch_motor;
static DJIMotorInstance *yaw_motor;
static DMMotorInstance *pitch_motor;
static Publisher_t *gimbal_pub; // 云台应用消息发布者(云台反馈给cmd)
static Subscriber_t *gimbal_sub; // cmd控制消息订阅者
@ -28,18 +29,18 @@ void GimbalInit() {
},
.controller_param_init_config = {
.angle_PID = {
.Kp = 0.8f,//1.2
.Kp = 0.0f,//1.2
.Ki = 0.0f,//0
.Kd = 0.04f,//0.05
.Kd = 0.0f,//0.05
.DeadBand = 0.0f,
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement,
.IntegralLimit = 100,
.MaxOut = 500,
},
.speed_PID = {
.Kp = 5000, //4000
.Ki = 100.0f, //100
.Kd = 0.03f, //0
.Kp = 0, //4000
.Ki = 0.0f, //100
.Kd = 0.0f, //0
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement,
.IntegralLimit = 10000,
.MaxOut = 15000,
@ -61,22 +62,22 @@ void GimbalInit() {
// PITCH
Motor_Init_Config_s pitch_config = {
.can_init_config = {
.can_handle = &hcan2,
.tx_id = 1,
.rx_id = 3,
.can_handle = &hcan1,
.tx_id = 0x04,
.rx_id = 0x02,
},
.controller_param_init_config = {
.angle_PID = {
.Kp = 1.0f,
.Kp = 0.0f,
.Ki = 0.0f,
.Kd = 0.02f,
.Kd = 0.0f,
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement,
.IntegralLimit = 100,
.MaxOut = 500,
},
.speed_PID = {
.Kp = 6000.0f,
.Ki = 900.0f,
.Kp = 0.0f,
.Ki = 0.0f,
.Kd = 0.0f, // 0
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement,
.IntegralLimit = 10000,
@ -101,7 +102,7 @@ void GimbalInit() {
};
// 电机对total_angle闭环,上电时为零,会保持静止,收到遥控器数据再动
yaw_motor = DJIMotorInit(&yaw_config);
pitch_motor = DJIMotorInit(&pitch_config);
pitch_motor = DMMotorInit(&pitch_config);
gimbal_pub = PubRegister("gimbal_feed", sizeof(Gimbal_Upload_Data_s));
gimbal_sub = SubRegister("gimbal_cmd", sizeof(Gimbal_Ctrl_Cmd_s));
@ -121,30 +122,26 @@ void GimbalTask() {
// 停止
case GIMBAL_ZERO_FORCE:
DJIMotorStop(yaw_motor);
DJIMotorStop(pitch_motor);
DMMotorStop(pitch_motor);
break;
// 使用陀螺仪的反馈,底盘根据yaw电机的offset跟随云台或视觉模式采用
case GIMBAL_GYRO_MODE: // 后续只保留此模式
DJIMotorEnable(yaw_motor);
DJIMotorEnable(pitch_motor);
DMMotorEnable(pitch_motor);
DJIMotorChangeFeed(yaw_motor, ANGLE_LOOP, OTHER_FEED);
DJIMotorChangeFeed(yaw_motor, SPEED_LOOP, OTHER_FEED);
DJIMotorChangeFeed(pitch_motor, ANGLE_LOOP, OTHER_FEED);
DJIMotorChangeFeed(pitch_motor, SPEED_LOOP, OTHER_FEED);
DJIMotorSetRef(yaw_motor, gimbal_cmd_recv.yaw); // yaw和pitch会在robot_cmd中处理好多圈和单圈
DJIMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
DMMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
//LimitPitchAngleAuto();
break;
// 云台自由模式,使用编码器反馈,底盘和云台分离,仅云台旋转,一般用于调整云台姿态(英雄吊射等)/能量机关
case GIMBAL_FREE_MODE: // 后续删除,或加入云台追地盘的跟随模式(响应速度更快)
DJIMotorEnable(yaw_motor);
DJIMotorEnable(pitch_motor);
DMMotorEnable(pitch_motor);
DJIMotorChangeFeed(yaw_motor, ANGLE_LOOP, OTHER_FEED);
DJIMotorChangeFeed(yaw_motor, SPEED_LOOP, OTHER_FEED);
DJIMotorChangeFeed(pitch_motor, ANGLE_LOOP, OTHER_FEED);
DJIMotorChangeFeed(pitch_motor, SPEED_LOOP, OTHER_FEED);
DJIMotorSetRef(yaw_motor, gimbal_cmd_recv.yaw); // yaw和pitch会在robot_cmd中处理好多圈和单圈
DJIMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
DMMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
break;
default:
break;

View File

@ -24,49 +24,49 @@ static float hibernate_time = 0,last_hibernate_time = 0, dead_time = 0;
void ShootInit()
{
// 左摩擦轮
Motor_Init_Config_s friction_config = {
.can_init_config = {
.can_handle = &hcan2,
},
.controller_param_init_config = {
.speed_PID = {
.Kp = 1.5f,
.Ki = 0.2f,
.Kd = 0,
.Improve = PID_Integral_Limit,
.IntegralLimit = 10000,
.MaxOut = 15000,
},
.current_PID = {
.Kp = 0,
.Ki = 0,
.Kd = 0,
.Improve = PID_Integral_Limit,
.IntegralLimit = 10000,
.MaxOut = 15000,
},
},
.controller_setting_init_config = {
.angle_feedback_source = MOTOR_FEED,
.speed_feedback_source = MOTOR_FEED,
.outer_loop_type = SPEED_LOOP,
.close_loop_type = SPEED_LOOP,
},
.motor_type = M3508};
friction_config.can_init_config.tx_id = 2,
friction_config.controller_setting_init_config.motor_reverse_flag = MOTOR_DIRECTION_NORMAL;
friction_l = DJIMotorInit(&friction_config);
friction_config.can_init_config.tx_id = 3; // 右摩擦轮,改txid和方向就行
friction_config.controller_setting_init_config.motor_reverse_flag = MOTOR_DIRECTION_REVERSE;
friction_r = DJIMotorInit(&friction_config);
// // 左摩擦轮
// Motor_Init_Config_s friction_config = {
// .can_init_config = {
// .can_handle = &hcan2,
// },
// .controller_param_init_config = {
// .speed_PID = {
// .Kp = 1.5f,
// .Ki = 0.2f,
// .Kd = 0,
// .Improve = PID_Integral_Limit,
// .IntegralLimit = 10000,
// .MaxOut = 15000,
// },
// .current_PID = {
// .Kp = 0,
// .Ki = 0,
// .Kd = 0,
// .Improve = PID_Integral_Limit,
// .IntegralLimit = 10000,
// .MaxOut = 15000,
// },
// },
// .controller_setting_init_config = {
// .angle_feedback_source = MOTOR_FEED,
// .speed_feedback_source = MOTOR_FEED,
// .outer_loop_type = SPEED_LOOP,
// .close_loop_type = SPEED_LOOP,
// },
// .motor_type = M3508};
// friction_config.can_init_config.tx_id = 2,
// friction_config.controller_setting_init_config.motor_reverse_flag = MOTOR_DIRECTION_NORMAL;
// friction_l = DJIMotorInit(&friction_config);
//
// friction_config.can_init_config.tx_id = 3; // 右摩擦轮,改txid和方向就行
// friction_config.controller_setting_init_config.motor_reverse_flag = MOTOR_DIRECTION_REVERSE;
// friction_r = DJIMotorInit(&friction_config);
// 拨盘电机
Motor_Init_Config_s loader_config = {
.can_init_config = {
.can_handle = &hcan1,
.tx_id = 2
.tx_id = 3
},
.controller_param_init_config = {
.angle_PID = {
@ -105,13 +105,11 @@ void ShootInit()
};
loader = DJIMotorInit(&loader_config);
shoot_pub = PubRegister("shoot_feed", sizeof(Shoot_Upload_Data_s));
shoot_sub = SubRegister("shoot_cmd", sizeof(Shoot_Ctrl_Cmd_s));
Pwmmotor_Init_Config_s friction_l1_config = {
.htim = &htim8,
.Channel = TIM_CHANNEL_1,
.Pwmmotor_type = 0,
.Initial_value = 1000,
};
friction_l1 = PwmmotorInit(&friction_l1_config);
@ -119,9 +117,12 @@ void ShootInit()
.htim = &htim8,
.Channel = TIM_CHANNEL_2,
.Pwmmotor_type = 0,
.Initial_value = 1000,
};
friction_r1 = PwmmotorInit(&friction_r1_config);
shoot_pub = PubRegister("shoot_feed", sizeof(Shoot_Upload_Data_s));
shoot_sub = SubRegister("shoot_cmd", sizeof(Shoot_Ctrl_Cmd_s));
// SPI_Init_Config_s rgb_config = {
// .spi_handle = ;
// .GPIOx = GPIOx;
@ -164,7 +165,6 @@ void stalled_detect()
/* 机器人发射机构控制核心任务 */
void ShootTask()
{
//WS2812_Number_4(0x000018,0x000018,0x000018,0x000018);
//从cmd获取控制数据
SubGetMessage(shoot_sub, &shoot_cmd_recv);
@ -173,15 +173,19 @@ void ShootTask()
{
//DJIMotorSetRef(friction_l, 0);
//DJIMotorSetRef(friction_r, 0);
Pwm_Motor_Stop(friction_l1, 1000);
Pwm_Motor_Stop(friction_r1, 1000);
DJIMotorEnable(loader);
}
else // 恢复运行
{
//DJIMotorEnable(friction_l);
//DJIMotorEnable(friction_r);
Pwm_MotorControl(friction_l1, 2000);
Pwm_MotorControl(friction_r1, 2000);
DJIMotorEnable(loader);
}
DJIMotorEnable(loader);
// 如果上一次触发单发或3发指令的时间加上不应期仍然大于当前时间(尚未休眠完毕),直接返回即可
// 单发模式主要提供给能量机关激活使用(以及英雄的射击大部分处于单发)
if (hibernate_time + dead_time > DWT_GetTimeline_ms())
@ -250,8 +254,8 @@ void ShootTask()
// DJIMotorSetRef(friction_r, 0);
// break;
//default: // 当前为了调试设定的默认值4000,因为还没有加入裁判系统无法读取弹速.
DJIMotorSetRef(friction_l, 39000);
DJIMotorSetRef(friction_r, 39000);
//DJIMotorSetRef(friction_l, 39000);
//DJIMotorSetRef(friction_r, 39000);
// break;
// }
@ -260,8 +264,8 @@ void ShootTask()
}
else // 关闭摩擦轮
{
DJIMotorSetRef(friction_l, 0);
DJIMotorSetRef(friction_r, 0);
//DJIMotorSetRef(friction_l, 0);
//DJIMotorSetRef(friction_r, 0);
Pwm_Motor_Stop(friction_l1, 1000);
Pwm_Motor_Stop(friction_r1, 1000);

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@
extern TIM_HandleTypeDef htim8;
static PwmmotorInstance *pwm_motor_instance[PWM_MOTOR_CNT] = {NULL};
static int16_t compare_value[PWM_MOTOR_CNT] = {0};
int16_t k = 1800/350, b = 400;
static uint8_t pwmmotor_idx = 0; // register pwmmotor_idx,是该文件的全局电机索引,在注册时使用
// 通过此函数注册一个电机
@ -19,8 +18,9 @@ PwmmotorInstance *PwmmotorInit(Pwmmotor_Init_Config_s *Pwmmotor_Init_Config)
pwmmotor->htim = Pwmmotor_Init_Config->htim;
pwmmotor->Channel = Pwmmotor_Init_Config->Channel;
HAL_TIM_Base_Start(Pwmmotor_Init_Config->htim);
HAL_TIM_PWM_Start(Pwmmotor_Init_Config->htim, Pwmmotor_Init_Config->Channel);
__HAL_TIM_SET_COMPARE(pwmmotor->htim, pwmmotor->Channel, 1000);//只有有了油门值Snail电机才能初始化完成不会发出b b b b的叫声。如下设定初始油门值
__HAL_TIM_SET_COMPARE(Pwmmotor_Init_Config->htim, Pwmmotor_Init_Config->Channel, Pwmmotor_Init_Config->Initial_value);//只有有了油门值Snail电机才能初始化完成不会发出b b b b的叫声。如下设定初始油门值
pwm_motor_instance[pwmmotor_idx++] = pwmmotor;
return pwmmotor;
}

View File

@ -47,6 +47,8 @@ typedef struct
*TIM_CHANNEL_ALL
*/
uint32_t Channel;
//油门初始值
int16_t Initial_value;
} Pwmmotor_Init_Config_s;