2024-04-28 19:22:24 +08:00
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
2024-04-25 23:12:31 +08:00
|
|
|
|
#include "gimbal.h"
|
|
|
|
|
#include "robot_def.h"
|
|
|
|
|
#include "dji_motor.h"
|
2024-05-07 14:06:47 +08:00
|
|
|
|
#include "dmmotor.h"
|
2024-04-25 23:12:31 +08:00
|
|
|
|
#include "ins_task.h"
|
|
|
|
|
#include "message_center.h"
|
|
|
|
|
#include "general_def.h"
|
|
|
|
|
#include "bmi088.h"
|
2024-05-07 14:06:47 +08:00
|
|
|
|
#include "user_lib.h"
|
2024-04-28 19:22:24 +08:00
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#include "matrix.h"
|
|
|
|
|
#include "robotics.h"
|
2024-04-25 23:12:31 +08:00
|
|
|
|
|
|
|
|
|
static attitude_t *gimba_IMU_data; // 云台IMU数据
|
2024-05-07 14:06:47 +08:00
|
|
|
|
static DMMotorInstance *yaw_motor, *pitch_motor, *roll_motor;
|
|
|
|
|
static DMMotorInstance *diff_r_motor,*diff_l_motor;
|
|
|
|
|
|
|
|
|
|
static PIDInstance diff_pitch_loop,diff_roll_loop;
|
|
|
|
|
static PIDInstance diff_pitch_spd_loop,diff_roll_spd_loop;
|
|
|
|
|
|
|
|
|
|
float arm_gravity_feedforward = 0;
|
|
|
|
|
float GRAVITY_COMP = 5.5;
|
2024-04-25 23:12:31 +08:00
|
|
|
|
|
|
|
|
|
static Publisher_t *gimbal_pub; // 云台应用消息发布者(云台反馈给cmd)
|
|
|
|
|
static Subscriber_t *gimbal_sub; // cmd控制消息订阅者
|
|
|
|
|
static Gimbal_Upload_Data_s gimbal_feedback_data; // 回传给cmd的云台状态信息
|
|
|
|
|
static Gimbal_Ctrl_Cmd_s gimbal_cmd_recv; // 来自cmd的控制信息
|
|
|
|
|
|
2024-05-07 14:06:47 +08:00
|
|
|
|
first_order_filter_type_t pitch_spd_filter,yaw_spd_filter,roll_spd_filter;
|
|
|
|
|
static float pitch_spd,yaw_spd,roll_spd;
|
|
|
|
|
|
|
|
|
|
first_order_filter_type_t diff_r_spd_filter,diff_l_spd_filter;
|
|
|
|
|
static float diff_r_spd,diff_l_spd;
|
|
|
|
|
|
2024-04-25 23:12:31 +08:00
|
|
|
|
void GimbalInit()
|
|
|
|
|
{
|
2024-05-07 14:06:47 +08:00
|
|
|
|
Motor_Init_Config_s yaw_motor_config = {
|
|
|
|
|
.controller_param_init_config = {
|
|
|
|
|
.other_speed_feedback_ptr = &yaw_spd,
|
|
|
|
|
.speed_PID = {
|
|
|
|
|
.Kp = 3,//5,
|
|
|
|
|
.Ki = 3.0f,
|
|
|
|
|
.Kd = 0.02f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 10.0F,
|
|
|
|
|
},
|
|
|
|
|
.angle_PID = {
|
|
|
|
|
.Kp = 10.0f,//13.0f,
|
|
|
|
|
.Ki = 0.0f,
|
|
|
|
|
.Kd = 0.0f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 10.0F,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
.controller_setting_init_config = {
|
|
|
|
|
.outer_loop_type = ANGLE_LOOP,
|
|
|
|
|
.close_loop_type = static_cast<Closeloop_Type_e>(ANGLE_LOOP | SPEED_LOOP),
|
|
|
|
|
.angle_feedback_source = MOTOR_FEED,
|
|
|
|
|
.speed_feedback_source = OTHER_FEED,
|
|
|
|
|
.feedforward_flag = CURRENT_FEEDFORWARD,
|
|
|
|
|
},
|
|
|
|
|
.motor_type = DM6006,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
yaw_motor_config.can_init_config.can_handle = &hcan2;
|
|
|
|
|
yaw_motor_config.can_init_config.tx_id = 1;
|
|
|
|
|
yaw_motor_config.can_init_config.rx_id = 2;
|
|
|
|
|
yaw_motor = DMMotorInit(&yaw_motor_config);
|
|
|
|
|
|
|
|
|
|
Motor_Init_Config_s pitch_motor_config = {
|
|
|
|
|
.controller_param_init_config = {
|
|
|
|
|
.other_speed_feedback_ptr = &pitch_spd,
|
|
|
|
|
.current_feedforward_ptr = &arm_gravity_feedforward,
|
|
|
|
|
.speed_PID = {
|
|
|
|
|
.Kp = 2.5f,
|
|
|
|
|
.Ki = 0.8f,
|
|
|
|
|
.Kd = 0.0f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 10.0F,
|
|
|
|
|
},
|
|
|
|
|
.angle_PID = {
|
|
|
|
|
.Kp = 8.0f,
|
|
|
|
|
.Ki = 0.0f,
|
|
|
|
|
.Kd = 0.0f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 10.0F,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
.controller_setting_init_config = {
|
|
|
|
|
.outer_loop_type = ANGLE_LOOP,
|
|
|
|
|
.close_loop_type = static_cast<Closeloop_Type_e>(ANGLE_LOOP | SPEED_LOOP),
|
|
|
|
|
.angle_feedback_source = MOTOR_FEED,
|
|
|
|
|
.speed_feedback_source = OTHER_FEED,
|
|
|
|
|
.feedforward_flag = CURRENT_FEEDFORWARD,
|
|
|
|
|
},
|
|
|
|
|
.motor_type = DM6006,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pitch_motor_config.can_init_config.can_handle = &hcan2;
|
|
|
|
|
pitch_motor_config.can_init_config.tx_id = 3;
|
|
|
|
|
pitch_motor_config.can_init_config.rx_id = 4;
|
|
|
|
|
pitch_motor = DMMotorInit(&pitch_motor_config);
|
|
|
|
|
|
|
|
|
|
//@todo:roll轴机械固定不牢 待细调
|
|
|
|
|
Motor_Init_Config_s roll_motor_config = {
|
|
|
|
|
.controller_param_init_config = {
|
|
|
|
|
.other_speed_feedback_ptr = &roll_spd,
|
|
|
|
|
.speed_PID = {
|
|
|
|
|
.Kp = 0.8f,
|
|
|
|
|
.Ki = 0.3f,
|
|
|
|
|
.Kd = 0.02f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 10.0F,
|
|
|
|
|
},
|
|
|
|
|
.angle_PID = {
|
|
|
|
|
.Kp = 10.0f,
|
|
|
|
|
.Ki = 0.0f,
|
|
|
|
|
.Kd = 0.0f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 10.0F,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
.controller_setting_init_config = {
|
|
|
|
|
.outer_loop_type = ANGLE_LOOP,
|
|
|
|
|
.close_loop_type = static_cast<Closeloop_Type_e>(ANGLE_LOOP | SPEED_LOOP),
|
|
|
|
|
.angle_feedback_source = MOTOR_FEED,
|
|
|
|
|
.speed_feedback_source = OTHER_FEED,
|
|
|
|
|
//.feedforward_flag = CURRENT_FEEDFORWARD,
|
|
|
|
|
},
|
|
|
|
|
.motor_type = DM4310,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
roll_motor_config.can_init_config.can_handle = &hcan2;
|
|
|
|
|
roll_motor_config.can_init_config.tx_id = 5;
|
|
|
|
|
roll_motor_config.can_init_config.rx_id = 6;
|
|
|
|
|
roll_motor = DMMotorInit(&roll_motor_config);
|
|
|
|
|
|
|
|
|
|
Motor_Init_Config_s diff_motor_config = {
|
|
|
|
|
.controller_setting_init_config = {
|
|
|
|
|
.outer_loop_type = OPEN_LOOP,
|
|
|
|
|
.close_loop_type = OPEN_LOOP,
|
|
|
|
|
.angle_feedback_source = MOTOR_FEED,
|
|
|
|
|
.speed_feedback_source = OTHER_FEED,
|
|
|
|
|
//.feedforward_flag = CURRENT_FEEDFORWARD,
|
|
|
|
|
},
|
|
|
|
|
.motor_type = DM4310,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
diff_motor_config.can_init_config.can_handle = &hcan2;
|
|
|
|
|
diff_motor_config.can_init_config.tx_id = 7;
|
|
|
|
|
diff_motor_config.can_init_config.rx_id = 8;
|
|
|
|
|
diff_motor_config.controller_param_init_config.other_speed_feedback_ptr = &diff_r_spd;
|
|
|
|
|
diff_r_motor = DMMotorInit(&diff_motor_config);
|
|
|
|
|
|
|
|
|
|
diff_motor_config.can_init_config.can_handle = &hcan2;
|
|
|
|
|
diff_motor_config.can_init_config.tx_id = 9;
|
|
|
|
|
diff_motor_config.can_init_config.rx_id = 10;
|
|
|
|
|
diff_motor_config.controller_param_init_config.other_speed_feedback_ptr = &diff_l_spd;
|
|
|
|
|
diff_l_motor = DMMotorInit(&diff_motor_config);
|
|
|
|
|
|
|
|
|
|
const float spd_filter_num = 0.05f;
|
|
|
|
|
first_order_filter_init(&pitch_spd_filter,5e-3,&spd_filter_num);
|
|
|
|
|
const float spd_filter_num_yaw = 0.1f;
|
|
|
|
|
first_order_filter_init(&yaw_spd_filter,5e-3,&spd_filter_num_yaw);
|
|
|
|
|
const float spd_filter_num_roll = 0.05f;
|
|
|
|
|
first_order_filter_init(&roll_spd_filter,5e-3,&spd_filter_num_roll);
|
2024-04-25 23:12:31 +08:00
|
|
|
|
|
2024-05-07 14:06:47 +08:00
|
|
|
|
const float spd_filter_num_diff = 0.05f;
|
|
|
|
|
first_order_filter_init(&diff_r_spd_filter,5e-3,&spd_filter_num_diff);
|
|
|
|
|
first_order_filter_init(&diff_l_spd_filter,5e-3,&spd_filter_num_diff);
|
2024-04-25 23:12:31 +08:00
|
|
|
|
|
2024-05-07 14:06:47 +08:00
|
|
|
|
PID_Init_Config_s diff_pitch_config= {
|
|
|
|
|
.Kp = 15.0f,
|
|
|
|
|
.Ki = 0,
|
|
|
|
|
.Kd = 0,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 100,
|
|
|
|
|
};
|
|
|
|
|
PIDInit(&diff_pitch_loop,&diff_pitch_config);
|
|
|
|
|
|
|
|
|
|
PID_Init_Config_s diff_pitch_spd_config= {
|
|
|
|
|
.Kp = 0.6f,
|
|
|
|
|
.Ki = 2.0f,
|
|
|
|
|
.Kd = 0.01f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 100,
|
|
|
|
|
};
|
|
|
|
|
PIDInit(&diff_pitch_spd_loop,&diff_pitch_spd_config);
|
|
|
|
|
|
|
|
|
|
PID_Init_Config_s diff_roll_config= {
|
|
|
|
|
.Kp = 14.0f,
|
|
|
|
|
.Ki = 0,
|
|
|
|
|
.Kd = 0,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 100,
|
|
|
|
|
};
|
|
|
|
|
PIDInit(&diff_roll_loop,&diff_roll_config);
|
|
|
|
|
|
|
|
|
|
PID_Init_Config_s diff_roll_spd_config= {
|
|
|
|
|
.Kp = 1.0f,
|
|
|
|
|
.Ki = 1.0f,
|
|
|
|
|
.Kd = 0.02f,
|
|
|
|
|
.MaxOut = 10,
|
|
|
|
|
.Improve = static_cast<PID_Improvement_e>(PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement),
|
|
|
|
|
.IntegralLimit = 100,
|
|
|
|
|
};
|
|
|
|
|
PIDInit(&diff_roll_spd_loop,&diff_roll_spd_config);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gimba_IMU_data = INS_Init(); // IMU先初始化,获取姿态数据指针赋给yaw电机的其他数据来源
|
|
|
|
|
// YAW
|
2024-04-25 23:12:31 +08:00
|
|
|
|
gimbal_pub = PubRegister("gimbal_feed", sizeof(Gimbal_Upload_Data_s));
|
|
|
|
|
gimbal_sub = SubRegister("gimbal_cmd", sizeof(Gimbal_Ctrl_Cmd_s));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 机器人云台控制核心任务,后续考虑只保留IMU控制,不再需要电机的反馈 */
|
|
|
|
|
void GimbalTask()
|
|
|
|
|
{
|
2024-04-28 19:22:24 +08:00
|
|
|
|
/* Example 1: PUMA560 ------------------------------------------------------------------------*/
|
|
|
|
|
float m[6] = {0.2645, 0.17, 0.1705, 0, 0, 0};
|
|
|
|
|
float data[18]={0, -8.5e-2, 0, 0, 0, 0,
|
|
|
|
|
13.225e-2, 0, 0, 0, 0, 0,
|
|
|
|
|
0, 3.7e-2, 8.525e-2, 0, 0, 0};
|
|
|
|
|
Matrixf<3, 6> rc(data);
|
|
|
|
|
Matrixf<3, 3> I[6];
|
2024-04-25 23:12:31 +08:00
|
|
|
|
// 获取云台控制数据
|
|
|
|
|
// 后续增加未收到数据的处理
|
|
|
|
|
SubGetMessage(gimbal_sub, &gimbal_cmd_recv);
|
2024-05-07 14:06:47 +08:00
|
|
|
|
//大臂重力补偿力矩
|
|
|
|
|
arm_gravity_feedforward = - GRAVITY_COMP * arm_cos_f32(- pitch_motor->measure.position);
|
|
|
|
|
//电机速度滤波
|
|
|
|
|
first_order_filter_cali(&pitch_spd_filter,pitch_motor->measure.velocity);
|
|
|
|
|
pitch_spd = pitch_spd_filter.out;
|
|
|
|
|
first_order_filter_cali(&yaw_spd_filter,yaw_motor->measure.velocity);
|
|
|
|
|
yaw_spd = yaw_spd_filter.out;
|
|
|
|
|
first_order_filter_cali(&roll_spd_filter,roll_motor->measure.velocity);
|
|
|
|
|
roll_spd = roll_spd_filter.out;
|
|
|
|
|
|
|
|
|
|
//手腕关节
|
|
|
|
|
first_order_filter_cali(&diff_r_spd_filter,diff_r_motor->measure.velocity);
|
|
|
|
|
diff_r_spd = diff_r_spd_filter.out;
|
|
|
|
|
first_order_filter_cali(&diff_l_spd_filter,diff_l_motor->measure.velocity);
|
|
|
|
|
diff_l_spd = diff_l_spd_filter.out;
|
|
|
|
|
|
|
|
|
|
float diff_pitch_angle = (diff_r_motor->measure.position + (-diff_l_motor->measure.position))/2;
|
|
|
|
|
float diff_roll_angle = (diff_r_motor->measure.position - (-diff_l_motor->measure.position))/2 * 18/52;
|
|
|
|
|
|
|
|
|
|
float pitch_angle_out = PIDCalculate(&diff_pitch_loop,diff_pitch_angle,gimbal_cmd_recv.diff_pitch * DEGREE_2_RAD);
|
|
|
|
|
float roll_angle_out = PIDCalculate(&diff_roll_loop,diff_roll_angle,gimbal_cmd_recv.diff_roll * DEGREE_2_RAD);
|
|
|
|
|
|
|
|
|
|
float diff_pitch_spd = (diff_r_spd + (-diff_l_spd)) / 2;
|
|
|
|
|
float diff_roll_spd = (diff_r_spd - (-diff_l_spd)) /2 * 18/52;
|
|
|
|
|
float pitch_out = PIDCalculate(&diff_pitch_spd_loop,diff_pitch_spd,pitch_angle_out);
|
|
|
|
|
float roll_out = PIDCalculate(&diff_roll_spd_loop,diff_roll_spd,roll_angle_out);
|
|
|
|
|
|
|
|
|
|
float r_speed_set = pitch_out + roll_out;
|
|
|
|
|
float l_speed_set = pitch_out - roll_out;
|
2024-04-25 23:12:31 +08:00
|
|
|
|
|
|
|
|
|
// @todo:现在已不再需要电机反馈,实际上可以始终使用IMU的姿态数据来作为云台的反馈,yaw电机的offset只是用来跟随底盘
|
|
|
|
|
// 根据控制模式进行电机反馈切换和过渡,视觉模式在robot_cmd模块就已经设置好,gimbal只看yaw_ref和pitch_ref
|
|
|
|
|
switch (gimbal_cmd_recv.gimbal_mode)
|
|
|
|
|
{
|
|
|
|
|
// 停止
|
|
|
|
|
case GIMBAL_ZERO_FORCE:
|
2024-05-07 14:06:47 +08:00
|
|
|
|
DMMotorStop(yaw_motor);
|
|
|
|
|
DMMotorStop(pitch_motor);
|
|
|
|
|
DMMotorStop(roll_motor);
|
|
|
|
|
DMMotorStop(diff_r_motor);
|
|
|
|
|
DMMotorStop(diff_l_motor);
|
|
|
|
|
|
2024-04-25 23:12:31 +08:00
|
|
|
|
break;
|
|
|
|
|
// 使用陀螺仪的反馈,底盘根据yaw电机的offset跟随云台或视觉模式采用
|
|
|
|
|
case GIMBAL_GYRO_MODE: // 后续只保留此模式
|
2024-05-07 14:06:47 +08:00
|
|
|
|
DMMotorEnable(yaw_motor);
|
|
|
|
|
DMMotorEnable(pitch_motor);
|
|
|
|
|
DMMotorEnable(roll_motor);
|
|
|
|
|
DMMotorSetRef(pitch_motor,gimbal_cmd_recv.pitch * DEGREE_2_RAD);
|
|
|
|
|
DMMotorSetRef(yaw_motor,gimbal_cmd_recv.yaw * DEGREE_2_RAD);
|
|
|
|
|
DMMotorSetRef(roll_motor,gimbal_cmd_recv.roll * DEGREE_2_RAD);
|
|
|
|
|
|
|
|
|
|
DMMotorEnable(diff_r_motor);
|
|
|
|
|
DMMotorEnable(diff_l_motor);
|
|
|
|
|
DMMotorSetRef(diff_r_motor,r_speed_set);
|
|
|
|
|
DMMotorSetRef(diff_l_motor,-l_speed_set);
|
2024-04-25 23:12:31 +08:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在合适的地方添加pitch重力补偿前馈力矩
|
|
|
|
|
// 根据IMU姿态/pitch电机角度反馈计算出当前配重下的重力矩
|
|
|
|
|
// ...
|
|
|
|
|
|
|
|
|
|
// 设置反馈数据,主要是imu和yaw的ecd
|
|
|
|
|
gimbal_feedback_data.gimbal_imu_data = *gimba_IMU_data;
|
|
|
|
|
gimbal_feedback_data.yaw_motor_single_round_angle = yaw_motor->measure.angle_single_round;
|
|
|
|
|
|
|
|
|
|
// 推送消息
|
|
|
|
|
PubPushMessage(gimbal_pub, (void *)&gimbal_feedback_data);
|
|
|
|
|
}
|