增加了遥控器按键功能并修改所有函数和类型定义为标准格式

This commit is contained in:
NeoZng
2022-12-05 21:01:26 +08:00
parent 3947c48230
commit 9c9ea14bde
40 changed files with 352 additions and 251 deletions

View File

@@ -36,7 +36,9 @@
"*.tcc": "c",
"type_traits": "c",
"typeinfo": "c",
"general_def.h": "c"
"general_def.h": "c",
"super_cap.h": "c",
"motor_def.h": "c"
},
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
}

0
TODO.md Normal file
View File

View File

@@ -22,7 +22,6 @@
#include "arm_math.h"
/* 根据robot_def.h中的macro自动计算的参数 */
#define HALF_WHEEL_BASE (WHEEL_BASE / 2.0f)
#define HALF_TRACK_WIDTH (TRACK_WIDTH / 2.0f)
@@ -37,10 +36,10 @@ IMU_Data_t *Chassis_IMU_data;
#endif // CHASSIS_BOARD
static referee_info_t *referee_data; // 裁判系统的数据
// static SuperCAP* cap; 尚未增加超级电容
static dji_motor_instance *motor_lf; // left right forward back
static dji_motor_instance *motor_rf;
static dji_motor_instance *motor_lb;
static dji_motor_instance *motor_rb;
static DJIMotorInstance *motor_lf; // left right forward back
static DJIMotorInstance *motor_rf;
static DJIMotorInstance *motor_lb;
static DJIMotorInstance *motor_rb;
/* chassis 包含的信息交互模块和数据*/
static Publisher_t *chassis_pub;
@@ -170,8 +169,8 @@ static void MecanumCalculate()
{
vt_lf = -chassis_vx - chassis_vy - chassis_cmd_recv.wz * LF_CENTER;
vt_rf = -chassis_vx + chassis_vy - chassis_cmd_recv.wz * RF_CENTER;
vt_lb = chassis_vx + chassis_vy - chassis_cmd_recv.wz * LB_CENTER;
vt_rb = chassis_vx - chassis_vy - chassis_cmd_recv.wz * RB_CENTER;
vt_lb = chassis_vx + chassis_vy - chassis_cmd_recv.wz * LB_CENTER;
vt_rb = chassis_vx - chassis_vy - chassis_cmd_recv.wz * RB_CENTER;
}
/**
@@ -249,7 +248,7 @@ void ChassisTask()
// 获取裁判系统数据
// 我方颜色id小于7是红色,大于7是蓝色,注意这里发送的是对方的颜色, 0:blue , 1:red
chassis_feedback_data.enemy_color = referee_data->GameRobotStat.robot_id > 7 ? 1 : 0;
chassis_feedback_data.enemy_color = referee_data->GameRobotStat.robot_id > 7 ? 1 : 0;
// 当前只做了17mm的数据获取,后续根据robot_def中的宏切换双枪管和英雄42mm的情况
chassis_feedback_data.bullet_speed = referee_data->GameRobotStat.shooter_id1_17mm_speed_limit;
chassis_feedback_data.rest_heat = referee_data->PowerHeatData.shooter_heat0;

View File

@@ -15,11 +15,11 @@
#ifndef ONE_BOARD
#include "can_comm.h"
static CANCommInstance *chasiss_can_comm; // 双板通信
#endif // !ONE_BOARD
#endif // !ONE_BOARD
static RC_ctrl_t *remote_control_data; // 遥控器数据,初始化时返回
static Vision_Recv_s *vision_recv_data; // 视觉接收数据指针,初始化时返回
static Vision_Send_s vision_send_data; // 视觉发送数据
static RC_ctrl_t *remote_control_data; // 遥控器数据,初始化时返回
static Vision_Recv_s *vision_recv_data; // 视觉接收数据指针,初始化时返回
static Vision_Send_s vision_send_data; // 视觉发送数据
static Publisher_t *gimbal_cmd_pub;
static Gimbal_Ctrl_Cmd_s gimbal_cmd_send; // 传递给云台的控制信息
@@ -38,8 +38,8 @@ static Chassis_Upload_Data_s chassis_fetch_data; // 从底盘应用接收的反
void GimbalCMDInit()
{
remote_control_data = RC_init(&huart3); // 修改为对应串口,注意dbus协议串口需加反相器
vision_recv_data = VisionInit(&huart1); // 视觉通信串口
remote_control_data = RemoteControlInit(&huart3); // 修改为对应串口,注意dbus协议串口需加反相器
vision_recv_data = VisionInit(&huart1); // 视觉通信串口
gimbal_cmd_pub = PubRegister("gimbal_cmd", sizeof(Gimbal_Ctrl_Cmd_s));
gimbal_feed_sub = SubRegister("gimbal_feed", sizeof(Gimbal_Upload_Data_s));
@@ -107,11 +107,11 @@ void GimbalCMDTask()
MouseKeySetMode();
// 设置视觉发送数据,work_mode在前一部分设置
vision_send_data.bullet_speed=chassis_fetch_data.bullet_speed;
vision_send_data.enemy_color=chassis_fetch_data.enemy_color;
vision_send_data.pitch=gimbal_fetch_data.gimbal_imu_data.Pitch;
vision_send_data.yaw=gimbal_fetch_data.gimbal_imu_data.Yaw;
vision_send_data.roll=gimbal_fetch_data.gimbal_imu_data.Roll;
vision_send_data.bullet_speed = chassis_fetch_data.bullet_speed;
vision_send_data.enemy_color = chassis_fetch_data.enemy_color;
vision_send_data.pitch = gimbal_fetch_data.gimbal_imu_data.Pitch;
vision_send_data.yaw = gimbal_fetch_data.gimbal_imu_data.Yaw;
vision_send_data.roll = gimbal_fetch_data.gimbal_imu_data.Roll;
// 推送消息,双板通信,视觉通信等
// 应用所需的控制数据在remotecontrolsetmode和mousekeysetmode中完成设置

View File

@@ -5,10 +5,9 @@
#include "message_center.h"
#include "general_def.h"
static attitude_t *Gimbal_IMU_data; // 云台IMU数据
static dji_motor_instance *yaw_motor; // yaw电机
static dji_motor_instance *pitch_motor; // pitch电机
static attitude_t *Gimbal_IMU_data; // 云台IMU数据
static DJIMotorInstance *yaw_motor; // yaw电机
static DJIMotorInstance *pitch_motor; // pitch电机
static Publisher_t *gimbal_pub;
static Gimbal_Upload_Data_s gimbal_feedback_data; // 回传给gimbal_cmd的云台状态信息

View File

@@ -5,11 +5,10 @@
#include "bsp_dwt.h"
#include "general_def.h"
/* 对于双发射机构的机器人,将下面的数据封装成结构体即可,生成两份shoot应用实例 */
static dji_motor_instance *friction_l; // 左摩擦轮
static dji_motor_instance *friction_r; // 右摩擦轮
static dji_motor_instance *loader; // 拨盘电机
static DJIMotorInstance *friction_l; // 左摩擦轮
static DJIMotorInstance *friction_r; // 右摩擦轮
static DJIMotorInstance *loader; // 拨盘电机
// static servo_instance *lid; 需要增加弹舱盖
static Publisher_t *shoot_pub;

View File

@@ -2,24 +2,24 @@
#include "main.h"
extern TIM_HandleTypeDef htim4;
static uint8_t tmp_warning_level=0;
static uint8_t tmp_warning_level = 0;
void buzzer_init()
void BuzzerInit()
{
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
}
void buzzer_on(uint16_t psc, uint16_t pwm,uint8_t level)
void BuzzerOn(uint16_t psc, uint16_t pwm, uint8_t level)
{
if(level>tmp_warning_level)
if (level > tmp_warning_level)
{
tmp_warning_level=level;
tmp_warning_level = level;
__HAL_TIM_PRESCALER(&htim4, psc);
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwm);
}
}
void buzzer_off(void)
void BuzzerOff(void)
{
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 0);
tmp_warning_level=0;
tmp_warning_level = 0;
}

