Files
Gimbal/application/gimbal/gimbal.c
T
SkyLiCoder 4d1702b577 refactor: migrate from DJI motors to DM motors, simplify to gimbal-only control
- Rewrite DM motor driver based on DM_6220 reference protocol (MIT/PosVel/Velocity modes)
- Use velocity control mode: MCU runs angle PID with IMU feedback, motor handles speed loop
- Rewrite vision protocol with 3 frame types (0xA5 auto data, 0xA6 manual data, 0xA7 command)
- Decouple serial parsing (opencv module) from mode switching (robot_cmd module)
- Implement dual-loop architecture: vision PID outer loop → angle ref → motor PID inner loop
- Add KF/PID reset on mode switch transitions
- Merge motor_reverse_flag and feedback_reverse_flag into single output_reverse flag
- Remove DMMotorEnable/DMMotorStop (motor always runs, controlled by angle ref)
- Remove unused modules: DJI/LK/HT/step/servo motors, chassis, shoot, referee
- Add ExitRun0Mode() for STM32H723 power supply configuration
- Clean up CMakeLists: 115 → 76 C source files
2026-05-29 23:37:36 +08:00

114 lines
4.0 KiB
C

#include "gimbal.h"
#include "robot_def.h"
#include "dmmotor.h"
#include "ins_task.h"
#include "message_center.h"
#include "general_def.h"
static attitude_t *gimbal_IMU_data;
static Publisher_t *gimbal_pub;
static Subscriber_t *gimbal_sub;
static Gimbal_Upload_Data_s gimbal_feedback_data;
static Gimbal_Ctrl_Cmd_s gimbal_cmd_recv;
static DMMotorInstance *yaw_motor; // DM-G6220
static DMMotorInstance *pitch_motor; // DM-J4310-2EC
void GimbalInit()
{
gimbal_IMU_data = INS_Init();
gimbal_pub = PubRegister("gimbal_feed", sizeof(Gimbal_Upload_Data_s));
gimbal_sub = SubRegister("gimbal_cmd", sizeof(Gimbal_Ctrl_Cmd_s));
/* ---- Yaw: DM-G6220, CAN1, TX=0x01, RX=0xF1, Velocity模式 ---- */
DM_Motor_Init_Config_s yaw_config = {
.motor_config = {
.can_init_config = {
.can_handle = &hcan1,
.tx_id = 0x01,
.rx_id = 0xF1,
},
.controller_param_init_config = {
.angle_PID = {
.Kp = 30, .Ki = 80, .Kd = 0.2f,
.IntegralLimit = 1000,
.CoefA = 20, .CoefB = 10,
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit |
PID_Derivative_On_Measurement | PID_ChangingIntegrationRate |
PID_DerivativeFilter | PID_OutputFilter,
.MaxOut = 2000,
},
.other_angle_feedback_ptr = &gimbal_IMU_data->YawTotalAngle,
.other_speed_feedback_ptr = &gimbal_IMU_data->Gyro[2],
},
.controller_setting_init_config = {
.angle_feedback_source = OTHER_FEED,
.speed_feedback_source = OTHER_FEED,
.outer_loop_type = ANGLE_LOOP,
.close_loop_type = ANGLE_LOOP,
.output_reverse = OUTPUT_DIRECTION_NORMAL,
},
.motor_type = DM_MOTOR,
},
.ctrl_mode = DM_MODE_VELOCITY,
.mit_kp = 0, .mit_kd = 0,
};
yaw_motor = DMMotorInit(&yaw_config);
/* ---- Pitch: DM-J4310-2EC, CAN1, TX=0x02, RX=0xF2, Velocity模式 ---- */
DM_Motor_Init_Config_s pitch_config = {
.motor_config = {
.can_init_config = {
.can_handle = &hcan1,
.tx_id = 0x02,
.rx_id = 0xF2,
},
.controller_param_init_config = {
.angle_PID = {
.Kp = 20, .Ki = 50, .Kd = 0.1f,
.IntegralLimit = 500,
.CoefA = 15, .CoefB = 5,
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit |
PID_Derivative_On_Measurement | PID_ChangingIntegrationRate,
.MaxOut = 1000,
},
.other_angle_feedback_ptr = &gimbal_IMU_data->Pitch,
.other_speed_feedback_ptr = &gimbal_IMU_data->Gyro[0],
},
.controller_setting_init_config = {
.angle_feedback_source = OTHER_FEED,
.speed_feedback_source = OTHER_FEED,
.outer_loop_type = ANGLE_LOOP,
.close_loop_type = ANGLE_LOOP,
.output_reverse = OUTPUT_DIRECTION_NORMAL,
},
.motor_type = DM_MOTOR,
},
.ctrl_mode = DM_MODE_VELOCITY,
.mit_kp = 0, .mit_kd = 0,
};
pitch_motor = DMMotorInit(&pitch_config);
}
void GimbalTask()
{
SubGetMessage(gimbal_sub, &gimbal_cmd_recv);
if (gimbal_cmd_recv.gimbal_mode == GIMBAL_ZERO_FORCE)
{
/* 零力模式: 保持当前IMU角度, 电机不主动出力 */
DMMotorSetRef(yaw_motor, gimbal_IMU_data->YawTotalAngle);
DMMotorSetRef(pitch_motor, gimbal_IMU_data->Pitch);
}
else
{
DMMotorSetRef(yaw_motor, gimbal_cmd_recv.yaw);
DMMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
}
gimbal_feedback_data.gimbal_imu_data = *gimbal_IMU_data;
PubPushMessage(gimbal_pub, (void *)&gimbal_feedback_data);
}