modified: MDK-ARM/DevC.uvoptx

modified:   MDK-ARM/DevC/DevC.axf
	modified:   MDK-ARM/DevC/DevC.hex
	modified:   User/module/config.c
	modified:   User/module/gimbal.c
	modified:   User/module/gimbal.h
	modified:   User/task/ai.c
	modified:   User/task/atti_esti.c
	modified:   User/task/rc.c
	modified:   User/task/user_task.c
This commit is contained in:
zzzhkgs@gmail.com 2026-03-14 03:53:43 +08:00
parent a998d90e0e
commit ed1a174ab1
10 changed files with 5376 additions and 5306 deletions

View File

@ -120,7 +120,7 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>CMSIS_AGDI</Key> <Key>CMSIS_AGDI</Key>
<Name>-X"" -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407IGHx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name> <Name>-X"Any" -UAny -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407IGHx$CMSIS\Flash\STM32F4xx_1024.FLM)</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
@ -180,6 +180,36 @@
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>dr16</ItemText> <ItemText>dr16</ItemText>
</Ww> </Ww>
<Ww>
<count>5</count>
<WinNumber>1</WinNumber>
<ItemText>robot_config</ItemText>
</Ww>
<Ww>
<count>6</count>
<WinNumber>1</WinNumber>
<ItemText>\\DevC\../User/module/config.c\robot_config.gimbal_param.mech_zero.pit</ItemText>
</Ww>
<Ww>
<count>7</count>
<WinNumber>1</WinNumber>
<ItemText>BSP_UART_AI</ItemText>
</Ww>
<Ww>
<count>8</count>
<WinNumber>1</WinNumber>
<ItemText>tx_pkg</ItemText>
</Ww>
<Ww>
<count>9</count>
<WinNumber>1</WinNumber>
<ItemText>tx_pkg</ItemText>
</Ww>
<Ww>
<count>10</count>
<WinNumber>1</WinNumber>
<ItemText>tx_pkg</ItemText>
</Ww>
</WatchWindow1> </WatchWindow1>
<Tracepoint> <Tracepoint>
<THDelay>0</THDelay> <THDelay>0</THDelay>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -66,12 +66,12 @@ Config_RobotParam_t robot_config = {
}, },
}, },
.mech_zero = { .mech_zero = {
.yaw = 0.0f, .yaw = 2.9f,
.pit = 1.1f, .pit = 1.39f,
}, },
.travel = { .travel = {
.yaw = -1.0f, .yaw = 1.0f,
.pit = 1.4f, .pit = 1.2f,
}, },
.low_pass_cutoff_freq = { .low_pass_cutoff_freq = {
.out = -1.0f, .out = -1.0f,
@ -88,7 +88,7 @@ Config_RobotParam_t robot_config = {
.can = BSP_CAN_1, .can = BSP_CAN_1,
.id = 0x206, .id = 0x206,
.module = MOTOR_GM6020, .module = MOTOR_GM6020,
.reverse = false, .reverse = true,
.gear = false, .gear = false,
}, },
// .imu = { // .imu = {
@ -104,8 +104,8 @@ Config_RobotParam_t robot_config = {
.shoot_param = { .shoot_param = {
.trig_step_angle=M_2PI/8, .trig_step_angle=M_2PI/7.8,
.shot_delay_time=0.05f, .shot_delay_time=0.08f,
.shot_burst_num=1, .shot_burst_num=1,
.fric_motor_param[0] = { .fric_motor_param[0] = {
.can = BSP_CAN_1, .can = BSP_CAN_1,
@ -164,8 +164,8 @@ Config_RobotParam_t robot_config = {
.p=1.0f, .p=1.0f,
.i=0.1f, .i=0.1f,
.d=0.05f, .d=0.05f,
.i_limit=0.8f, .i_limit=0.3f,
.out_limit=0.5f, .out_limit=0.9f,
.d_cutoff_freq=-1.0f, .d_cutoff_freq=-1.0f,
.range=M_2PI, .range=M_2PI,
}, },

View File

@ -17,7 +17,9 @@
/* Private macro ------------------------------------------------------------ */ /* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */ /* Private function -------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
#define YAW_MAX_OUTPUT 0.3f /* Yaw轴(大疆电机)最大输出比例限制范围0.0 到 1.0 */
#define PIT_MAX_TORQUE 1.0f /* Pitch轴(达妙电机)最大扭矩限制单位N·m (请根据实际情况调整) */
/** /**
* \brief * \brief
* *
@ -252,19 +254,37 @@ int8_t Gimbal_Control(Gimbal_t *g, Gimbal_CMD_t *g_cmd) {
return 0; return 0;
} }
/** /**
* \brief * \brief
* *
* \param s * \param g
* \param out CAN设备云台输出结构体
*/ */
void Gimbal_Output(Gimbal_t *g){ void Gimbal_Output(Gimbal_t *g){
if (g_debug_motor_enable) { if (1) {
/* 标志位为1正常工作时的输出逻辑 */ /* 标志位为1正常工作时的输出逻辑 */
MOTOR_RM_SetOutput(&g->param->yaw_motor, g->out.yaw);
/* 1. 对 Yaw 轴输出(大疆 RM 电机)进行限幅 */
float target_yaw_out = g->out.yaw;
if (target_yaw_out > YAW_MAX_OUTPUT) {
target_yaw_out = YAW_MAX_OUTPUT;
} else if (target_yaw_out < -YAW_MAX_OUTPUT) {
target_yaw_out = -YAW_MAX_OUTPUT;
}
MOTOR_RM_SetOutput(&g->param->yaw_motor, target_yaw_out);
/* 2. 计算 Pitch 轴扭矩(达妙 DM 电机)并进行限幅 */
float target_pit_torque = g->out.pit * 3.0f; // 乘以减速比
if (target_pit_torque > PIT_MAX_TORQUE) {
target_pit_torque = PIT_MAX_TORQUE;
} else if (target_pit_torque < -PIT_MAX_TORQUE) {
target_pit_torque = -PIT_MAX_TORQUE;
}
MOTOR_MIT_Output_t output = {0}; MOTOR_MIT_Output_t output = {0};
output.torque = g->out.pit * 3.0f; // 乘以减速比 output.torque = target_pit_torque;
output.kd = 0.3f; output.kd = 0.3f;
/* 下发控制指令 */
MOTOR_RM_Ctrl(&g->param->yaw_motor); MOTOR_RM_Ctrl(&g->param->yaw_motor);
MOTOR_DM_MITCtrl(&g->param->pit_motor, &output); MOTOR_DM_MITCtrl(&g->param->pit_motor, &output);
} else { } else {

View File

@ -54,6 +54,14 @@ typedef struct {
float min; float min;
} Gimbal_Limit_t; } Gimbal_Limit_t;
#define LIMIT_POLYGON_POINTS 8
typedef struct {
float yaw; /* 节点的 Yaw 坐标 (横轴) */
float pit; /* 节点的 Pitch 坐标 (纵轴) */
} Gimbal_Point2D_t;
/* 云台参数的结构体包含所有初始化用的参数通常是const存好几组。*/ /* 云台参数的结构体包含所有初始化用的参数通常是const存好几组。*/
typedef struct { typedef struct {
MOTOR_DM_Param_t pit_motor; /* pitch轴电机参数 */ MOTOR_DM_Param_t pit_motor; /* pitch轴电机参数 */
@ -65,6 +73,7 @@ typedef struct {
KPID_Params_t pit_angle; /* pitch轴角位置环PID参数 */ KPID_Params_t pit_angle; /* pitch轴角位置环PID参数 */
} pid; } pid;
/* 低通滤波器截止频率 */ /* 低通滤波器截止频率 */
struct { struct {
float out; /* 电机输出 */ float out; /* 电机输出 */

View File

@ -18,92 +18,88 @@
/* USER INCLUDE END */ /* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
#define ID_MCU (0xC4) // MCU 数据包 (发送)
#define ID_REF (0xA8) // 裁判系统数据包 (发送)
#define ID_AI (0xB5) // AI 控制数据包 (接收)
extern uint8_t AI_mode; // AI 模式变量供其他模块查询当前AI控制模式 extern uint8_t AI_mode; // AI 模式变量供其他模块查询当前AI控制模式
// MCU 数据结构MCU -> 上位机) // MCU 数据结构MCU -> 上位机)
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
uint8_t mode; // 0: 空闲, 1: 自瞄, 2: 小符, 3: 大符 uint8_t head[2]; // {'M', 'R'}
float q[4]; // 四元数 wxyz 顺序 uint8_t mode; // 0: 空闲, 1: 自瞄, 2: 小符, 3: 大符
float yaw; // 偏航角 float q[4]; // wxyz顺序
float yaw_vel; // 偏航角速度 float yaw; // 偏航角
float pitch; // 俯仰角 float yaw_vel; // 偏航角速度
float pitch_vel; // 俯仰角速度 float pitch; // 俯仰角
float bullet_speed; // 弹速 float pitch_vel; // 俯仰角速度
uint16_t bullet_count; // 子弹累计发送次数 float bullet_speed; // 弹速
} DataMCU_t; uint16_t bullet_count; // 子弹累计发送次数
typedef struct __attribute__((packed)) {
uint8_t id; // 数据包 ID: 0xC4
DataMCU_t data;
uint16_t crc16; uint16_t crc16;
} PackageMCU_t; } GimbalToVision_t;
// 确保结构体大小符合要求 (C11 标准)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(GimbalToVision_t) <= 64, "GimbalToVision_t size exceeds 64 bytes");
#endif
// AI 控制数据结构(上位机 -> MCU // AI 控制数据结构(上位机 -> MCU
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
uint8_t mode; // 0: 不控制, 1: 控制云台但不开火, 2: 控制云台且开火 uint8_t head[2]; // {'M', 'R'}
float yaw; // 目标偏航角/偏移量 uint8_t mode; // 0: 不控制, 1: 控制云台但不开火2: 控制云台且开火
float yaw_vel; // 偏航角速度 float yaw; // 目标偏航角/偏移量
float yaw_acc; // 偏航角加速度 float yaw_vel; // 偏航角速度
float pitch; // 目标俯仰角/偏移量 float yaw_acc; // 偏航角加速度
float pitch_vel; // 俯仰角速度 float pitch; // 目标俯仰角/偏移量
float pitch_acc; // 俯仰角加速度 float pitch_vel; // 俯仰角速度
float vx; // X 方向速度 float pitch_acc; // 俯仰角加速度
float vy; // Y 方向速度
float wz; // Z 方向角速度
uint8_t reserved; // 预留字段
} DataAI_t;
typedef struct __attribute__((packed)) {
uint8_t id; // 数据包 ID: 0xB5
DataAI_t data;
uint16_t crc16; uint16_t crc16;
} PackageAI_t; } VisionToGimbal_t;
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(VisionToGimbal_t) <= 64, "VisionToGimbal_t size exceeds 64 bytes");
#endif
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
static uint8_t ai_rx_buf[sizeof(PackageAI_t)]; static uint8_t ai_rx_buf[sizeof(VisionToGimbal_t)];
static PackageAI_t ai_rx_data; static VisionToGimbal_t ai_rx_data;
/* 声明外部全局变量,用于直接获取高频反馈数据 */ /* 声明外部全局变量,用于直接获取高频反馈数据 */
extern Gimbal_t gimbal; extern Gimbal_t gimbal;
extern Shoot_t shoot; extern Shoot_t shoot;
GimbalToVision_t tx_pkg;
/* USER FUNCTION BEGIN */ /* USER FUNCTION BEGIN */
/** /**
* @brief AI串口接收完成回调函数 * @brief AI串口接收完成回调函数
* @note ID与CRC16校验DMA接收 * @note CRC16校验DMA接收
*/ */
static void AI_RxCpltCallback(void) { static void AI_RxCpltCallback(void) {
if (ai_rx_buf[0] == ID_AI) { /* 检查包头是否为 'M' 和 'R' */
if (ai_rx_buf[0] == 'M' && ai_rx_buf[1] == 'R') {
/* 校验 CRC确保数据包完整 */ /* 校验 CRC确保数据包完整 */
if (CRC16_Verify(ai_rx_buf, sizeof(PackageAI_t))) { if (CRC16_Verify(ai_rx_buf, sizeof(VisionToGimbal_t))) {
memcpy(&ai_rx_data, ai_rx_buf, sizeof(PackageAI_t)); memcpy(&ai_rx_data, ai_rx_buf, sizeof(VisionToGimbal_t));
/* --- 修复 2务必初始化局部变量 --- */ /* --- 务必初始化局部变量 --- */
Gimbal_Vision_t vision_data; Gimbal_Vision_t vision_data;
memset(&vision_data, 0, sizeof(Gimbal_Vision_t)); memset(&vision_data, 0, sizeof(Gimbal_Vision_t));
Shoot_CMD_t ai_shoot_cmd; Shoot_CMD_t ai_shoot_cmd;
memset(&ai_shoot_cmd, 0, sizeof(Shoot_CMD_t)); // 防止野指针走火 memset(&ai_shoot_cmd, 0, sizeof(Shoot_CMD_t)); // 防止野指针走火
/* --- 修复 1 & 3正确赋值视觉结构体 --- */ /* --- 正确赋值视觉结构体 --- */
switch (ai_rx_data.data.mode) { switch (ai_rx_data.mode) {
case 0: /* 不控制 */ case 0: /* 不控制 */
vision_data.target_found = 0; vision_data.target_found = 0;
// ai_shoot_cmd.mode = SHOOT_MODE_STOP; // ai_shoot_cmd.mode = SHOOT_MODE_STOP;
break; break;
case 1: /* 控制云台但不开火 */ case 1: /* 控制云台但不开火 */
vision_data.target_found = 1; vision_data.target_found = 1;
vision_data.yaw = ai_rx_data.data.yaw; vision_data.yaw = ai_rx_data.yaw;
vision_data.pit = ai_rx_data.data.pitch; vision_data.pit = ai_rx_data.pitch;
// ai_shoot_cmd.mode = SHOOT_MODE_READY; // ai_shoot_cmd.mode = SHOOT_MODE_READY;
break; break;
case 2: /* 控制云台且开火 */ case 2: /* 控制云台且开火 */
vision_data.target_found = 1; vision_data.target_found = 1;
vision_data.yaw = ai_rx_data.data.yaw; vision_data.yaw = ai_rx_data.yaw;
vision_data.pit = ai_rx_data.data.pitch; vision_data.pit = ai_rx_data.pitch;
// ai_shoot_cmd.mode = SHOOT_MODE_FIRE; // ai_shoot_cmd.mode = SHOOT_MODE_FIRE;
break; break;
default: default:
@ -119,49 +115,50 @@ static void AI_RxCpltCallback(void) {
} }
} }
/* 重新开启DMA定长接收 */ /* 重新开启DMA定长接收 */
BSP_UART_Receive(BSP_UART_AI, ai_rx_buf, sizeof(PackageAI_t), true); BSP_UART_Receive(BSP_UART_AI, ai_rx_buf, sizeof(VisionToGimbal_t), true);
} }
/** /**
* @brief MCU状态数据 * @brief MCU状态数据
*/ */
static void AI_Send_MCU_Data(void) { static void AI_Send_MCU_Data(void) {
PackageMCU_t tx_pkg;
AHRS_Quaternion_t current_quat; AHRS_Quaternion_t current_quat;
tx_pkg.id = ID_MCU; memset(&tx_pkg, 0, sizeof(GimbalToVision_t));
memset(&tx_pkg.data, 0, sizeof(DataMCU_t));
/* 写入包头 */
tx_pkg.head[0] = 'M';
tx_pkg.head[1] = 'R';
/* 1. 获取四元数 (从消息队列读取) */ /* 1. 获取四元数 (从消息队列读取) */
if (osMessageQueueGet(task_runtime.msgq.ai.quat, &current_quat, NULL, 0) == osOK) { if (osMessageQueueGet(task_runtime.msgq.ai.quat, &current_quat, NULL, 0) == osOK) {
tx_pkg.data.q[0] = current_quat.q0; tx_pkg.q[0] = current_quat.q0;
tx_pkg.data.q[1] = current_quat.q1; tx_pkg.q[1] = current_quat.q1;
tx_pkg.data.q[2] = current_quat.q2; tx_pkg.q[2] = current_quat.q2;
tx_pkg.data.q[3] = current_quat.q3; tx_pkg.q[3] = current_quat.q3;
} }
/* 2. 获取云台状态 (直接读取全局 gimbal 结构体) */ /* 2. 获取云台状态 (直接读取全局 gimbal 结构体) */
tx_pkg.data.yaw = gimbal.feedback.imu.eulr.yaw; tx_pkg.yaw = gimbal.feedback.imu.eulr.yaw;
tx_pkg.data.yaw_vel = gimbal.feedback.imu.gyro.z; tx_pkg.yaw_vel = gimbal.feedback.imu.gyro.z;
tx_pkg.data.pitch = gimbal.feedback.imu.eulr.rol; /* 电控中 Pitch 对应 IMU 的 Rol */ tx_pkg.pitch = gimbal.feedback.imu.eulr.rol; /* 电控中 Pitch 对应 IMU 的 Rol */
tx_pkg.data.pitch_vel = gimbal.feedback.imu.gyro.y; tx_pkg.pitch_vel = gimbal.feedback.imu.gyro.y;
/* 3. 获取发射机构与模式状态 (直接读取全局 shoot 结构体) */ /* 3. 获取发射机构与模式状态 (直接读取全局 shoot 结构体) */
/* 模式回传,取值为实际枚举映射 */ /* 模式回传,取值为实际枚举映射 */
//tx_pkg.data.mode = (uint8_t)shoot.mode; tx_pkg.mode = AI_mode; /* 直接回传当前AI模式供上位机显示 */
tx_pkg.data.mode = AI_mode; /* 直接回传当前AI模式供上位机显示 */
/* 弹速反馈:由于硬件可能无法直接测弹速,暂用摩擦轮目标转速或估算转速代替。 /* 弹速反馈:暂用摩擦轮目标转速或估算转速代替。若接入裁判系统,应替换为真实弹速。 */
*/ tx_pkg.bullet_speed = shoot.target_variable.target_rpm;
tx_pkg.data.bullet_speed = shoot.target_variable.target_rpm;
/* 弹量统计:如有独立计数变量,可进行赋值 */ /* 弹量统计:如有独立计数变量,可进行赋值 */
//tx_pkg.data.bullet_count = shoot.feedback.xxxx; tx_pkg.bullet_count = -1;
tx_pkg.data.bullet_count = -1;
/* 4. 计算 CRC16扣除末尾 2 字节) */ /* 4. 计算 CRC16扣除末尾 2 字节) */
tx_pkg.crc16 = CRC16_Calc((const uint8_t *)&tx_pkg, sizeof(PackageMCU_t) - 2, CRC16_INIT); tx_pkg.crc16 = CRC16_Calc((const uint8_t *)&tx_pkg, sizeof(GimbalToVision_t) - 2, CRC16_INIT);
/* 5. 通过 DMA 发送至上位机 */ /* 5. 通过 DMA 发送至上位机 */
BSP_UART_Transmit(BSP_UART_AI, (uint8_t *)&tx_pkg, sizeof(PackageMCU_t), true); BSP_UART_Transmit(BSP_UART_AI, (uint8_t *)&tx_pkg, sizeof(GimbalToVision_t), true);
} }
/* USER FUNCTION END */ /* USER FUNCTION END */
@ -177,7 +174,7 @@ void Task_ai(void *argument) {
/* USER CODE INIT BEGIN */ /* USER CODE INIT BEGIN */
/* 注册串口接收完成回调并启动第一次DMA接收 */ /* 注册串口接收完成回调并启动第一次DMA接收 */
BSP_UART_RegisterCallback(BSP_UART_AI, BSP_UART_RX_CPLT_CB, AI_RxCpltCallback); BSP_UART_RegisterCallback(BSP_UART_AI, BSP_UART_RX_CPLT_CB, AI_RxCpltCallback);
BSP_UART_Receive(BSP_UART_AI, ai_rx_buf, sizeof(PackageAI_t), true); BSP_UART_Receive(BSP_UART_AI, ai_rx_buf, sizeof(VisionToGimbal_t), true);
/* USER CODE INIT END */ /* USER CODE INIT END */
while (1) { while (1) {

View File

@ -16,6 +16,7 @@
#include "component/ahrs.h" #include "component/ahrs.h"
#include "component/pid.h" #include "component/pid.h"
#include "device/bmi088.h" #include "device/bmi088.h"
#include "module/gimbal.h" /* 新增:引入云台模块以使用 Gimbal_IMU_t 结构体 */
/* USER INCLUDE END */ /* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
@ -83,6 +84,14 @@ void Task_atti_esti(void *argument) {
/* 根据解析出来的四元数计算欧拉角 */ /* 根据解析出来的四元数计算欧拉角 */
AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs); AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs);
osKernelUnlock(); osKernelUnlock();
// --- 新增将IMU数据角速度与欧拉角发送至云台控制任务的队列 ---
Gimbal_IMU_t gimbal_imu_to_send;
gimbal_imu_to_send.gyro = bmi088.gyro; // 填充陀螺仪角速度
gimbal_imu_to_send.eulr = eulr_to_send; // 填充解算后的欧拉角
osMessageQueuePut(task_runtime.msgq.gimbal.imu, &gimbal_imu_to_send, 0, 0);
// -----------------------------------------------------------------
// 将四元数发送至 AI 任务的消息队列 // 将四元数发送至 AI 任务的消息队列
// &gimbal_ahrs.quat: 四元数结构体地址 // &gimbal_ahrs.quat: 四元数结构体地址
// 0: 消息优先级 // 0: 消息优先级

View File

@ -64,14 +64,14 @@ void Task_rc(void *argument) {
break; break;
case DR16_SW_MID: case DR16_SW_MID:
cmd_for_gimbal.mode = GIMBAL_MODE_ABSOLUTE; cmd_for_gimbal.mode = GIMBAL_MODE_ABSOLUTE;
cmd_for_gimbal.delta_yaw = -dr16.data.ch_r_x * 5.0f; cmd_for_gimbal.delta_yaw = -dr16.data.ch_r_x * 1.0f;
cmd_for_gimbal.delta_pit = dr16.data.ch_r_y * 5.0f; cmd_for_gimbal.delta_pit = dr16.data.ch_r_y * 1.0f;
AI_mode = 0; /* AI 模式:空闲 */ AI_mode = 0; /* AI 模式:空闲 */
break; break;
case DR16_SW_DOWN: case DR16_SW_DOWN:
cmd_for_gimbal.mode = GIMBAL_MODE_AUTO_AIM; cmd_for_gimbal.mode = GIMBAL_MODE_AUTO_AIM;
cmd_for_gimbal.delta_yaw = -dr16.data.ch_r_x * 5.0f; cmd_for_gimbal.delta_yaw = -dr16.data.ch_r_x * 1.0f;
cmd_for_gimbal.delta_pit = dr16.data.ch_r_y * 5.0f; cmd_for_gimbal.delta_pit = dr16.data.ch_r_y * 1.0f;
AI_mode = 1; /* AI 模式:自动瞄准 */ AI_mode = 1; /* AI 模式:自动瞄准 */
break; break;
default: default:

View File

@ -12,7 +12,7 @@ const osThreadAttr_t attr_init = {
const osThreadAttr_t attr_ai = { const osThreadAttr_t attr_ai = {
.name = "ai", .name = "ai",
.priority = osPriorityNormal, .priority = osPriorityNormal,
.stack_size = 256 * 4, .stack_size = 256 * 8,
}; };
const osThreadAttr_t attr_blink = { const osThreadAttr_t attr_blink = {
.name = "blink", .name = "blink",