View File

@@ -3,8 +3,8 @@
#include <stdint-gcc.h>
void buzzer_init();
extern void buzzer_on(uint16_t psc, uint16_t pwm,uint8_t level);
extern void buzzer_off(void);
void BuzzerInit();
extern void BuzzerOn(uint16_t psc, uint16_t pwm, uint8_t level);
extern void BuzzerOff(void);
#endif

View File

@@ -5,7 +5,7 @@
/* can instance ptrs storage, used for recv callback */
// 在CAN产生接收中断会遍历数组,选出hcan和rxid与发生中断的实例相同的那个,调用其回调函数
static can_instance *instance[MX_REGISTER_DEVICE_CNT] = {NULL};
static CANInstance *instance[MX_REGISTER_DEVICE_CNT] = {NULL};
/* ----------------two static function called by CANRegister()-------------------- */
@@ -24,7 +24,7 @@ static can_instance *instance[MX_REGISTER_DEVICE_CNT] = {NULL};
*
* @param _instance can instance owned by specific module
*/
static void CANAddFilter(can_instance *_instance)
static void CANAddFilter(CANInstance *_instance)
{
CAN_FilterTypeDef can_filter_conf;
static uint8_t can1_filter_idx = 0, can2_filter_idx = 14;
@@ -60,15 +60,15 @@ static void CANServiceInit()
/* ----------------------- two extern callable function -----------------------*/
can_instance *CANRegister(can_instance_config_s *config)
CANInstance *CANRegister(CAN_Init_Config_s *config)
{
static uint8_t idx; // 全局CAN实例索引,每次有新的模块注册会自增
if (!idx)
{
CANServiceInit(); // 第一次注册,先进行硬件初始化
}
instance[idx] = (can_instance *)malloc(sizeof(can_instance)); // 分配空间
memset(instance[idx], 0, sizeof(can_instance));
instance[idx] = (CANInstance *)malloc(sizeof(CANInstance)); // 分配空间
memset(instance[idx], 0, sizeof(CANInstance));
// 进行发送报文的配置
instance[idx]->txconf.StdId = config->tx_id;
instance[idx]->txconf.IDE = CAN_ID_STD;
@@ -85,7 +85,7 @@ can_instance *CANRegister(can_instance_config_s *config)
}
/* TODO:目前似乎封装过度,应该添加一个指向tx_buff的指针,tx_buff不应该由CAN instance保存 */
void CANTransmit(can_instance *_instance)
void CANTransmit(CANInstance *_instance)
{
while (HAL_CAN_GetTxMailboxesFreeLevel(_instance->can_handle) == 0)
;
@@ -93,7 +93,7 @@ void CANTransmit(can_instance *_instance)
HAL_CAN_AddTxMessage(_instance->can_handle, &_instance->txconf, _instance->tx_buff, &_instance->tx_mailbox);
}
void CANSetDLC(can_instance *_instance, uint8_t length)
void CANSetDLC(CANInstance *_instance, uint8_t length)
{
if (length > 8) // 安全检查
while (1)

View File

@@ -23,7 +23,7 @@ typedef struct _
uint8_t rx_len; // 接收长度,可能为0-8
// 接收的回调函数,用于解析接收到的数据
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
} can_instance;
} CANInstance;
#pragma pack()
/* this structure is used for initialization */
@@ -32,8 +32,8 @@ typedef struct
CAN_HandleTypeDef *can_handle;
uint32_t tx_id;
uint32_t rx_id;
void (*can_module_callback)(can_instance *);
} can_instance_config_s;
void (*can_module_callback)(CANInstance *);
} CAN_Init_Config_s;
/**
* @brief 修改CAN发送报文的数据帧长度;注意最大长度为8,在没有进行修改的时候,默认长度为8
@@ -41,7 +41,7 @@ typedef struct
* @param _instance 要修改长度的can实例
* @param length 设定长度
*/
void CANSetDLC(can_instance *_instance, uint8_t length);
void CANSetDLC(CANInstance *_instance, uint8_t length);
/**
* @brief transmit mesg through CAN device,通过can实例发送消息
@@ -49,14 +49,14 @@ void CANSetDLC(can_instance *_instance, uint8_t length);
*
* @param _instance* can instance owned by module
*/
void CANTransmit(can_instance *_instance);
void CANTransmit(CANInstance *_instance);
/**
* @brief Register a module to CAN service,remember to call this before using a CAN device
* 注册(初始化)一个can实例,需要传入初始化配置的指针.
* @param config init config
* @return can_instance* can instance owned by module
* @return CANInstance* can instance owned by module
*/
can_instance *CANRegister(can_instance_config_s *config);
CANInstance *CANRegister(CAN_Init_Config_s *config);
#endif

View File

@@ -9,8 +9,8 @@
void BSPInit()
{
DWT_Init(168);
BSP_Log_Init();
LED_init();
BSPLogInit();
LEDInit();
IMUTempInit();
buzzer_init();
BuzzerInit();
}

View File

@@ -4,14 +4,14 @@
extern TIM_HandleTypeDef htim5;
static uint8_t tmp_output_level = 0;
void LED_init()
void LEDInit()
{
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3);
}
void aRGB_led_show(uint32_t aRGB)
void FlowRGBShow(uint32_t aRGB)
{
static uint8_t alpha;
static uint16_t red, green, blue;

View File

@@ -3,7 +3,7 @@
#include <stdint-gcc.h>
void LED_init();
extern void aRGB_led_show(uint32_t aRGB);
void LEDInit();
extern void FlowRGBShow(uint32_t aRGB);
#endif

View File

@@ -6,12 +6,12 @@
#define BUFFER_INDEX 0
void BSP_Log_Init()
void BSPLogInit()
{
SEGGER_RTT_Init();
}
int printf_log(const char *fmt, ...)
int PrintLog(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);

View File

@@ -1,9 +1,9 @@
#ifndef _BSP_LOG_H
#define _BSP_LOG_H
void BSP_Log_Init();
void BSPLogInit();
int printf_log(const char *fmt, ...);
int PrintLog(const char *fmt, ...);
void Float2Str(char *str, float va);

View File

@@ -7,7 +7,7 @@ void IMUTempInit()
HAL_TIM_PWM_Start(&htim10, TIM_CHANNEL_1);
}
void imu_pwm_set(uint16_t pwm)
void IMUPWMSet(uint16_t pwm)
{
__HAL_TIM_SetCompare(&htim10, TIM_CHANNEL_1, pwm);
}

View File

@@ -5,6 +5,6 @@
#include "tim.h"
void IMUTempInit();
extern void imu_pwm_set(uint16_t pwm);
extern void IMUPWMSet(uint16_t pwm);
#endif

View File

@@ -14,7 +14,7 @@
/* usart service instance, modules' info would be recoreded here using USARTRegister() */
/* usart服务实例,所有注册了usart的模块信息会被保存在这里 */
static usart_instance *instance[DEVICE_USART_CNT] = {NULL};
static USARTInstance *instance[DEVICE_USART_CNT] = {NULL};
/**
* @brief usart service will start automatically, after each module registered
@@ -22,7 +22,7 @@ static usart_instance *instance[DEVICE_USART_CNT] = {NULL};
*
* @param _instance instance owned by module,模块拥有的串口实例
*/
static void USARTServiceInit(usart_instance *_instance)
static void USARTServiceInit(USARTInstance *_instance)
{
HAL_UARTEx_ReceiveToIdle_DMA(_instance->usart_handle, _instance->recv_buff, _instance->recv_buff_size);
// 关闭dma half transfer中断防止两次进入HAL_UARTEx_RxEventCallback()
@@ -31,23 +31,23 @@ static void USARTServiceInit(usart_instance *_instance)
__HAL_DMA_DISABLE_IT(_instance->usart_handle->hdmarx, DMA_IT_HT);
}
usart_instance* USARTRegister(USART_Init_Config_s *init_config)
USARTInstance *USARTRegister(USART_Init_Config_s *init_config)
{
static uint8_t idx;
instance[idx]=(usart_instance*)malloc(sizeof(usart_instance));
memset(instance[idx],0,sizeof(usart_instance));
instance[idx] = (USARTInstance *)malloc(sizeof(USARTInstance));
memset(instance[idx], 0, sizeof(USARTInstance));
instance[idx]->module_callback=init_config->module_callback;
instance[idx]->recv_buff_size=init_config->recv_buff_size;
instance[idx]->usart_handle=init_config->usart_handle;
instance[idx]->module_callback = init_config->module_callback;
instance[idx]->recv_buff_size = init_config->recv_buff_size;
instance[idx]->usart_handle = init_config->usart_handle;
USARTServiceInit(instance[idx]);
return instance[idx++];
}
/* @todo 当前仅进行了形式上的封装,后续要进一步考虑是否将module的行为与bsp完全分离 */
void USARTSend(usart_instance *_instance, uint8_t *send_buf, uint16_t send_size)
void USARTSend(USARTInstance *_instance, uint8_t *send_buf, uint16_t send_size)
{
HAL_UART_Transmit_DMA(_instance->usart_handle, send_buf, send_size);
}
@@ -75,7 +75,7 @@ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
if (huart == instance[i]->usart_handle)
{
instance[i]->module_callback();
memset(instance[i]->recv_buff,0,Size); // 接收结束后清空buffer,对于变长数据是必要的
memset(instance[i]->recv_buff, 0, Size); // 接收结束后清空buffer,对于变长数据是必要的
HAL_UARTEx_ReceiveToIdle_DMA(instance[i]->usart_handle, instance[i]->recv_buff, instance[i]->recv_buff_size);
__HAL_DMA_DISABLE_IT(instance[i]->usart_handle->hdmarx, DMA_IT_HT);
break;

View File

@@ -10,7 +10,7 @@
/* application callback,which resolves specific protocol,解析协议的回调函数 */
typedef void (*usart_module_callback)();
/* usart_instance struct,each app would have one instance */
/* USARTInstance struct,each app would have one instance */
typedef struct
{
// 更新:弃用malloc方案,使用了固定大小的数组方便debug时查看
@@ -18,7 +18,7 @@ typedef struct
uint8_t recv_buff_size; // 模块接收一包数据的大小
UART_HandleTypeDef *usart_handle; // 实例对应的usart_handle
usart_module_callback module_callback; // 解析收到的数据的回调函数
} usart_instance;
} USARTInstance;
/* usart 初始化配置结构体 */
typedef struct
@@ -33,7 +33,7 @@ typedef struct
*
* @param init_config 传入串口初始化结构体
*/
usart_instance* USARTRegister(USART_Init_Config_s *init_config);
USARTInstance *USARTRegister(USART_Init_Config_s *init_config);
/**
* @todo 是否需要进一步封装发送buff和size,并创建一个串口任务以一定频率自动发送?
@@ -45,6 +45,6 @@ usart_instance* USARTRegister(USART_Init_Config_s *init_config);
* @param id specify which usart would be used
* @param send_size how many bytes to send
*/
void USARTSend(usart_instance *_instance, uint8_t *send_buf, uint16_t send_size);
void USARTSend(USARTInstance *_instance, uint8_t *send_buf, uint16_t send_size);
#endif

View File

@@ -12,14 +12,14 @@
#include <memory.h>
// PID优化环节函数声明
static void f_Trapezoid_Intergral(PID_t *pid); // 梯形积分
static void f_Integral_Limit(PID_t *pid); // 积分限幅
static void f_Derivative_On_Measurement(PID_t *pid); // 微分先行(仅使用反馈值而不计参考输入的微分)
static void f_Changing_Integration_Rate(PID_t *pid); // 变速积分(误差小时积分作用更强)
static void f_Output_Filter(PID_t *pid); // 输出滤波(平滑输出)
static void f_Derivative_Filter(PID_t *pid); // 微分滤波(采集时,滤除高频噪声)
static void f_Output_Limit(PID_t *pid); // 输出限幅
static void f_PID_ErrorHandle(PID_t *pid); // 堵转保护
static void f_Trapezoid_Intergral(PIDInstance *pid); // 梯形积分
static void f_Integral_Limit(PIDInstance *pid); // 积分限幅
static void f_Derivative_On_Measurement(PIDInstance *pid); // 微分先行(仅使用反馈值而不计参考输入的微分)
static void f_Changing_Integration_Rate(PIDInstance *pid); // 变速积分(误差小时积分作用更强)
static void f_Output_Filter(PIDInstance *pid); // 输出滤波(平滑输出)
static void f_Derivative_Filter(PIDInstance *pid); // 微分滤波(采集时,滤除高频噪声)
static void f_Output_Limit(PIDInstance *pid); // 输出限幅
static void f_PID_ErrorHandle(PIDInstance *pid); // 堵转保护
/**
* @brief 初始化PID,设置参数和启用的优化环节,将其他数据置零
@@ -27,12 +27,12 @@ static void f_PID_ErrorHandle(PID_t *pid); // 堵转保护
* @param pid PID实例
* @param config PID初始化设置
*/
void PID_Init(PID_t *pid, PID_Init_config_s *config)
void PID_Init(PIDInstance *pid, PID_Init_config_s *config)
{
// utilize the quality of struct that its memeory is continuous
memcpy(pid, config, sizeof(PID_Init_config_s));
// set rest of memory to 0
memset(&pid->Measure, 0, sizeof(PID_t) - sizeof(PID_Init_config_s));
memset(&pid->Measure, 0, sizeof(PIDInstance) - sizeof(PID_Init_config_s));
}
/**
@@ -42,7 +42,7 @@ void PID_Init(PID_t *pid, PID_Init_config_s *config)
* @param[in] 期望值
* @retval 返回空
*/
float PID_Calculate(PID_t *pid, float measure, float ref)
float PID_Calculate(PIDInstance *pid, float measure, float ref)
{
if (pid->Improve & ErrorHandle)
f_PID_ErrorHandle(pid);
@@ -93,13 +93,13 @@ float PID_Calculate(PID_t *pid, float measure, float ref)
return pid->Output;
}
static void f_Trapezoid_Intergral(PID_t *pid)
static void f_Trapezoid_Intergral(PIDInstance *pid)
{
pid->ITerm = pid->Ki * ((pid->Err + pid->Last_Err) / 2) * pid->dt;
}
static void f_Changing_Integration_Rate(PID_t *pid)
static void f_Changing_Integration_Rate(PIDInstance *pid)
{
if (pid->Err * pid->Iout > 0)
{
@@ -114,7 +114,7 @@ static void f_Changing_Integration_Rate(PID_t *pid)
}
}
static void f_Integral_Limit(PID_t *pid)
static void f_Integral_Limit(PIDInstance *pid)
{
static float temp_Output, temp_Iout;
temp_Iout = pid->Iout + pid->ITerm;
@@ -141,24 +141,24 @@ static void f_Integral_Limit(PID_t *pid)
}
}
static void f_Derivative_On_Measurement(PID_t *pid)
static void f_Derivative_On_Measurement(PIDInstance *pid)
{
pid->Dout = pid->Kd * (pid->Last_Measure - pid->Measure) / pid->dt;
}
static void f_Derivative_Filter(PID_t *pid)
static void f_Derivative_Filter(PIDInstance *pid)
{
pid->Dout = pid->Dout * pid->dt / (pid->Derivative_LPF_RC + pid->dt) +
pid->Last_Dout * pid->Derivative_LPF_RC / (pid->Derivative_LPF_RC + pid->dt);
}
static void f_Output_Filter(PID_t *pid)
static void f_Output_Filter(PIDInstance *pid)
{
pid->Output = pid->Output * pid->dt / (pid->Output_LPF_RC + pid->dt) +
pid->Last_Output * pid->Output_LPF_RC / (pid->Output_LPF_RC + pid->dt);
}
static void f_Output_Limit(PID_t *pid)
static void f_Output_Limit(PIDInstance *pid)
{
if (pid->Output > pid->MaxOut)
{
@@ -171,7 +171,7 @@ static void f_Output_Limit(PID_t *pid)
}
// PID ERRORHandle Function
static void f_PID_ErrorHandle(PID_t *pid)
static void f_PID_ErrorHandle(PIDInstance *pid)
{
/*Motor Blocked Handle*/
if (pid->Output < pid->MaxOut * 0.001f || fabsf(pid->Ref) < 0.0001f)

View File

@@ -93,7 +93,7 @@ typedef struct
float dt;
PID_ErrorHandler_t ERRORHandler;
} PID_t;
} PIDInstance;
/* 用于PID初始化的结构体*/
typedef struct
@@ -120,7 +120,7 @@ typedef struct
* @param pid PID实例指针
* @param config PID初始化配置
*/
void PID_Init(PID_t *pid, PID_Init_config_s *config);
void PID_Init(PIDInstance *pid, PID_Init_config_s *config);
/**
* @brief 计算PID输出
@@ -130,6 +130,6 @@ void PID_Init(PID_t *pid, PID_Init_config_s *config);
* @param ref 设定值
* @return float PID计算输出
*/
float PID_Calculate(PID_t *pid, float measure, float ref);
float PID_Calculate(PIDInstance *pid, float measure, float ref);
#endif

