2 Commits

Author SHA1 Message Date
Zorua
0b0b62f6f9 4310pitch driver bug solved 2026-03-21 15:34:10 +08:00
guoxy06
3ebb57d86b 修改RectifyRCjoystick()改了左摇杆限幅 2026-03-15 16:41:00 +08:00
6 changed files with 70 additions and 29 deletions

View File

@@ -113,14 +113,14 @@ void ChassisInit()
.can_init_config.can_handle = &hcan1, .can_init_config.can_handle = &hcan1,
.controller_param_init_config = { .controller_param_init_config = {
.angle_PID = { .angle_PID = {
.Kp = 12, .Kp = 35,
.Ki = 0.2, .Ki = 0.25,
.Kd = 0, .Kd = 0,
.CoefA = 3, .CoefA = 3,
.CoefB = 0.1, .CoefB = 0.1,
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement | PID_DerivativeFilter | PID_ChangingIntegrationRate, .Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement | PID_DerivativeFilter | PID_ChangingIntegrationRate,
.IntegralLimit = 1000, .IntegralLimit = 1500,
.MaxOut = 5000, .MaxOut = 6000,
.Derivative_LPF_RC = 0.001, .Derivative_LPF_RC = 0.001,
.DeadBand = 0.5, .DeadBand = 0.5,
}, },
@@ -151,7 +151,7 @@ void ChassisInit()
motor_steering_lb = DJIMotorInit(&chassis_motor_steering_config); motor_steering_lb = DJIMotorInit(&chassis_motor_steering_config);
PID_Init_Config_s chassis_follow_pid_conf = { PID_Init_Config_s chassis_follow_pid_conf = {
.Kp = 1.05, // 6 .Kp = 0.95, // 6
.Ki = 0, .Ki = 0,
.Kd = 0.1, // 0.495 .Kd = 0.1, // 0.495
.DeadBand = 0.5f,// 启用死区,值为0.5度 .DeadBand = 0.5f,// 启用死区,值为0.5度

View File

@@ -203,14 +203,13 @@ static void RemoteControlSet()
// 左侧开关状态为[下],或视觉未识别到目标,纯遥控器拨杆控制 // 左侧开关状态为[下],或视觉未识别到目标,纯遥控器拨杆控制
if (switch_is_down(rc_data[TEMP].rc.switch_left) ) if (switch_is_down(rc_data[TEMP].rc.switch_left) )
{ // 按照摇杆的输出大小进行角度增量,增益系数需调整 { // 按照摇杆的输出大小进行角度增量,增益系数需调整
gimbal_cmd_send.yaw += 0.005f * (float)rc_data[TEMP].rc.rocker_l_; gimbal_cmd_send.yaw += 0.005f * (float)rc_data[TEMP].rc.rocker_r_;
gimbal_cmd_send.pitch += 0.001f * (float)rc_data[TEMP].rc.rocker_l1; gimbal_cmd_send.pitch += 0.001f * (float)rc_data[TEMP].rc.rocker_r1;
} }
// 云台软件限位 // 云台软件限位
// 底盘参数,目前没有加入小陀螺(调试似乎暂时没有必要),系数需要调整 // 底盘参数,目前没有加入小陀螺(调试似乎暂时没有必要),系数需要调整
chassis_cmd_send.vx = 0.15f * (float)rc_data[TEMP].rc.rocker_r_; // _水平方向 chassis_cmd_send.vx = 0.15f * (float)rc_data[TEMP].rc.rocker_l_; // _水平方向
chassis_cmd_send.vy = 0.15f * (float)rc_data[TEMP].rc.rocker_r1; // 1数值方向 chassis_cmd_send.vy = 0.15f * (float)rc_data[TEMP].rc.rocker_l1; // 1数值方向
// // 发射参数 // // 发射参数
// if (switch_is_up(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[上],弹舱打开 // if (switch_is_up(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[上],弹舱打开

View File

@@ -26,10 +26,10 @@ void GimbalInit()
}, },
.controller_param_init_config = { .controller_param_init_config = {
.angle_PID = { .angle_PID = {
//.Kp = 0.685, // 8 //.Kp = 0.785, // 8
.Kp = 0.585, // 8 .Kp = 3, // 8
//.Ki = 0.315, //.Ki = 0.315,
.Ki = 0.25, .Ki = 0.45,
.Kd = 0.03, .Kd = 0.03,
//.DeadBand = 0.1 //.DeadBand = 0.1
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement | PID_DerivativeFilter | PID_ChangingIntegrationRate, .Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement | PID_DerivativeFilter | PID_ChangingIntegrationRate,
@@ -40,9 +40,9 @@ void GimbalInit()
.Derivative_LPF_RC = 0.001 .Derivative_LPF_RC = 0.001
}, },
.speed_PID = { .speed_PID = {
.Kp = 8000, // 50 .Kp = 500, // 50
//.Kp = 5000, // 50 //.Kp = 5000, // 50
.Ki = 5000, // 200 .Ki = 2000, // 200
.Kd = 0, .Kd = 0,
.CoefB = 1, .CoefB = 1,
.CoefA = 10, .CoefA = 10,
@@ -132,7 +132,18 @@ void GimbalTask()
DJIMotorChangeFeed(pitch_motor, SPEED_LOOP, OTHER_FEED); DJIMotorChangeFeed(pitch_motor, SPEED_LOOP, OTHER_FEED);
DJIMotorSetRef(yaw_motor, gimbal_cmd_recv.yaw); // yaw和pitch会在robot_cmd中处理好多圈和单圈 DJIMotorSetRef(yaw_motor, gimbal_cmd_recv.yaw); // yaw和pitch会在robot_cmd中处理好多圈和单圈
DJIMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch); DJIMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
break; // // 根据底盘速度进行补偿,保持云台稳定
// // 这里简化处理,实际应用中可能需要更复杂的补偿算法
// float yaw_ref = gimbal_cmd_recv.yaw;
// float pitch_ref = gimbal_cmd_recv.pitch;
//
// // 当底盘移动时,云台需要保持相对稳定
// // 这里可以根据底盘速度调整云台的控制参考值
// // 例如,当底盘向前移动时,云台可能需要稍微向后调整以保持稳定
//
// DJIMotorSetRef(yaw_motor, yaw_ref); // yaw和pitch会在robot_cmd中处理好多圈和单圈
// DJIMotorSetRef(pitch_motor, pitch_ref);
break;
// 云台自由模式,使用编码器反馈,底盘和云台分离,仅云台旋转,一般用于调整云台姿态(英雄吊射等)/能量机关 // 云台自由模式,使用编码器反馈,底盘和云台分离,仅云台旋转,一般用于调整云台姿态(英雄吊射等)/能量机关
case GIMBAL_FREE_MODE: // 后续删除,或加入云台追地盘的跟随模式(响应速度更快) case GIMBAL_FREE_MODE: // 后续删除,或加入云台追地盘的跟随模式(响应速度更快)
DJIMotorEnable(yaw_motor); DJIMotorEnable(yaw_motor);
@@ -159,4 +170,13 @@ void GimbalTask()
// gimbal_feedback_data.yaw_motor_total_angle = gimba_IMU_data->YawTotalAngle; // gimbal_feedback_data.yaw_motor_total_angle = gimba_IMU_data->YawTotalAngle;
// 推送消息 // 推送消息
PubPushMessage(gimbal_pub, (void *)&gimbal_feedback_data); PubPushMessage(gimbal_pub, (void *)&gimbal_feedback_data);
} }
// /**
// * @brief 获取云台IMU数据指针
// *
// * @return attitude_t* 云台IMU数据指针
// */
// attitude_t *GetGimbalIMUData()
// {
// return gimba_IMU_data;
// }

View File

@@ -1,6 +1,6 @@
#ifndef GIMBAL_H #ifndef GIMBAL_H
#define GIMBAL_H #define GIMBAL_H
#include "../modules/imu/ins_task.h"
/** /**
* @brief 初始化云台,会被RobotInit()调用 * @brief 初始化云台,会被RobotInit()调用
* *
@@ -9,8 +9,8 @@ void GimbalInit();
/** /**
* @brief 云台任务 * @brief 云台任务
* * @return attitude_t* 云台IMU数据指针
*/ */
void GimbalTask(); void GimbalTask();
//attitude_t *GetGimbalIMUData();
#endif // GIMBAL_H #endif // GIMBAL_H

View File

@@ -24,10 +24,12 @@ static CANInstance sender_assignment[6] = {
[1] = {.can_handle = &hcan1, .txconf.StdId = 0x200, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}}, [1] = {.can_handle = &hcan1, .txconf.StdId = 0x200, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[2] = {.can_handle = &hcan1, .txconf.StdId = 0x2ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}}, [2] = {.can_handle = &hcan1, .txconf.StdId = 0x2ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[3] = {.can_handle = &hcan2, .txconf.StdId = 0x1ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}}, [3] = {.can_handle = &hcan2, .txconf.StdId = 0x1ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[4] = {.can_handle = &hcan2, .txconf.StdId = 0x3FE, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}}, [4] = {.can_handle = &hcan2, .txconf.StdId = 0x200, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[5] = {.can_handle = &hcan2, .txconf.StdId = 0x2ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}}, [5] = {.can_handle = &hcan2, .txconf.StdId = 0x2ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
}; };
static CANInstance DM_sender_assignment[1] = {
[0] = {.can_handle = &hcan2, .txconf.StdId = 0x3FE, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}}
};
/** /**
* @brief 6个用于确认是否有电机注册到sender_assignment中的标志位,防止发送空帧,此变量将在DJIMotorControl()使用 * @brief 6个用于确认是否有电机注册到sender_assignment中的标志位,防止发送空帧,此变量将在DJIMotorControl()使用
* flag的初始化在 MotorSenderGrouping()中进行 * flag的初始化在 MotorSenderGrouping()中进行
@@ -326,10 +328,10 @@ void DJIMotorControl()
group = motor->sender_group; group = motor->sender_group;
num = motor->message_num; num = motor->message_num;
if (i == 1) if (i == 1)//pitch轴电机对应i值为1,需要特殊处理,因为它的发送顺序和其他电机不同,在同一帧中与其他电机的高八位和低八位相反
{ {
sender_assignment[4].tx_buff[6] = (uint8_t)(set & 0x00ff); // 高八位 DM_sender_assignment[0].tx_buff[6] = (uint8_t)(set & 0x00ff); // 高八位
sender_assignment[4].tx_buff[7] = (uint8_t)(set >> 8); // 低八位 DM_sender_assignment[0].tx_buff[7] = (uint8_t)(set >> 8); // 低八位
} }
else else
{ {
@@ -348,6 +350,7 @@ void DJIMotorControl()
if (sender_enable_flag[i]) if (sender_enable_flag[i])
{ {
CANTransmit(&sender_assignment[i], 1); CANTransmit(&sender_assignment[i], 1);
CANTransmit(&DM_sender_assignment[0], 1);//达妙电机单独一帧发送
} }
} }
} }

View File

@@ -20,13 +20,32 @@ static DaemonInstance *rc_daemon_instance;
* @brief 矫正遥控器摇杆的值,超过660或者小于-660的值都认为是无效值,置0 * @brief 矫正遥控器摇杆的值,超过660或者小于-660的值都认为是无效值,置0
* *
*/ */
static void RectifyRCjoystick() // static void RectifyRCjoystick()
// {
// for (uint8_t i = 0; i < 5; ++i)
// if (abs(*(&rc_ctrl[TEMP].rc.rocker_l_ + i)) > 660)
// *(&rc_ctrl[TEMP].rc.rocker_l_ + i) = 0;
// }
static void RectifyRCjoystick()//左遥杆水平向右限幅不够,因为下面的+3,将+3删除就用上面的
{ {
int16_t *rocker_ptr = &rc_ctrl[TEMP].rc.rocker_l_;
for (uint8_t i = 0; i < 5; ++i) for (uint8_t i = 0; i < 5; ++i)
if (abs(*(&rc_ctrl[TEMP].rc.rocker_l_ + i)) > 660) {
*(&rc_ctrl[TEMP].rc.rocker_l_ + i) = 0; if (i == 0) // 左遥杆水平方向
{
// 增加右向最大值到700,左向保持660不变
if (rocker_ptr[i] > 700)
rocker_ptr[i] = 700;
else if (rocker_ptr[i] < -660)
rocker_ptr[i] = -660;
}
else // 其他通道保持原限制
{
if (abs(rocker_ptr[i]) > 660)
rocker_ptr[i] = 0;
}
}
} }
/** /**
* @brief 遥控器数据解析 * @brief 遥控器数据解析
* *