shooter/User/device/djiMotor.c
2025-03-26 20:15:44 +08:00

378 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
****************************(C) COPYRIGHT ZhouCc****************************
* @file djiMotor.c/h
* @brief 大疆电机接收发送程序
* @note
* @history
* Version Date Author Modification
* V1.0.0 2023.12.11 ZhouCc 完成
*
@verbatim
==============================================================================
==============================================================================
@endverbatim
****************************(C) COPYRIGHT ZhouCc****************************
*/
#include "djiMotor.h"
#include "can_it.h"
#include "can_init.h"
#if FREERTOS_DJI == 1
#include "TopDefine.h"
#include<cmsis_os2.h>
#include "FreeRTOS.h"
#include "odrive_can.h"
static CAN_TxHeaderTypeDef vesc_tx_message;
static uint8_t vesc_send_data[4];
#endif
//motor data read
#define get_motor_measure(ptr, data) \
{ \
(ptr)->last_ecd = (ptr)->ecd; \
(ptr)->ecd = (uint16_t)((data)[0] << 8 | (data)[1]); \
(ptr)->speed_rpm = (uint16_t)((data)[2] << 8 | (data)[3]); \
(ptr)->given_current = (uint16_t)((data)[4] << 8 | (data)[5]); \
(ptr)->temperate = (data)[6]; \
(ptr)->ecd - (ptr)->last_ecd > 4096 ? ((ptr)->round_cnt--) : ((ptr)->round_cnt=(ptr)->round_cnt); \
(ptr)->ecd - (ptr)->last_ecd < -4096 ? ((ptr)->round_cnt++) : ((ptr)->round_cnt=(ptr)->round_cnt); \
(ptr)->total_angle = (fp64)((ptr)->round_cnt * 8192 + (ptr)->ecd - (ptr)->offset_ecd ) * MOTOR_ECD_TO_ANGLE_3508; \
}//ptr指向电机测量数据结构体的指针data包含电机测量数据的数组.
/*(ptr)->real_angle = (ptr)->real_angle % 360; */
#define get_motor_offset(ptr, data) \
{ \
(ptr)->ecd = (uint16_t)((data)[0] << 8 | (data)[1]); \
(ptr)->offset_ecd = (ptr)->ecd; \
}
#define get_6020_motor_measure(ptr, data) \
{ \
(ptr)->last_ecd = (ptr)->ecd; \
(ptr)->ecd = (uint16_t)((data)[0] << 8 | (data)[1]); \
(ptr)->speed_rpm = (uint16_t)((data)[2] << 8 | (data)[3]); \
(ptr)->given_current = (uint16_t)((data)[4] << 8 | (data)[5]); \
(ptr)->temperate = (data)[6]; \
(ptr)->ecd - (ptr)->last_ecd > 4096 ? ((ptr)->round_cnt--) : ((ptr)->round_cnt=(ptr)->round_cnt); \
(ptr)->ecd - (ptr)->last_ecd < -4096 ? ((ptr)->round_cnt++) : ((ptr)->round_cnt=(ptr)->round_cnt); \
(ptr)->total_angle = (fp64)((ptr)->round_cnt * 8192 + (ptr)->ecd - (ptr)->offset_ecd ) * MOTOR_ECD_TO_ANGLE_6020; \
}
#define get_2006_motor_measure(ptr, data) \
{ \
(ptr)->last_ecd = (ptr)->ecd; \
(ptr)->ecd = (uint16_t)((data)[0] << 8 | (data)[1]); \
(ptr)->speed_rpm = (uint16_t)((data)[2] << 8 | (data)[3]); \
(ptr)->given_current = (uint16_t)((data)[4] << 8 | (data)[5]); \
(ptr)->temperate = (data)[6]; \
(ptr)->ecd - (ptr)->last_ecd > 4096 ? ((ptr)->round_cnt--) : ((ptr)->round_cnt=(ptr)->round_cnt); \
(ptr)->ecd - (ptr)->last_ecd < -4096 ? ((ptr)->round_cnt++) : ((ptr)->round_cnt=(ptr)->round_cnt); \
(ptr)->total_angle = (fp64)((ptr)->round_cnt * 8192 + (ptr)->ecd - (ptr)->offset_ecd ) * MOTOR_ECD_TO_ANGLE_2006; \
}
// 解析出初始编码器值
// #define get_5065motor_measure(ptr, data) \
// { \
// (ptr)->last_ecd = (ptr)->ecd; \
// (ptr)->ecd = (float)((data)[0] << 4 | (data)[1] <<3 |(data)[2] < 2 |(data)[3]); \
// (ptr)->speed_rpm = (float)((data)[4] << 4 | (data)[5] <<3 |(data)[6] < 2 |(data)[7]);; \
// }
/*(ptr)->real_angle = (ptr)->real_angle % 360; */
static void CAN_VescMotor_Decode_1(CAN_MotorFeedback_t *feedback,
const uint8_t *raw)
{
if (feedback == NULL || raw == NULL) return;
union
{
int x;
uint8_t data[4];
}speed;
speed.data[0]= raw[3];
speed.data[1]= raw[2];
speed.data[2]= raw[1];
speed.data[3]= raw[0];
feedback->rotor_speed = speed.x;
union
{
int16_t y;
uint8_t dat[2];
}current;
current.dat[0]= raw[5];
current.dat[1]= raw[4];
feedback->torque_current =(fp32)current.y/10;
}
#if DEBUG == 1
motor_measure_t motor_chassis[5];
CAN_MotorFeedback_t motor_6384;
#else
static motor_measure_t motor_chassis[5];
#endif
static CAN_TxHeaderTypeDef tx_meessage_1ff;
static uint8_t can_send_data_1ff[8];
static CAN_TxHeaderTypeDef tx_meessage_2ff;
static uint8_t can_send_data_2ff[8];
static CAN_TxHeaderTypeDef tx_message_200;
static uint8_t can_send_data_200[8];
CAN_RxHeaderTypeDef dji_rx_header;
uint8_t dji_rx_data[8];
/**
* @brief 数据处理函数
* @param[in] none
* @retval none
*/
void djiMotorEncode()
{
switch (dji_rx_header.StdId)
{
case 0x201:
case 0x202:
case 0x203:
case 0x204:
case 0x205:
case 0x206:
case 0x207:
{
static uint8_t i = 0;
//get motor id
i = dji_rx_header.StdId - 0x201;
if(motor_chassis[i].msg_cnt<=50)
{
motor_chassis[i].msg_cnt++;
get_motor_offset(&motor_chassis[i], dji_rx_data);
}else{
get_motor_measure(&motor_chassis[i], dji_rx_data);
}
break;
}
default:
{
break;
}
}
}
void vescMotorEncode()
{
switch (dji_rx_header.ExtId) {
case CAN_VESC5065_M1_MSG1:
// 存储消息到对应的电机结构体中
CAN_VescMotor_Decode_1(&motor_6384, dji_rx_data);
break;
default:
break;
}
}
#if FREERTOS_DJI == 0
/**
* @brief hal库CAN回调函数,接收电机数据
* @param[in] hcan:CAN句柄指针
* @retval none
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &dji_rx_header, dji_rx_data);
djiMotorEncode();
}
#else
static osEventFlagsId_t eventReceive;//事件标志
/**
* @brief 自定义大疆电机回调函数
* @param[in] none
* @retval none
*/
void Dji_Motor_CB()
{
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &dji_rx_header, dji_rx_data);
osEventFlagsSet(eventReceive, EVENT_CAN);
}
/**
* @brief 大疆电机初始化
* @param none
* @retval none
*/
void djiInit(void)
{
BSP_CAN_RegisterCallback(BSP_CAN_1, HAL_CAN_RX_FIFO0_MSG_PENDING_CB,
Dji_Motor_CB);
can_filter_init();
}
/**
* @brief 等待新数据
*/
uint32_t waitNewDji()
{
return osEventFlagsWait(
eventReceive, EVENT_CAN,osFlagsWaitAny, osWaitForever);
}
#endif
/**
* @brief 发送电机控制电流(0x205,0x206,0x207,0x208)
* @param[in] motor1: (0x205) 电机控制电流
* @param[in] motor2: (0x206) 电机控制电流
* @param[in] motor3: (0x207) 电机控制电流
* @param[in] motor4: (0x208) 电机控制电流
* @retval none
*/
extern void CAN_cmd_1FF(int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4,CAN_HandleTypeDef*hcan)
{
uint32_t send_mail_box;
tx_meessage_1ff.StdId = 0x1FF;
tx_meessage_1ff.IDE = CAN_ID_STD;
tx_meessage_1ff.RTR = CAN_RTR_DATA;
tx_meessage_1ff.DLC = 0x08;
can_send_data_1ff[0] = (motor1 >> 8);
can_send_data_1ff[1] = motor1;
can_send_data_1ff[2] = (motor2 >> 8);
can_send_data_1ff[3] = motor2;
can_send_data_1ff[4] = (motor3 >> 8);
can_send_data_1ff[5] = motor3;
can_send_data_1ff[6] = (motor4 >> 8);
can_send_data_1ff[7] = motor4;
HAL_CAN_AddTxMessage(hcan, &tx_meessage_1ff, can_send_data_1ff, &send_mail_box);
}
/**
* @brief 发送电机控制电流(0x201,0x202,0x203,0x204)
* @param[in] motor1: (0x201) 电机控制电流
* @param[in] motor2: (0x202) 电机控制电流
* @param[in] motor3: (0x203) 电机控制电流
* @param[in] motor4: (0x204) 电机控制电流
* @retval none
*/
void CAN_cmd_200(int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4,CAN_HandleTypeDef*hcan)
{
uint32_t send_mail_box;
tx_message_200.StdId = 0x200;
tx_message_200.IDE = CAN_ID_STD;
tx_message_200.RTR = CAN_RTR_DATA;
tx_message_200.DLC = 0x08;
can_send_data_200[0] = motor1 >> 8;
can_send_data_200[1] = motor1;
can_send_data_200[2] = motor2 >> 8;
can_send_data_200[3] = motor2;
can_send_data_200[4] = motor3 >> 8;
can_send_data_200[5] = motor3;
can_send_data_200[6] = motor4 >> 8;
can_send_data_200[7] = motor4;
HAL_CAN_AddTxMessage(hcan, &tx_message_200, can_send_data_200, &send_mail_box);
}
/**
* @brief 发送电机控制电流(0x205,0x206,0x207,0x208)
* @param[in] motor1: (0x209) 电机控制电流
* @param[in] motor2: (0x20A) 电机控制电流
* @param[in] motor3: (0x20B) 电机控制电流
* @retval none
*/
void CAN_cmd_2FF(int16_t motor1, int16_t motor2, int16_t motor3, CAN_HandleTypeDef*hcan)
{
uint32_t send_mail_box;
tx_meessage_2ff.StdId = 0x1FF;
tx_meessage_2ff.IDE = CAN_ID_STD;
tx_meessage_2ff.RTR = CAN_RTR_DATA;
tx_meessage_2ff.DLC = 0x08;
can_send_data_2ff[0] = (motor1 >> 8);
can_send_data_2ff[1] = motor1;
can_send_data_2ff[2] = (motor2 >> 8);
can_send_data_2ff[3] = motor2;
can_send_data_2ff[4] = (motor3 >> 8);
can_send_data_2ff[5] = motor3;
can_send_data_2ff[6] = (0 >> 8);
can_send_data_2ff[7] = 0;
HAL_CAN_AddTxMessage(hcan, &tx_meessage_2ff, can_send_data_2ff, &send_mail_box);
}
/**
* @brief 返回电机数据指针
* @param[in] i: 电机编号
* @retval 电机数据指针
*/
motor_measure_t *get_motor_point(uint8_t i)
{
return &motor_chassis[i];
}
/**
* @brief 限制vesc电机转速
* @param[in/out] rpm: vesce电机转速
* @retval none
*
* 如果rpm的绝对值大于wtrcfg_VESC_COMMAND_ERPM_MAX,
* 则将rpm的值设置为wtrcfg_VESC_COMMAND_ERPM_MAX或-wtrcfg_VESC_COMMAND_ERPM_MAX
*/
void assert_param_rpm(float *rpm){
if( fabsf(*rpm) > wtrcfg_VESC_COMMAND_ERPM_MAX )
*rpm = *rpm > 0 ? wtrcfg_VESC_COMMAND_ERPM_MAX : - wtrcfg_VESC_COMMAND_ERPM_MAX ;
}
/**
* @brief 使vesc电机进入转速模式
* @param[in] controller_id: vesc电机控制器id
* @param[in] RPM: 电机转速
* @retval RPM1000-50000之间的数
*/
void CAN_VESC_RPM(uint8_t controller_id, float RPM)
{
uint32_t id;
int32_t data;
uint32_t send_mail_box;
id = controller_id | ((uint32_t)CAN_PACKET_SET_RPM << 8);
assert_param_rpm(&RPM);
data = (int32_t)(RPM);
vesc_tx_message.ExtId = id;
vesc_tx_message.IDE = CAN_ID_EXT;
vesc_tx_message.RTR = CAN_RTR_DATA;
vesc_tx_message.DLC = 0x04;
vesc_send_data[0] = data >> 24 ;
vesc_send_data[1] = data >> 16 ;
vesc_send_data[2] = data >> 8 ;
vesc_send_data[3] = data ;
HAL_CAN_AddTxMessage(&hcan1, &vesc_tx_message, vesc_send_data, &send_mail_box);
}
/**
* @brief 使vesc电机进入制动模式
* @param[in] controller_id: vesc电机控制器id
* @retval none
*/
void CAN_VESC_HEAD(uint8_t controller_id)
{
uint32_t id;
uint32_t send_mail_box;
id = controller_id | ((uint32_t)CAN_PACKET_SET_CURRENT_BRAKE << 8);
vesc_tx_message.ExtId = id;
vesc_tx_message.IDE = CAN_ID_EXT;
vesc_tx_message.RTR = CAN_RTR_DATA;
vesc_tx_message.DLC = 0x04;
HAL_CAN_AddTxMessage(&hcan1, &vesc_tx_message, vesc_send_data, &send_mail_box);
}