View File

@@ -24,7 +24,7 @@ static void CANCommResetRx(CANCommInstance *ins)
*
* @param _instance
*/
static void CANCommRxCallback(can_instance *_instance)
static void CANCommRxCallback(CANInstance *_instance)
{
for (size_t i = 0; i < idx; i++)
{
@@ -65,7 +65,7 @@ static void CANCommRxCallback(can_instance *_instance)
if (can_comm_instance[i]->raw_recvbuf[can_comm_instance[i]->recv_buf_len - 2] ==
crc_8(can_comm_instance[i]->raw_recvbuf + 2, can_comm_instance[i]->recv_data_len))
{ // 通过校验,复制数据到unpack_data中
memcpy(can_comm_instance[i]->unpacked_recv_data,can_comm_instance[i]->raw_recvbuf + 2, can_comm_instance[i]->recv_data_len);
memcpy(can_comm_instance[i]->unpacked_recv_data, can_comm_instance[i]->raw_recvbuf + 2, can_comm_instance[i]->recv_data_len);
can_comm_instance[i]->update_flag = 1; // 数据更新flag置为1
}
CANCommResetRx(can_comm_instance[i]);
@@ -91,7 +91,7 @@ CANCommInstance *CANCommInit(CANComm_Init_Config_s *comm_config)
can_comm_instance[idx]->raw_sendbuf[comm_config->send_data_len + CAN_COMM_OFFSET_BYTES - 1] = CAN_COMM_TAIL;
comm_config->can_config.can_module_callback = CANCommRxCallback;
can_comm_instance[idx]->can_ins=CANRegister(&comm_config->can_config);
can_comm_instance[idx]->can_ins = CANRegister(&comm_config->can_config);
return can_comm_instance[idx++];
}
@@ -104,10 +104,10 @@ void CANCommSend(CANCommInstance *instance, uint8_t *data)
instance->raw_sendbuf[2 + instance->send_data_len] = crc8;
for (size_t i = 0; i < instance->send_buf_len; i += 8)
{ // 如果是最后一包,send len将会小于8,要修改CAN的txconf中的DLC位,调用bsp_can提供的接口即可
{ // 如果是最后一包,send len将会小于8,要修改CAN的txconf中的DLC位,调用bsp_can提供的接口即可
send_len = instance->send_buf_len - i >= 8 ? 8 : instance->send_buf_len - i;
CANSetDLC(instance->can_ins, send_len);
memcpy(instance->can_ins->tx_buff, instance->raw_sendbuf+i, send_len);
memcpy(instance->can_ins->tx_buff, instance->raw_sendbuf + i, send_len);
CANTransmit(instance->can_ins);
}
}

View File

@@ -24,7 +24,7 @@
/* CAN comm 结构体, 拥有CAN comm的app应该包含一个CAN comm指针 */
typedef struct
{
can_instance* can_ins;
CANInstance *can_ins;
/* 发送部分 */
uint8_t send_data_len;
uint8_t send_buf_len;
@@ -44,7 +44,7 @@ typedef struct
/* CAN comm 初始化结构体 */
typedef struct
{
can_instance_config_s can_config;
CAN_Init_Config_s can_config;
uint8_t send_data_len;
uint8_t recv_data_len;
} CANComm_Init_Config_s;
@@ -55,7 +55,7 @@ typedef struct
* @param config
* @return CANCommInstance*
*/
CANCommInstance *CANCommInit(CANComm_Init_Config_s* comm_config);
CANCommInstance *CANCommInit(CANComm_Init_Config_s *comm_config);
/**
* @brief 发送数据

View File

@@ -20,7 +20,7 @@
static INS_t INS;
static IMU_Param_t IMU_Param;
static PID_t TempCtrl = {0};
static PIDInstance TempCtrl = {0};
const float xb[3] = {1, 0, 0};
const float yb[3] = {0, 1, 0};
@@ -33,7 +33,6 @@ static float RefTemp = 40; // 恒温设定温度
static void IMU_Param_Correction(IMU_Param_t *param, float gyro[3], float accel[3]);
/**
* @brief 温度控制
*
@@ -41,12 +40,13 @@ static void IMU_Param_Correction(IMU_Param_t *param, float gyro[3], float accel[
static void IMU_Temperature_Ctrl(void)
{
PID_Calculate(&TempCtrl, BMI088.Temperature, RefTemp);
imu_pwm_set(float_constrain(float_rounding(TempCtrl.Output), 0, UINT32_MAX));
IMUPWMSet(float_constrain(float_rounding(TempCtrl.Output), 0, UINT32_MAX));
}
attitude_t* INS_Init(void)
attitude_t *INS_Init(void)
{
while (BMI088Init(&hspi1, 1) != BMI088_NO_ERROR);
while (BMI088Init(&hspi1, 1) != BMI088_NO_ERROR)
;
IMU_Param.scale[X] = 1;
IMU_Param.scale[Y] = 1;
IMU_Param.scale[Z] = 1;

View File

@@ -53,7 +53,7 @@ void led_RGB_flow_task()
blue += delta_blue;
aRGB = ((uint32_t)(alpha)) << 24 | ((uint32_t)(red)) << 16 | ((uint32_t)(green)) << 8 | ((uint32_t)(blue)) << 0;
aRGB_led_show(aRGB);
FlowRGBShow(aRGB);
}
}
}

View File

@@ -18,7 +18,7 @@ static Vision_Recv_s recv_data;
// @todo:由于后续需要进行IMU-Cam的硬件触发采集控制,因此可能需要将发送设置为定时任务,或由IMU采集完成产生的中断唤醒的任务,
// 使得时间戳对齐. 因此,在send_data中设定其他的标志位数据,让ins_task填充姿态值.
// static Vision_Send_s send_data;
static usart_instance *vision_usart_instance;
static USARTInstance *vision_usart_instance;
/**
* @brief 接收解包回调函数,将在bsp_usart.c中被usart rx callback调用
@@ -28,7 +28,7 @@ static usart_instance *vision_usart_instance;
static void DecodeVision()
{
static uint16_t flag_register;
get_protocol_info(vision_usart_instance->recv_buff, &flag_register, (uint8_t*)&recv_data.pitch);
get_protocol_info(vision_usart_instance->recv_buff, &flag_register, (uint8_t *)&recv_data.pitch);
// TODO: code to resolve flag_register;
}

View File

@@ -17,7 +17,7 @@ static float uint_to_float(int x_int, float x_min, float x_max, int bits)
return ((float)x_int) * span / ((float)((1 << bits) - 1)) + offset;
}
static void DecodeJoint(can_instance *motor_instance)
static void DecodeJoint(CANInstance *motor_instance)
{
uint16_t tmp;
for (size_t i = 0; i < HT_MOTOR_CNT; i++)
@@ -36,11 +36,11 @@ static void DecodeJoint(can_instance *motor_instance)
}
}
joint_instance *HTMotorInit(can_instance_config_s config)
joint_instance *HTMotorInit(CAN_Init_Config_s config)
{
static uint8_t idx;
joint_motor_info[idx] = (joint_instance *)malloc(sizeof(joint_instance));
joint_motor_info[idx]->motor_can_instace =CANRegister(&config);
joint_motor_info[idx]->motor_can_instace = CANRegister(&config);
return joint_motor_info[idx++];
}

View File

@@ -22,8 +22,8 @@ typedef struct // HT04
float speed_rpm;
float given_current;
PID_t pid;
can_instance *motor_can_instace;
PIDInstance pid;
CANInstance *motor_can_instace;
} joint_instance;
typedef enum
@@ -33,7 +33,7 @@ typedef enum
CMD_ZERO_POSITION = 0xfe
} joint_mode;
joint_instance *HTMotorInit(can_instance_config_s config);
joint_instance *HTMotorInit(CAN_Init_Config_s config);
void JointControl(joint_instance *_instance, float current);

View File

@@ -2,7 +2,7 @@
static driven_instance *driven_motor_info[LK_MOTOR_CNT];
static void DecodeDriven(can_instance *_instance)
static void DecodeDriven(CANInstance *_instance)
{
for (size_t i = 0; i < LK_MOTOR_CNT; i++)
{
@@ -18,12 +18,12 @@ static void DecodeDriven(can_instance *_instance)
}
}
driven_instance *LKMotroInit(can_instance_config_s config)
driven_instance *LKMotroInit(CAN_Init_Config_s config)
{
static uint8_t idx;
driven_motor_info[idx] = (driven_instance *)malloc(sizeof(driven_instance));
config.can_module_callback = DecodeDriven;
driven_motor_info[idx]->motor_can_instance=CANRegister(&config);
driven_motor_info[idx]->motor_can_instance = CANRegister(&config);
return driven_motor_info[idx++];
}

View File

@@ -18,8 +18,8 @@ typedef struct // 9025
int16_t given_current;
uint8_t temperate;
PID_t *pid;
can_instance *motor_can_instance;
PIDInstance *pid;
CANInstance *motor_can_instance;
} driven_instance;
@@ -28,7 +28,7 @@ typedef enum
unused = 0,
} driven_mode;
driven_instance *LKMotroInit(can_instance_config_s config);
driven_instance *LKMotroInit(CAN_Init_Config_s config);
void DrivenControl(int16_t motor1_current, int16_t motor2_current);

View File

@@ -4,7 +4,7 @@
static uint8_t idx = 0; // register idx,是该文件的全局电机索引,在注册时使用
/* DJI电机的实例,此处仅保存指针,内存的分配将通过电机实例初始化时通过malloc()进行 */
static dji_motor_instance *dji_motor_info[DJI_MOTOR_CNT] = {NULL};
static DJIMotorInstance *dji_motor_info[DJI_MOTOR_CNT] = {NULL};
/**
* @brief 由于DJI电机发送以四个一组的形式进行,故对其进行特殊处理,用6个(2can*3group)can_instance专门负责发送
@@ -13,7 +13,7 @@ static dji_motor_instance *dji_motor_info[DJI_MOTOR_CNT] = {NULL};
* can1: [0]:0x1FF,[1]:0x200,[2]:0x2FF
* can2: [0]:0x1FF,[1]:0x200,[2]:0x2FF
*/
static can_instance sender_assignment[6] =
static CANInstance sender_assignment[6] =
{
[0] = {.can_handle = &hcan1, .txconf.StdId = 0x1ff, .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}},
@@ -46,7 +46,7 @@ static void IDcrash_Handler(uint8_t conflict_motor_idx, uint8_t temp_motor_idx)
*
* @param config
*/
static void MotorSenderGrouping(can_instance_config_s *config)
static void MotorSenderGrouping(CAN_Init_Config_s *config)
{
uint8_t motor_id = config->tx_id - 1; // 下标从零开始,先减一方便赋值
uint8_t motor_send_num;
@@ -116,11 +116,11 @@ static void MotorSenderGrouping(can_instance_config_s *config)
*
* @param _instance 收到数据的instance,通过遍历与所有电机进行对比以选择正确的实例
*/
static void DecodeDJIMotor(can_instance *_instance)
static void DecodeDJIMotor(CANInstance *_instance)
{
// 由于需要多次变址访存,直接将buff和measure地址保存在寄存器里避免多次存取
static uint8_t *rxbuff;
static dji_motor_measure *measure;
static DJI_Motor_Measure_s *measure;
for (size_t i = 0; i < DJI_MOTOR_CNT; i++)
{
@@ -151,10 +151,10 @@ static void DecodeDJIMotor(can_instance *_instance)
}
// 电机初始化,返回一个电机实例
dji_motor_instance *DJIMotorInit(Motor_Init_Config_s *config)
DJIMotorInstance *DJIMotorInit(Motor_Init_Config_s *config)
{
dji_motor_info[idx] = (dji_motor_instance *)malloc(sizeof(dji_motor_instance));
memset(dji_motor_info[idx], 0, sizeof(dji_motor_instance));
dji_motor_info[idx] = (DJIMotorInstance *)malloc(sizeof(DJIMotorInstance));
memset(dji_motor_info[idx], 0, sizeof(DJIMotorInstance));
// motor basic setting
dji_motor_info[idx]->motor_type = config->motor_type;
@@ -177,7 +177,7 @@ dji_motor_instance *DJIMotorInit(Motor_Init_Config_s *config)
return dji_motor_info[idx++];
}
void DJIMotorChangeFeed(dji_motor_instance *motor, Closeloop_Type_e loop, Feedback_Source_e type)
void DJIMotorChangeFeed(DJIMotorInstance *motor, Closeloop_Type_e loop, Feedback_Source_e type)
{
if (loop == ANGLE_LOOP)
{
@@ -189,23 +189,23 @@ void DJIMotorChangeFeed(dji_motor_instance *motor, Closeloop_Type_e loop, Feedba
}
}
void DJIMotorStop(dji_motor_instance *motor)
void DJIMotorStop(DJIMotorInstance *motor)
{
motor->stop_flag = MOTOR_STOP;
}
void DJIMotorEnable(dji_motor_instance *motor)
void DJIMotorEnable(DJIMotorInstance *motor)
{
motor->stop_flag = MOTOR_ENALBED;
}
void DJIMotorOuterLoop(dji_motor_instance *motor, Closeloop_Type_e outer_loop)
void DJIMotorOuterLoop(DJIMotorInstance *motor, Closeloop_Type_e outer_loop)
{
motor->motor_settings.outer_loop_type = outer_loop;
}
// 设置参考值
void DJIMotorSetRef(dji_motor_instance *motor, float ref)
void DJIMotorSetRef(DJIMotorInstance *motor, float ref)
{
motor->motor_controller.pid_ref = ref;
}
@@ -217,10 +217,10 @@ void DJIMotorControl()
// 同样可以提高可读性
static uint8_t group, num;
static int16_t set;
static dji_motor_instance *motor;
static DJIMotorInstance *motor;
static Motor_Control_Setting_s *motor_setting;
static Motor_Controller_s *motor_controller;
static dji_motor_measure *motor_measure;
static DJI_Motor_Measure_s *motor_measure;
static float pid_measure;
// 遍历所有电机实例,进行串级PID的计算并设置发送报文的值
for (size_t i = 0; i < DJI_MOTOR_CNT; i++)

View File

@@ -24,8 +24,7 @@
/* 滤波系数设置为1的时候即关闭滤波 */
#define SPEED_SMOOTH_COEF 0.9f // better to be greater than 0.85
#define CURRENT_SMOOTH_COEF 0.98f // this coef *must* be greater than 0.95
#define ECD_ANGLE_COEF 0.043945f // 360/8192,将编码器值转化为角度制
#define ECD_ANGLE_COEF 0.043945f // 360/8192,将编码器值转化为角度制
/* DJI电机CAN反馈信息*/
typedef struct
@@ -38,7 +37,7 @@ typedef struct
uint8_t temperate; // 温度 Celsius
int16_t total_round; // 总圈数,注意方向
int32_t total_angle; // 总角度,注意方向
} dji_motor_measure;
} DJI_Motor_Measure_s;
/**
* @brief DJI intelligent motor typedef
@@ -47,7 +46,7 @@ typedef struct
typedef struct
{
/* motor measurement recv from CAN feedback */
dji_motor_measure motor_measure;
DJI_Motor_Measure_s motor_measure;
/* basic config of a motor*/
Motor_Control_Setting_s motor_settings;
@@ -56,7 +55,7 @@ typedef struct
Motor_Controller_s motor_controller;
/* the CAN instance own by motor instance*/
can_instance *motor_can_instance;
CANInstance *motor_can_instance;
/* sender assigment*/
uint8_t sender_group;
@@ -65,7 +64,7 @@ typedef struct
Motor_Type_e motor_type; // 电机类型
Motor_Working_Type_e stop_flag; // 启停标志
} dji_motor_instance;
} DJIMotorInstance;
/**
* @brief 调用此函数注册一个DJI智能电机,需要传递较多的初始化参数,请在application初始化的时候调用此函数
@@ -81,9 +80,9 @@ typedef struct
*
* @param config 电机初始化结构体,包含了电机控制设置,电机PID参数设置,电机类型以及电机挂载的CAN设置
*
* @return dji_motor_instance*
* @return DJIMotorInstance*
*/
dji_motor_instance *DJIMotorInit(Motor_Init_Config_s *config);
DJIMotorInstance *DJIMotorInit(Motor_Init_Config_s *config);
/**
* @brief 被application层的应用调用,给电机设定参考值.
@@ -92,7 +91,7 @@ dji_motor_instance *DJIMotorInit(Motor_Init_Config_s *config);
* @param motor 要设置的电机
* @param ref 设定参考值
*/
void DJIMotorSetRef(dji_motor_instance *motor, float ref);
void DJIMotorSetRef(DJIMotorInstance *motor, float ref);
/**
* @brief 切换反馈的目标来源,如将角速度和角度的来源换为IMU(小陀螺模式常用)
@@ -101,7 +100,7 @@ void DJIMotorSetRef(dji_motor_instance *motor, float ref);
* @param loop 要切换反馈数据来源的控制闭环
* @param type 目标反馈模式
*/
void DJIMotorChangeFeed(dji_motor_instance *motor, Closeloop_Type_e loop, Feedback_Source_e type);
void DJIMotorChangeFeed(DJIMotorInstance *motor, Closeloop_Type_e loop, Feedback_Source_e type);
/**
* @brief 该函数被motor_task调用运行在rtos上,motor_stask内通过osDelay()确定控制频率
@@ -113,14 +112,14 @@ void DJIMotorControl();
* @brief 停止电机,注意不是将设定值设为零,而是直接给电机发送的电流值置零
*
*/
void DJIMotorStop(dji_motor_instance *motor);
void DJIMotorStop(DJIMotorInstance *motor);
/**
* @brief 启动电机,此时电机会响应设定值
* 初始化时不需要此函数,因为stop_flag的默认值为0
*
*/
void DJIMotorEnable(dji_motor_instance *motor);
void DJIMotorEnable(DJIMotorInstance *motor);
/**
* @brief 修改电机闭环目标(外层闭环)
@@ -128,6 +127,6 @@ void DJIMotorEnable(dji_motor_instance *motor);
* @param motor 要修改的电机实例指针
* @param outer_loop 外层闭环类型
*/
void DJIMotorOuterLoop(dji_motor_instance *motor, Closeloop_Type_e outer_loop);
void DJIMotorOuterLoop(DJIMotorInstance *motor, Closeloop_Type_e outer_loop);
#endif // !DJI_MOTOR_H

View File

@@ -75,9 +75,9 @@ typedef struct
// float *speed_foward_ptr;
// float *current_foward_ptr;
PID_t current_PID;
PID_t speed_PID;
PID_t angle_PID;
PIDInstance current_PID;
PIDInstance speed_PID;
PIDInstance angle_PID;
float pid_ref; // 将会作为每个环的输入和输出顺次通过串级闭环
} Motor_Controller_s;
@@ -114,7 +114,7 @@ typedef struct
Motor_Controller_Init_s controller_param_init_config;
Motor_Control_Setting_s controller_setting_init_config;
Motor_Type_e motor_type;
can_instance_config_s can_init_config;
CAN_Init_Config_s can_init_config;
} Motor_Init_Config_s;
#endif // !MOTOR_DEF_H

