版本协议

GPL 3.0

标签
专业版
#第十届立创电赛#视觉语音巡线小车

创建时间:2个月前

246 1

视频

描述

<p style="line-height:1.8;">注:* 为必填项</p> <p style="line-height:1.8;"><strong><span style="color:#0093e6;">请在报名阶段填写 ↓</span></strong></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 1、项目功能介绍</h3> <hr> <p style="line-height:3;"><span style="font-size:18px;">1. 语音控制功能</span></p> <ul style="line-height:1.8;"> <li>语音指令识别</li> </ul> <p style="line-height:1.8;">     通过ASR Pro模块识别关键词(如“出发”、“停车”、“开灯”、“关灯”)</p> <p style="line-height:1.8;">     支持自定义唤醒词和指令集(天问51Block图形化配置)</p> <ul style="line-height:1.8;"> <li>语音反馈机制</li> </ul> <p style="line-height:1.8;">     执行指令时通过麦克风播报自定义词(如“出发喽”)</p> <ul style="line-height:1.8;"> <li>指令传输</li> </ul> <p style="line-height:1.8;">     ASR Pro通过串口向STM32发送指令码(例:0x01启动巡线,0x02紧急停止)</p> <p style="line-height:3;"><span style="font-size:18px;">2. 视觉巡线功能</span></p> <ul style="line-height:1.8;"> <li>路径识别核心算法</li> </ul> <p style="line-height:1.8;">     python</p> <p style="line-height:1.8;">     # 二值化处理</p> <p style="line-height:1.8;">     # 线性回归拟合</p> <p style="line-height:1.8;">     # 发送端点坐标+斜率</p> <ul style="line-height:1.8;"> <li>重要动态参数</li> </ul> <p style="line-height:1.8;">     斜率(判断整体方向)</p> <p style="line-height:1.8;">     端点坐标(计算路径偏移量)</p> <p style="line-height:3;"><span style="font-size:18px;">3. 运动控制功能</span></p> <ul style="line-height:1.8;"> <li>双环PID控制架构</li> </ul> <table style="border-collapse:collapse;width:47.6653%;height:96px;"> <tr> <td style="width:18.0592%;text-align:center;"><em>控制环</em></td> <td style="width:18.0335%;text-align:center;"><em>算法类型 </em></td> <td style="width:33.6069%;text-align:center;"><em> 功能</em></td> <td style="width:115.026%;text-align:center;"><em>参数示例</em></td> </tr> <tr> <td style="width:18.0592%;text-align:center;">速度环</td> <td style="width:18.0335%;text-align:center;">PI控制</td> <td style="width:33.6069%;text-align:center;">维持恒定速度</td> <td style="width:115.026%;text-align:center;">Kp=-400, Ki=-1.8</td> </tr> <tr> <td style="width:18.0592%;text-align:center;">转向环</td> <td style="width:18.0335%;text-align:center;">PD控制</td> <td style="width:33.6069%;text-align:center;">动态调整前轮转向角</td> <td style="width:115.026%;text-align:center;">Kp=15, Kd=300</td> </tr> </table> <ul style="line-height:1.8;"> <li>电机控制逻辑</li> </ul> <p style="line-height:1.8;">     接收串口指令后输出PWM波驱动电机</p> <p style="line-height:1.8;">     速度环+转向环输出量计算</p> <p style="line-height:3;"><span style="font-size:18px;">4. 多设备协同通信</span></p> <ul style="line-height:1.8;"> <li>串口协议设计</li> </ul> <table style="border-collapse:collapse;width:47.3032%;height:115px;"> <tr style="height:22px;"> <td style="width:31.4452%;height:22px;text-align:center;"><em>设备</em></td> <td style="width:52.0268%;height:22px;text-align:center;"><em>数据格式 </em></td> <td style="width:83.8878%;height:22px;text-align:center;"><em> 波特率</em></td> </tr> <tr style="height:38px;"> <td style="width:31.4452%;height:38px;text-align:center;">ASR Pro → STM32 </td> <td style="width:52.0268%;height:38px;text-align:center;">[CMD]</td> <td style="width:83.8878%;height:38px;text-align:center;">115200</td> </tr> <tr style="height:55px;"> <td style="width:31.4452%;height:55px;text-align:center;">OpenMV → STM32</td> <td style="width:52.0268%;height:55px;text-align:center;">[0xa3, 0xb3, bottom_x, theta, 0xc3] </td> <td style="width:83.8878%;height:55px;text-align:center;">115200</td> </tr> </table> <p style="line-height:3;"><span style="font-size:18px;">5. 状态指示系统</span></p> <ul style="line-height:1.8;"> <li>LED指示灯逻辑:语音激活:大LED灯亮/断1次</li> </ul> <p style="line-height:1.8;"><span style="font-size:18px;">6. 异常处理机制</span></p> <ul> <li style="line-height:1.8;">路径丢失检测:OpenMV未识别到直线时发送错误标志码</li> </ul> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*2、项目属性</h3> <hr> <p style="line-height:1.8;">项目首次公开,为原创<br>项目未参与其他比赛,未答辩</p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 3、开源协议</h3> <hr> <p>GPL3.0</p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><strong><span style="color:#0093e6;">请在竞赛阶段填写 ↓</span></strong></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*4、硬件部分</h3> <hr> <p style="line-height:1.8;">我一般都是写代码的角色,不会画板子,所以画的板子都是简单的模块堆积。</p> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/95IpG8yZwSn2By7U2iPfjA3xTTGTc9RhknTsG3hV.png" width="320" height="275" alt="95IpG8yZwSn2By7U2iPfjA3xTTGTc9RhknTsG3hV.png"></p> <p style="line-height:1.8;">一共两块板子:控制板(STM32,asrpro,openmv,蓝牙等)和供电板(12v,7v,5v,3.3v降压模块等)。分开是为了省钱,大学生比赛比较多,做其他项目只需要改控制板,最后直接把供电板插上去就好了,不需要再买降压模块也不用再焊接了。</p> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/QHUtvxvrAlSVBXQG32j8DDaMoJtf0cNS8QgcxY6k.jpeg" width="334" height="251" alt="QHUtvxvrAlSVBXQG32j8DDaMoJtf0cNS8QgcxY6k.jpeg"></p> <p style="line-height:1.8;">各模块增加100μF电解电容+0.1μF陶瓷电容滤波</p> <p style="line-height:1.8;">我板子画的比较烂,你们可以自己画。具体引脚连接保持一致就行,这样代码烧上就能动</p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*5、软件部分</h3> <hr> <p><strong>1. ASRPRO</strong>:<br>asrpro用天问51编程,我买的asrpro是带type-c下载的比较方便,天问51软件下载和烧录方法网上都是的,搜一下就好了,还有官方qq交流群。<br>下面是我的asrpro引脚配置和图形化编程,非常的简单</p> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/59taOUvTyJobp3vhD2UrSs7YanQoHuS0g4JohiK3.png" width="721" height="437" alt="59taOUvTyJobp3vhD2UrSs7YanQoHuS0g4JohiK3.png"></p> <p style="line-height:1.8;"> </p> <p><strong>2. OPENMV:</strong><br>  主要功能:通过摄像头捕捉图像,进行二值化、形态学处理和线性回归来识别巡线,然后通过串口发送数据给STM32。<br><span style="font-size:16px;">  算法流程:</span>图像采集 → 预处理 → 二值化 → 形态学处理 → 线性回归 → 数据解析 → 串口通信</p> <div>  辅助函数:</div> <pre><span style="font-size:14px;"><span style="font-size:16px;"> def get_endpoint(line): #获取直线下端点 #原理:在巡线应用中,y坐标越大代表越靠近小车前方 (x1, y1, x2, y2) = line.line() # 获取直线端点坐标 if y1 > y2: return (x1, y1) # 端点1更靠近底部 else: return (x2, y2) # 端点2更靠近底部 def theta_change(theta): #角度归一:将OpenMV的0-180度范围转换为-90到+90度 #便于STM32理解左右转向指令 if theta > 90: theta = theta - 180 # 将[91,179]映射到[-89,-1] return theta else: return theta </span><span style="font-size:16px;"># [0,90]保持不变</span><br></span></pre> <div>  二值化分割:   <span style="font-size:16px;">img.binary([THRESHOLD])</span></div> <div>         基于LAB色彩空间的阈值分割,将巡线区域变为白色(255),背景变为黑色(0),LAB色彩空间对光照变化不敏感,提高鲁棒性</div> <div>  线性回归检测:    <span style="font-size:16px;">line </span><span style="font-size:16px;">=</span><span style="font-size:16px;"> img</span><span style="font-size:16px;">.</span><span style="font-size:16px;">get_regression</span><span style="font-size:16px;">(</span><span style="font-size:16px;">[</span><span style="font-size:16px;">(</span><span style="font-size:16px;">100</span><span style="font-size:16px;">,</span><span style="font-size:16px;">100</span><span style="font-size:16px;">)</span><span style="font-size:16px;">]</span><span style="font-size:16px;">,</span><span style="font-size:16px;"> robust</span><span style="font-size:16px;">=</span><span style="font-size:16px;">True</span><span style="font-size:16px;">)</span></div> <div> <p>  通信协议设计:<br>         帧结构: [帧头1][帧头2][数据1][数据2][帧尾]<br>                       0xA3  0xB3 bottom_x theta  0xC3</p> <p>         特殊状态编码:<br>        - (200, 200): 巡线丢失状态<br>        - bottom_x: 下端点的x坐标(0-79)<br>        - theta: 归一化角度(-90到+90)</p> </div> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><strong>3. STM32:</strong></p> <div>多环控制:</div> <p>              速度环(PI) ←→ 转向环(PD) ←→ 电机输出<br>                    ↑                          ↑<br>            编码器反馈           OpenMV<br>速度环PI控制算法:</p> <pre><span style="font-size:16px;">int velocity_PID_value(int velocity_measure, int velocity_calcu) { float a = 0.3; // 一阶低通滤波系数 // 偏差计算 velocity = velocity_measure - velocity_calcu; // 一阶低通滤波:滤除高频噪声 filt_velocity = a * velocity + (1 - a) * last_filt_velocity; // 积分项累加(注意:此处可能需考虑积分限幅时机) velocity_sum += filt_velocity; // 积分限幅(抗积分饱和) I_xianfu(2000); // 更新历史值 last_filt_velocity = filt_velocity; // PI控制器输出:P项 + I项 return VKp * filt_velocity + VKi * velocity_sum; }</span></pre> <p>OpenMV视觉转向环(PD控制):</p> <pre><span style="font-size:16px;">float turn_mv_x_PID_value(float Target_x, float True_x) { // 偏差计算:实际值 - 目标值(注意符号定义) mv_x_err = True_x - Target_x; // 微分项计算:当前偏差 - 上次偏差 err_difference_x = mv_x_err - last_mv_x_err; // 更新历史值 last_mv_x_err = mv_x_err; // PD控制器输出:P项 + D项 return MKp * mv_x_err + MKd * err_difference_x; }</span></pre> <p>控制参数:</p> <p style="padding-left:40px;">速度环参数 (VKp=-400, VKi=-1.7)    快速响应速度变化,缓慢消除稳态误差,避免振荡</p> <p style="padding-left:40px;">视觉转向环参数 (MKp=15, MKd=430)     保证转向响应性,强烈抑制超调,提高转向平滑性,无积分项避免在视觉跳动时产生累积误差</p> <div>参数整定:</div> <div> <p style="padding-left:40px;">先P后I最后D:先调Kp至临界振荡,然后加入Ki、Kd</p> <p style="padding-left:40px;">速度环:先保证速度稳定,再优化动态响应</p> <p style="padding-left:40px;">转向环:在直道调试Kp,在弯道调试Kd</p> </div> <p>典型问题:</p> <p style="padding-left:40px;">振荡:降低Kp或增加Kd</p> <p style="padding-left:40px;">响应慢:增加Kp或降低滤波系数</p> <p style="padding-left:40px;">稳态误差:适当增加Ki(需谨慎)</p> <p style="padding-left:40px;">超调大:增加Kd或降低Kp</p> <p> </p> <p>中断服务函数框架:</p> <pre><span style="font-size:16px;">void EXTI9_5_IRQHandler(void) { // 10ms周期执行的控制逻辑 // 传感器数据采集与处理 // PID控制算法执行 // 电机输出计算与加载 EXTI_ClearITPendingBit(EXTI_Line5); // 清除中断挂起位 }</span></pre> <p style="line-height:1.8;">具体见源码</p> <p style="line-height:1.8;"> </p> <p>串口通信:</p> <p style="padding-left:40px;">ASR Pro语音 → 0x50/0x51 → asrpro_start_flag → 主控制使能</p> <p style="padding-left:40px;">OpenMV视觉 → (x,θ)数据 → pwm_mv_flag → 视觉巡线使能</p> <p style="padding-left:40px;">                                 ↓</p> <p style="padding-left:40px;">                         PID控制器 → 电机差速输出</p> <p style="padding-left:40px;"><strong>USART1</strong>:<br>语音指令通道(ASR Pro → STM32)</p> <p style="padding-left:40px;">单字节指令协议,简单高效</p> <p style="padding-left:40px;">实时控制:LED开关、巡线启停</p> <p style="padding-left:40px;"><strong>USART2</strong>:<br>视觉数据通道(OpenMV → STM32)</p> <p style="padding-left:40px;">5字节定长数据包协议</p> <p style="padding-left:40px;">双帧头+帧尾校验,保证数据可靠性</p> <p style="padding-left:40px;">包含坐标数据和巡线状态信息</p> <pre><span style="font-size:16px;"> /*串口2中断服务程序(接收OpenMV视觉数据包-5字节协议)*/ void USART2_IRQHandler(void) { static int i=0; if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) { openmv_data[i++] = USART_ReceiveData(USART2); if(openmv_data[0]!=0xa3) i=0; // 帧头0xA3 if((i==2)&&(openmv_data[1]!=0xb3)) i=0; // 帧头0xB3 // 完整数据包接收完成判断 if(i==5) { i = 0; if( Data_test(openmv_data) ) { bottom_x = openmv_data[2]; // 第3字节: 路线下端x坐标(0-79正常值, 200为丢失标志) theta = openmv_data[3]; // 第4字节: 路线角度(-90~+90度) if(bottom_x==200 && theta==200) //表示巡线丢失 { pwm_mv_flag=0; // 禁用巡线 } else { pwm_mv_flag=1; // 启用巡线 } } } } } /*包完整性校验函数*/ int Data_test(int data[]) { if(data[0]!=0xa3) return 0; // 帧头1 if(data[1]!=0xb3) return 0; // 帧头2 if(data[4]!=0xc3) return 0; // 帧尾 return 1; }</span></pre> <p style="line-height:1.8;">通过分层协议设计和严格的数据校验,确保语音与视觉控制的实时性和可靠性</p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;"> </span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*6、BOM清单</h3> <hr> <p style="line-height:1.8;">模块的话原理图里都标注名字了,都是常用模块,自行购买<img src="//image.lceda.cn/pullimage/Ic2U8qEj4aJ4rXehozsEVVkVMSMbhDuJtpRmS0s6.png" width="1200" height="343" alt="Ic2U8qEj4aJ4rXehozsEVVkVMSMbhDuJtpRmS0s6.png"></p> <h3 style="line-height:1.8;">*7、大赛LOGO验证</h3> <hr> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/9KUTieQVj2hmkx4dQba3wk9SLtzOINRygKcYpu1c.jpeg" width="272" height="244" alt="9KUTieQVj2hmkx4dQba3wk9SLtzOINRygKcYpu1c.jpeg"></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 8、演示您的项目并录制成视频上传</h3> <hr> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="font-size:14px;"><a href="/posts/42551e8f2f2548cabc1c36626a42da94" target="_blank">前往查看更多详情 ></a></span></p> <p style="line-height:1.8;"> </p>

文档

BOM

暂无

附件

附件名 下载
BOM_主控板_Schematic1_2025-10-15.xlsx
源码(stm32+openmv).rar
Gerber_PCB_控制板.zip
Gerber_PCB_供电板.zip

评论(2)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
立创电赛 回复
<p>[emojis:打招呼]加油更新,记得上传logo验证实物图哦</p>
立创电赛 回复
<p>需发布工程</p>
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow