跳到主要内容基于 STM32F407 与 K230 的二维云台激光打靶系统设计 | 极客日志CAI算法
基于 STM32F407 与 K230 的二维云台激光打靶系统设计
基于 STM32F407 微控制器与 K230 视觉模块构建的二维云台激光打靶系统,通过分段式自适应 PID 算法实现高精度目标追踪与自动瞄准。系统采用多任务调度机制,结合 UART 串口通信控制步进电机,支持多种工作模式及防摆动优化策略,适用于嵌入式视觉伺服控制场景。
CloudNative1 浏览 系统概述
本项目实现了一套基于 STM32F407 微控制器与 K230 视觉模块的二维云台激光打靶系统。通过视觉伺服控制、PID 算法及步进电机驱动技术,完成高精度的目标识别、自动瞄准与激光发射功能。系统经竞赛验证,在动态追踪与定点命中方面表现稳定。
系统总体设计
架构分层
- 感知层:摄像头采集图像,提取目标坐标信息。
- 控制层:主控板处理数据,运行 PID 控制算法与运动规划。
- 执行层:双轴步进电机调整云台角度,继电器控制激光发射。
- 交互层:按键输入、状态指示灯及串口调试输出。
工作流程
- 目标识别:视觉模块实时采集图像,提取目标像素坐标。
- 误差计算:对比目标坐标与激光准星位置,计算像素误差。
- PID 控制:根据误差生成电机控制信号。
- 电机驱动:控制双轴步进电机调整云台角度以消除误差。
- 激光发射:当目标稳定在允许误差范围内时触发激光。
- 状态反馈:通过指示灯和串口实时输出系统状态。
硬件选型与配置
1. 主控板:嘉立创天空星
- 核心芯片:STM32F407VET6 (ARM Cortex-M4)
- 主频:25MHz 晶振,PLL 倍频至系统时钟
- 外设配置:5 路 UART 串口、多路 GPIO 控制、DMA 数据传输、TIM 定时器
2. 步进电机:张大头步进电机(Emm42_V5.0 PLC 套餐)
- 型号:Emm42_V5.0 PLC 套餐
- 控制方式:UART 串口通信
- 地址配置:X 轴电机地址 0x01(UART2),Y 轴电机地址 0x02(UART4)
- 性能参数:最大速度 2000 RPM,高精度位置控制,内置闭环反馈
3. 视觉模块:亚博 K230 视觉模块
- 平台:CanMV K230
- 功能:实时图像采集与矩形识别
- 输出格式:
origin:(x,y)\r\n 坐标数据
- 性能:全角度圆形校正,高精度坐标提取
4. 激光笔:10mw 蓝紫色可调焦激光笔
- 功率:10mw
- 颜色:蓝紫色
- 特性:可调焦,光束清晰可见,适合室内使用
5. 继电器:1 路 5 伏高低电平触发
- 控制方式:低电平触发激光笔开关
- 电压:5V
- 功能:实现激光的电子开关控制,电气隔离防止干扰
硬件连接示意
摄像头模块 (UART3) → STM32F407
步进电机 轴 (UART2) → STM32F407
步进电机 轴 (UART4) → STM32F407
激光控制 (PA8) → 继电器 → 激光笔
按键输入 (PE9/PE11/PB6) → STM32F407
LED 指示灯 (PA3/PA5) → STM32F407
调试串口 (UART1) → 上位机
X
Y
软件架构设计
模块化软件架构
├── Core/
│ ├── Inc/
│ └── Src/
├── Drivers/
├── bsp/
│ ├── bsp_system.h
│ ├── schedule.c
│ ├── key_bsp.c
│ ├── uart_bsp.c
│ ├── step_motor_bsp.c
│ ├── pi_bsp.c
│ └── laser_bsp.c
├── app/
│ ├── Emm_V5.c
│ ├── Emm_V5.h
│ ├── mypid.c
│ └── mypid.h
└── ringbuffer/
任务调度系统
系统采用基于时间片的任务调度机制,确保关键任务及时执行:
void schedule_init(void) {
task_list[TASK_ID_LASER_CONTROL] = &Laser_Process;
task_list[TASK_ID_KEY_SCAN] = &Key_Scan_Process;
task_list[TASK_ID_VISION_PROC] = &pi_proc;
}
void schedule_run(void) {
uint32_t current_time = HAL_GetTick();
for (int i = 0; i < TASK_COUNT; i++) {
if (current_time - task_last_run[i] >= task_interval[i]) {
task_list[i]();
task_last_run[i] = current_time;
}
}
}
视觉数据处理模块
int pi_parse_data(char* buffer) {
int parsed_x, parsed_y;
int parsed_count;
if (strncmp(buffer, "origin:", 7) == 0) {
parsed_count = sscanf(buffer, "origin:(%d,%d)", &parsed_x, &parsed_y);
if (parsed_count != 2) return -2;
latest_red_laser_coord.x = parsed_x;
latest_red_laser_coord.y = parsed_y;
latest_red_laser_coord.isValid = 1;
my_printf(&huart1, "Origin: (%d,%d)\r\n", parsed_x, parsed_y);
return 0;
}
return -3;
}
关键技术实现
1. 分段式 PID 设计逻辑
由于激光点在画面中的像素误差与电机转角是非线性关系(近处误差 10 像素与远处 10 像素对应的物理偏转角不同),设计了分段式自适应 PID:
- 超远距离 (Error > 100px):采用大 Kp (2.0) 快速趋近。
- 中近距离 (Error < 15px):切换至小 Kp (1.0 - 0.5) 并减小输出限幅,防止在目标点附近产生高频震荡。
- 积分策略:引入积分分离,仅在近距离时保留微弱积分项,以消除静差并防止过冲。
typedef struct {
float kp;
float ki;
float kd;
float iout;
float last_err;
float out_max;
} PID_Controller;
float adaptive_pid_control(PID_Controller *pid, float target, float current, float error_distance) {
float err = target - current;
if (error_distance > 100.0f) {
pid->kp = 2.0f;
pid->out_max = 25.0f;
} else if (error_distance > 60.0f) {
pid->kp = 1.8f;
pid->out_max = 20.0f;
} else if (error_distance > 40.0f) {
pid->kp = 1.5f;
pid->out_max = 16.0f;
} else if (error_distance > 25.0f) {
pid->kp = 1.2f;
pid->out_max = 12.0f;
} else if (error_distance > 15.0f) {
pid->kp = 1.0f;
pid->out_max = 5.0f;
} else if (error_distance > 10.0f) {
pid->kp = 0.8f;
pid->out_max = 3.0f;
} else {
pid->kp = 0.5f;
pid->out_max = 1.0f;
}
if (error_distance < 15.0f) pid->ki = 0.0001f;
else pid->ki = 0.00015f;
float pout = pid->kp * err;
pid->iout += pid->ki * err;
if (pid->iout > pid->out_max) pid->iout = pid->out_max;
else if (pid->iout < -pid->out_max) pid->iout = -pid->out_max;
float dout = pid->kd * (err - pid->last_err);
pid->last_err = err;
float output = pout + pid->iout + dout;
if (output > pid->out_max) output = pid->out_max;
else if (output < -pid->out_max) output = -pid->out_max;
return output;
}
2. 步进电机精确控制
通过 UART 串口与步进电机驱动器通信,实现精确的角度控制:
void Step_Motor_Set_Speed_my(float x_rpm, float y_rpm) {
uint8_t x_dir, y_dir;
uint16_t x_speed_scaled, y_speed_scaled;
x_dir = (x_rpm >= 0.0f) ? 0 : 1;
y_dir = (y_rpm >= 0.0f) ? 0 : 1;
x_speed_scaled = (uint16_t)(fabs(x_rpm) * 10 + 0.5f);
y_speed_scaled = (uint16_t)(fabs(y_rpm) * 10 + 0.5f);
Emm_V5_Vel_Control(&MOTOR_X_UART, MOTOR_X_ADDR, x_dir, x_speed_scaled, MOTOR_ACCEL, MOTOR_SYNC_FLAG);
Emm_V5_Vel_Control(&MOTOR_Y_UART, MOTOR_Y_ADDR, y_dir, y_speed_scaled, MOTOR_ACCEL, MOTOR_SYNC_FLAG);
}
void Step_Motor_Rotate_X_Angle(int16_t angle) {
uint8_t dir;
uint32_t pulses;
if (angle > 180) angle = 180;
if (angle < -180) angle = -180;
if (angle >= 0) {
dir = 1;
pulses = (uint32_t)(angle * 150);
} else {
dir = 0;
pulses = (uint32_t)((-angle) * 150);
}
Emm_V5_Pos_Control(&MOTOR_X_UART, MOTOR_X_ADDR, dir, MOTOR_MAX_SPEED, MOTOR_ACCEL, pulses, false, MOTOR_SYNC_FLAG);
}
3. 激光控制系统
实现多模式激光发射策略,包括定时发射、按键触发和自动追踪:
void Laser_Process(void) {
uint32_t current_time = HAL_GetTick();
if (laser_control.system_mode == SYSTEM_MODE_1 && laser_control.system_started && !laser_control.mode1_fired && !laser_control.manual_override) {
uint32_t elapsed_time = current_time - laser_control.system_start_time;
if (elapsed_time >= MODE1_AUTO_FIRE_DELAY_MS) {
laser_control.state = LASER_STATE_AUTO_FIRING;
laser_control.fire_start_time = current_time;
laser_control.mode1_fired = 1;
my_printf(&huart1, "LASER: Mode 1 - Auto fire started after 1.5s!\r\n");
}
}
if (laser_control.system_mode == SYSTEM_MODE_3 && laser_control.system_started && !laser_control.manual_override) {
if (laser_control.target_locked && !laser_control.mode3_tracking) {
laser_control.mode3_start_time = current_time;
laser_control.mode3_tracking = 1;
laser_control.state = LASER_STATE_AUTO_FIRING;
laser_control.fire_start_time = current_time;
laser_control.mode3_fired = 1;
my_printf(&huart1, "LASER: Mode 3 - Target detected, immediate laser firing started (20s continuous duration)\r\n");
}
}
if (laser_control.state == LASER_STATE_AUTO_FIRING && laser_control.system_mode != SYSTEM_MODE_3 && !laser_control.manual_override) {
if (current_time - laser_control.fire_start_time >= laser_control.fire_duration_ms) {
laser_control.state = LASER_STATE_OFF;
my_printf(&huart1, "LASER: Auto fire completed - OFF\r\n");
}
}
}
系统工作模式
-
模式 0:待机模式
- 状态:电机未使能,激光强制关闭
- 指示灯:LED1 和 LED2 均灭
- 操作:按下 START 键启动系统
- 适用场景:系统初始化与安全检查
-
模式 1:定时发射模式
- 功能:Y 轴复位后自动定位发射
- 特点:无目标追踪,X 轴不运动
- 指示灯:LED1 亮,LED2 灭
- 触发条件:Y 轴回零完成后
- 适用场景:固定目标打靶与基础测试
-
模式 2:按键角度模式
- 功能:先通过角度按键预设启动后的转动角度,按下 START 键后自动转动并发射
- 特点:支持目标追踪,双轴运动
- 指示灯:LED1 灭,LED2 亮
- 触发条件:按下 START 键开始计时
- 适用场景:移动目标静态打靶
-
模式 3:增强稳定模式
- 功能:识别目标立即发射,持续 20 秒
- 特点:高级滤波算法,抗干扰性强
- 指示灯:LED1 和 LED2 均亮
- 触发条件:目标进入稳定区域
- 适用场景:复杂环境下高精度动态追踪打靶
防摆动优化策略
系统采用多层防摆动机制,确保高速追踪过程中的稳定性:
1. 渐进式积分管理
if (error_distance < 15.0f) {
float integral_factor = error_distance / 15.0f;
if (integral_factor < 0.3f) integral_factor = 0.3f;
pid_x.iout *= integral_factor;
pid_y.iout *= integral_factor;
}
if (error_distance < 8.0f) {
pid_x.iout *= 0.5f;
pid_y.iout *= 0.5f;
}
2. 自适应变化率限制
if (error_distance < 15.0f) {
float max_change_x, max_change_y;
if (error_distance < 6.0f) {
max_change_x = 1.0f;
max_change_y = 1.0f;
} else {
max_change_x = 3.0f;
max_change_y = 3.0f;
}
float change_x = smooth_x - last_smooth_x;
float change_y = smooth_y - last_smooth_y;
if (change_x > max_change_x) smooth_x = last_smooth_x + max_change_x;
if (change_x < -max_change_x) smooth_x = last_smooth_x - max_change_x;
if (change_y > max_change_y) smooth_y = last_smooth_y + max_change_y;
if (change_y < -max_change_y) smooth_y = last_smooth_y - max_change_y;
}
3. 智能摆动检测与抑制
if (error_distance < 35.0f) {
static float last_error_x = 0.0f, last_error_y = 0.0f;
static uint8_t direction_changes_x = 0, direction_changes_y = 0;
float current_error_x = latest_green_laser_coord.x - latest_red_laser_coord.x;
float current_error_y = latest_green_laser_coord.y - latest_red_laser_coord.y;
if ((current_error_x * last_error_x < 0) && (fabs(current_error_x) > oscillation_threshold_x)) {
direction_changes_x++;
if (direction_changes_x > 3) {
my_printf(&huart1, "X-AXIS SEVERE OSCILLATION - Emergency damping\r\n");
pid_x.iout *= 0.005f;
} else if (direction_changes_x > 2) {
my_printf(&huart1, "X-AXIS MODERATE OSCILLATION - Strong damping\r\n");
pid_x.iout *= 0.02f;
}
}
}
性能测试与优化
1. 追踪精度测试
在不同距离条件下测试系统追踪精度,均可在满足基础部分时间限制要求的前提下,基本命中靶心(误差仅在 1cm 左右)。
2. 稳定性提升
float adaptive_filtering(float raw_value, float filtered_value, float movement_magnitude) {
float filter_alpha;
if (movement_magnitude > 50.0f) filter_alpha = 0.4f;
else if (movement_magnitude > 20.0f) filter_alpha = 0.25f;
else if (movement_magnitude > 10.0f) filter_alpha = 0.15f;
else filter_alpha = 0.1f;
return filtered_value * (1.0f - filter_alpha) + raw_value * filter_alpha;
}
创新点总结
- 软硬件协同优化:选用高性能硬件组合,配合自适应 PID+ 防摆动优化+ 多模式控制策略。
- 多模式工作系统:4 种工作模式适应不同应用场景,灵活的人机交互设计与状态可视化反馈。
- 高效防摆动策略:多层防摆动机制,包含自适应变化率限制与智能摆动检测与抑制。
- 模块化系统设计:清晰的软件架构,可复用的功能模块,易于扩展和维护。
项目开源与资源共享
资源包含完整源代码(STM32 工程文件,Python 视觉处理脚本)、开发文档(系统设计说明,API 接口文档)及 3D 打印文件(适配张大头步进电机的二维云台 3D 结构)。初学者建议先阅读 README.md 了解系统架构,开发者可直接使用现有代码框架进行二次开发。
总结
本项目成功实现了基于 STM32F407 的二维云台激光打靶系统,融合了视觉识别、运动控制和实时调度等多项关键技术。通过本项目的实践,不仅为电子设计竞赛提供了完整解决方案,也为嵌入式视觉伺服系统的开发积累了宝贵经验。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- 随机西班牙地址生成器
随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online