View File

@@ -7,26 +7,26 @@
// 参考深圳大学 Infantry_X-master
#define RE_RX_BUFFER_SIZE 200
// static usart_instance referee_usart_instance;
static usart_instance* referee_usart_instance;
// static USARTInstance referee_usart_instance;
static USARTInstance *referee_usart_instance;
/**************裁判系统数据******************/
static referee_info_t referee_info;
static uint8_t Judge_Self_ID; // 当前机器人的ID
static uint8_t Judge_Self_ID; // 当前机器人的ID
static uint16_t Judge_SelfClient_ID; // 发送者机器人对应的客户端ID
static void ReceiveCallback()
static void RCRxCallback()
{
JudgeReadData(referee_usart_instance->recv_buff);
}
referee_info_t* RefereeInit(UART_HandleTypeDef *referee_usart_handle)
referee_info_t *RefereeInit(UART_HandleTypeDef *referee_usart_handle)
{
USART_Init_Config_s conf;
conf.module_callback = ReceiveCallback;
conf.module_callback = RCRxCallback;
conf.usart_handle = referee_usart_handle;
conf.recv_buff_size = RE_RX_BUFFER_SIZE;
referee_usart_instance=USARTRegister(&conf);
referee_usart_instance = USARTRegister(&conf);
return &referee_info;
}

View File

@@ -338,6 +338,7 @@ typedef struct
ext_SendClientData_t ShowData; // 客户端信息
ext_CommunatianData_t CommuData; // 队友通信信息
} referee_info_t;
#pragma pack()

View File

@@ -0,0 +1,70 @@
remote_control
<p align='right'>neozng1@hnu.edu.cn</p>
```
/*************************发射机DT7***************************
* *
* ----------------------------------------------------- *
* | (上-1) (上-1) | *
* |SW_L|(中-3) SW_R|(中-3) | *
* | (下-2) (下-2) | *
* | | *
* | | ^ | | ^ | | *
* | | 3 |左摇杆 右摇杆| 1 | | *
* | --- --- --- --- | *
* |< 2> < 0>| *
* | --- --- --- --- | *
* | | | | | | *
* | | | | | | *
* | | *
* ----------------------------------------------------- *
* *
**************************遥控器信息**************************
*域 通道0 通道1 通道2 通道3 S1 S2 *
*偏移 0 11 22 33 44 46 *
*长度(bit) 11 11 11 11 2 2 *
*符号位 无 无 无 无 无 无 *
*范围 ***********最大值1684********* *最大值3* *
* * 中间值1024 * *最小值1* *
* ***********最小值364********** *
*功能 1:上 1:上 *
* 2:下 2:下 *
* 3:中 3:中 *
* *
***************************鼠标信息***************************
*域 鼠标x轴 鼠标y轴 鼠标z轴 鼠标左键 鼠标右键*
*偏移 48 64 80 86 94 *
*长度 16 16 16 8 8 *
*符号位 有 有 有 无 无 *
*范围 ******最大值32767***** ***最大值1*** *
* * 最小值-32768 * ***最小值0*** *
* ******静止值0********* *
*功能 ***鼠标在XYZ轴的移动速度*** *鼠标左右键是否按下*
* * 负值表示往左移动 * * 0:没按下 *
* ***正值表示往右移动******** *****1:按下*********
* *
* *
***************************键盘信息***************************
*域 按键 *
*偏移 102 *
*长度 16 *
*符号位 无 *
*范围 位值标识 *
*功能 每个按键对应一个bit *
* Bit 0:W键 *
* Bit 1:S键 *
* Bit 2:A键 *
* Bit 3:D键 *
* Bit 4:Shift键 *
* Bit 5:Ctrl键 *
* Bit 6:Q键 *
* Bit 7:E键 *
* Bit 8:R键 *
* Bit 9:F键 *
* Bit10:G键 *
* Bit11:Z键 *
* Bit12:X键 *
* Bit13:C键 *
* Bit14:V键 *
* Bit15:B键 *
**************************************************************/
```

View File

@@ -1,13 +1,13 @@
#include "remote_control.h"
#include "string.h"
#include "bsp_usart.h"
#include "memory.h"
#define REMOTE_CONTROL_FRAME_SIZE 18u // 遥控器接收的buffer大小
// 遥控器数据
static RC_ctrl_t rc_ctrl;
static RC_ctrl_t rc_ctrl[2]; //[0]:当前数据,[1]:上一次的数据.用于按键判断
// 遥控器拥有的串口实例
static usart_instance* rc_usart_instance;
static USARTInstance *rc_usart_instance;
/**
* @brief remote control protocol resolution
@@ -15,33 +15,50 @@ static usart_instance* rc_usart_instance;
* @param[out] rc_ctrl: remote control data struct point
* @retval none
*/
static void sbus_to_rc(volatile const uint8_t *sbus_buf, RC_ctrl_t *rc_ctrl)
static void sbus_to_rc(volatile const uint8_t *sbus_buf)
{
if (sbus_buf == NULL || rc_ctrl == NULL)
{
return;
}
rc_ctrl->rc.ch[0] = (sbus_buf[0] | (sbus_buf[1] << 8)) & 0x07ff; //!< Channel 0
rc_ctrl->rc.ch[1] = ((sbus_buf[1] >> 3) | (sbus_buf[2] << 5)) & 0x07ff; //!< Channel 1
rc_ctrl->rc.ch[2] = ((sbus_buf[2] >> 6) | (sbus_buf[3] << 2) | //!< Channel 2
(sbus_buf[4] << 10)) &
0x07ff;
rc_ctrl->rc.ch[3] = ((sbus_buf[4] >> 1) | (sbus_buf[5] << 7)) & 0x07ff; //!< Channel 3
rc_ctrl->rc.s[0] = ((sbus_buf[5] >> 4) & 0x0003); //!< Switch left
rc_ctrl->rc.s[1] = ((sbus_buf[5] >> 4) & 0x000C) >> 2; //!< Switch right
rc_ctrl->mouse.x = sbus_buf[6] | (sbus_buf[7] << 8); //!< Mouse X axis
rc_ctrl->mouse.y = sbus_buf[8] | (sbus_buf[9] << 8); //!< Mouse Y axis
rc_ctrl->mouse.z = sbus_buf[10] | (sbus_buf[11] << 8); //!< Mouse Z axis
rc_ctrl->mouse.press_l = sbus_buf[12]; //!< Mouse Left Is Press ?
rc_ctrl->mouse.press_r = sbus_buf[13]; //!< Mouse Right Is Press ?
rc_ctrl->key.v = sbus_buf[14] | (sbus_buf[15] << 8); //!< KeyBoard value
rc_ctrl->rc.ch[4] = sbus_buf[16] | (sbus_buf[17] << 8); // NULL
memcpy(&rc_ctrl[1], &rc_ctrl[0], sizeof(RC_ctrl_t)); // 保存上一次的数据
// 摇杆
rc_ctrl[0].joy_stick.ch[0] = (sbus_buf[0] | (sbus_buf[1] << 8)) & 0x07ff; //!< Channel 0
rc_ctrl[0].joy_stick.ch[1] = ((sbus_buf[1] >> 3) | (sbus_buf[2] << 5)) & 0x07ff; //!< Channel 1
rc_ctrl[0].joy_stick.ch[2] = ((sbus_buf[2] >> 6) | (sbus_buf[3] << 2) | (sbus_buf[4] << 10)) & 0x07ff; //!< Channel 2
rc_ctrl[0].joy_stick.ch[3] = ((sbus_buf[4] >> 1) | (sbus_buf[5] << 7)) & 0x07ff; //!< Channel 3
rc_ctrl[0].joy_stick.ch[4] = sbus_buf[16] | (sbus_buf[17] << 8); // 拨轮
// 开关,0左1右
rc_ctrl[0].joy_stick.s[0] = ((sbus_buf[5] >> 4) & 0x0003); //!< Switch left
rc_ctrl[0].joy_stick.s[1] = ((sbus_buf[5] >> 4) & 0x000C) >> 2; //!< Switch right
rc_ctrl->rc.ch[0] -= RC_CH_VALUE_OFFSET;
rc_ctrl->rc.ch[1] -= RC_CH_VALUE_OFFSET;
rc_ctrl->rc.ch[2] -= RC_CH_VALUE_OFFSET;
rc_ctrl->rc.ch[3] -= RC_CH_VALUE_OFFSET;
rc_ctrl->rc.ch[4] -= RC_CH_VALUE_OFFSET;
// 鼠标解析
rc_ctrl[0].mouse.x = sbus_buf[6] | (sbus_buf[7] << 8); //!< Mouse X axis
rc_ctrl[0].mouse.y = sbus_buf[8] | (sbus_buf[9] << 8); //!< Mouse Y axis
rc_ctrl[0].mouse.z = sbus_buf[10] | (sbus_buf[11] << 8); //!< Mouse Z axis
rc_ctrl[0].mouse.press_l = sbus_buf[12]; //!< Mouse Left Is Press ?
rc_ctrl[0].mouse.press_r = sbus_buf[13]; //!< Mouse Right Is Press ?
// 按键值,每个键1bit,key_temp共16位;按键顺序在remote_control.h的宏定义中可见
rc_ctrl[0].key_temp = sbus_buf[14] | (sbus_buf[15] << 8); //!< KeyBoard value
// @todo 似乎可以直接用位域操作进行,把key_temp通过强制类型转换变成key类型? 方案见remote_control.md
// 按键值解算,利用宏+循环减少代码长度
for (uint16_t i = 0x0001, j = 0; i < 0x8001; i *= 2, j++) // 依次查看每一个键
{
// 如果键按下,对应键的key press状态置1,否则为0
rc_ctrl[0].key[KEY_PRESS][j] = rc_ctrl[0].key_temp & i;
// 如果当前按下且上一次没按下,切换按键状态.一些工作要通过按键状态而不是按键是否按下来确定(实际上是大部分)
rc_ctrl[0].key[KEY_STATE][j] = rc_ctrl[0].key[KEY_PRESS][j] && !rc_ctrl[1].key[KEY_PRESS][j];
// 检查是否有组合键按下
if (rc_ctrl[0].key_temp & 0x0001u << Key_Shift) // 按下ctrl
rc_ctrl[0].key[KEY_PRESS_WITH_SHIFT][j] = rc_ctrl[0].key_temp & i;
if (rc_ctrl[0].key_temp & 0x0001u << Key_Ctrl) // 按下shift
rc_ctrl[0].key[KEY_PRESS_WITH_CTRL][j] = rc_ctrl[0].key_temp & i;
}
// 减去偏置值
rc_ctrl[0].joy_stick.ch[0] -= RC_CH_VALUE_OFFSET;
rc_ctrl[0].joy_stick.ch[1] -= RC_CH_VALUE_OFFSET;
rc_ctrl[0].joy_stick.ch[2] -= RC_CH_VALUE_OFFSET;
rc_ctrl[0].joy_stick.ch[3] -= RC_CH_VALUE_OFFSET;
rc_ctrl[0].joy_stick.ch[4] -= RC_CH_VALUE_OFFSET;
}
/**
@@ -50,15 +67,15 @@ static void sbus_to_rc(volatile const uint8_t *sbus_buf, RC_ctrl_t *rc_ctrl)
* 对sbus_to_rc的简单封装
*
*/
static void ReceiveCallback()
static void RCRxCallback()
{
sbus_to_rc(rc_usart_instance->recv_buff, &rc_ctrl);
sbus_to_rc(rc_usart_instance->recv_buff);
}
RC_ctrl_t *RC_init(UART_HandleTypeDef *rc_usart_handle)
RC_ctrl_t *RemoteControlInit(UART_HandleTypeDef *rc_usart_handle)
{
USART_Init_Config_s conf;
conf.module_callback = ReceiveCallback;
conf.module_callback = RCRxCallback;
conf.usart_handle = rc_usart_handle;
conf.recv_buff_size = REMOTE_CONTROL_FRAME_SIZE;
rc_usart_instance = USARTRegister(&conf);

View File

@@ -17,9 +17,16 @@
#include "main.h"
#include "usart.h"
// 获取按键操作
#define KEY_PRESS 0
#define KEY_STATE 1
#define KEY_PRESS_WITH_CTRL 2
#define KEY_PRESS_WITH_SHIFT 3
#define RC_CH_VALUE_MIN ((uint16_t)364)
#define RC_CH_VALUE_OFFSET ((uint16_t)1024)
#define RC_CH_VALUE_MAX ((uint16_t)1684)
/* ----------------------- RC Switch Definition----------------------------- */
#define RC_SW_UP ((uint16_t)1)
#define RC_SW_MID ((uint16_t)3)
@@ -27,31 +34,34 @@
#define switch_is_down(s) (s == RC_SW_DOWN)
#define switch_is_mid(s) (s == RC_SW_MID)
#define switch_is_up(s) (s == RC_SW_UP)
/* ----------------------- PC Key Definition-------------------------------- */
#define KEY_PRESSED_OFFSET_W ((uint16_t)1 << 0)
#define KEY_PRESSED_OFFSET_S ((uint16_t)1 << 1)
#define KEY_PRESSED_OFFSET_A ((uint16_t)1 << 2)
#define KEY_PRESSED_OFFSET_D ((uint16_t)1 << 3)
#define KEY_PRESSED_OFFSET_SHIFT ((uint16_t)1 << 4)
#define KEY_PRESSED_OFFSET_CTRL ((uint16_t)1 << 5)
#define KEY_PRESSED_OFFSET_E ((uint16_t)1 << 7)
#define KEY_PRESSED_OFFSET_Q ((uint16_t)1 << 6)
#define KEY_PRESSED_OFFSET_R ((uint16_t)1 << 8)
#define KEY_PRESSED_OFFSET_F ((uint16_t)1 << 9)
#define KEY_PRESSED_OFFSET_G ((uint16_t)1 << 10)
#define KEY_PRESSED_OFFSET_Z ((uint16_t)1 << 11)
#define KEY_PRESSED_OFFSET_X ((uint16_t)1 << 12)
#define KEY_PRESSED_OFFSET_C ((uint16_t)1 << 13)
#define KEY_PRESSED_OFFSET_V ((uint16_t)1 << 14)
#define KEY_PRESSED_OFFSET_B ((uint16_t)1 << 15)
// 对应key[x][0~16],获取对应的键;例如通过key[KEY_PRESS][Key_W]获取W键是否按下
#define Key_W 0
#define Key_S 1
#define Key_D 2
#define Key_A 3
#define Key_Shift 4
#define Key_Ctrl 5
#define Key_Q 6
#define Key_E 7
#define Key_R 8
#define Key_F 9
#define Key_G 10
#define Key_Z 11
#define Key_X 12
#define Key_C 13
#define Key_V 14
#define Key_B 15
/* ----------------------- Data Struct ------------------------------------- */
typedef struct
{
struct
{
int16_t ch[5];
char s[2];
} rc;
int16_t ch[5]; // 右|0 ,右-1 ,左-2 ,左|3 ,拨轮4
uint8_t s[2]; //[0]:left [1]:right
} joy_stick;
struct
{
int16_t x;
@@ -60,12 +70,33 @@ typedef struct
uint8_t press_l;
uint8_t press_r;
} mouse;
struct
{
uint16_t v;
} key;
uint16_t key_temp;
uint8_t key[4][16];
} RC_ctrl_t;
// 待测试的位域结构体,可以极大提升解析速度
typedef struct
{
uint16_t w : 1;
uint16_t s : 1;
uint16_t d : 1;
uint16_t a : 1;
uint16_t shift : 1;
uint16_t ctrl : 1;
uint16_t q : 1;
uint16_t e : 1;
uint16_t r : 1;
uint16_t f : 1;
uint16_t g : 1;
uint16_t z : 1;
uint16_t x : 1;
uint16_t c : 1;
uint16_t v : 1;
uint16_t b : 1;
} Key_t;
/* ------------------------- Internal Data ----------------------------------- */
/**
@@ -74,6 +105,6 @@ typedef struct
* @attention 注意分配正确的串口硬件,遥控器在C板上使用USART3
*
*/
RC_ctrl_t *RC_init(UART_HandleTypeDef *rc_usart_handle);
RC_ctrl_t *RemoteControlInit(UART_HandleTypeDef *rc_usart_handle);
#endif

View File

@@ -10,7 +10,7 @@
#include "stdlib.h"
static SuperCapInstance *super_cap_instance = NULL;
static void SuperCapRxCallback(can_instance *_instance)
static void SuperCapRxCallback(CANInstance *_instance)
{
static uint8_t *rxbuff;
static SuperCap_Msg_s *Msg;
@@ -25,9 +25,6 @@ SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config)
{
super_cap_instance = (SuperCapInstance *)malloc(sizeof(SuperCapInstance));
memset(super_cap_instance, 0, sizeof(SuperCapInstance));
super_cap_instance->recv_data_len = supercap_config->recv_data_len;
super_cap_instance->send_data_len = supercap_config->send_data_len;
supercap_config->can_config.can_module_callback = SuperCapRxCallback;
super_cap_instance->can_ins = CANRegister(&supercap_config->can_config);
return super_cap_instance;
@@ -35,9 +32,7 @@ SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config)
void SuperCapSend(SuperCapInstance *instance, uint8_t *data)
{
CANSetDLC(instance->can_ins, 8);
memcpy(instance->can_ins->tx_buff, data, instance->send_data_len);
memcpy(instance->can_ins->tx_buff, data, 8);
CANTransmit(instance->can_ins);
}

View File

@@ -1,50 +1,39 @@
/*
* @Descripttion:
* @version:
* @Descripttion:
* @version:
* @Author: Chenfu
* @Date: 2022-12-02 21:32:47
* @LastEditTime: 2022-12-05 15:25:46
*/
#ifndef SUPER_CAP_H
#define SUPER_CAP_H
#define SUPER_CAP_H
#include "bsp_can.h"
typedef struct
typedef struct
{
uint16_t vol;
uint16_t current;
uint16_t power;
}SuperCap_Msg_s;
} SuperCap_Msg_s;
#pragma pack(1)
typedef struct
{
can_instance* can_ins;
/* 发送部分 */
uint8_t send_data_len;
uint8_t raw_sendbuf;
/* 接收部分 */
uint8_t recv_data_len;
uint8_t raw_recvbuff;
CANInstance *can_ins;
SuperCap_Msg_s cap_msg;
} SuperCapInstance;
#pragma pack()
typedef struct
{
can_instance_config_s can_config;
CAN_Init_Config_s can_config;
uint8_t send_data_len;
uint8_t recv_data_len;
} SuperCap_Init_Config_s;
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s* supercap_config);
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config);
void SuperCapSend(SuperCapInstance *instance, uint8_t *data);
#endif // !SUPER_CAP_Hd