<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-CN"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://fancy666888.github.io/feed.xml" rel="self" type="application/atom+xml"/><link href="https://fancy666888.github.io/" rel="alternate" type="text/html" hreflang="zh-CN"/><updated>2026-08-29T10:40:55+00:00</updated><id>https://fancy666888.github.io/feed.xml</id><title type="html">樊佳烁</title><subtitle>樊佳烁的个人学术主页，记录自动化、机器人、机器视觉与数学建模方向的学习过程、项目和论文成果。 </subtitle><entry><title type="html">从这里开始：为什么建立个人学术主页</title><link href="https://fancy666888.github.io/blog/2026/hello/" rel="alternate" type="text/html" title="从这里开始：为什么建立个人学术主页"/><published>2026-08-13T04:00:00+00:00</published><updated>2026-08-13T04:00:00+00:00</updated><id>https://fancy666888.github.io/blog/2026/hello</id><content type="html" xml:base="https://fancy666888.github.io/blog/2026/hello/"><![CDATA[<p>这是我的个人学术主页的第一篇记录。</p> <p>建立这个网站，是为了把分散在课程作业、实验文件、代码仓库和文档中的内容整理成一条可以回顾的成长轨迹。相比只在阶段结束时制作一份简历，我更希望持续记录问题是怎样提出的、方案为什么这样选择，以及实验结果如何改进了我的理解。</p> <h2 id="我会记录什么">我会记录什么</h2> <ol> <li>自动化专业课程中的重要概念与方法；</li> <li>项目从需求、设计到实验和复盘的完整过程；</li> <li>论文阅读中的问题、方法、结论与个人思考；</li> <li>编程、仿真、硬件调试和科研工具的使用经验。</li> </ol> <h2 id="接下来的计划">接下来的计划</h2> <ul> <li>补充真实个人简介与联系方式；</li> <li>整理已有项目，优先记录自己承担的工作和可验证结果；</li> <li>建立统一的论文阅读笔记模板；</li> <li>在每个阶段结束时更新一次经历与技能清单。</li> </ul> <p>这个网站会和我的学习过程一起成长。</p>]]></content><author><name></name></author><category term="研究随笔"/><category term="自动化"/><category term="实验记录"/><summary type="html"><![CDATA[记录网站的目标、内容边界和接下来的建设计划。]]></summary></entry><entry><title type="html">YOLO 实例分割复盘：可复现训练与半熟蓝莓错误分析</title><link href="https://fancy666888.github.io/blog/2026/yolo-segmentation-workflow-and-error-analysis/" rel="alternate" type="text/html" title="YOLO 实例分割复盘：可复现训练与半熟蓝莓错误分析"/><published>2026-07-25T07:14:28+00:00</published><updated>2026-07-25T07:14:28+00:00</updated><id>https://fancy666888.github.io/blog/2026/yolo-segmentation-workflow-and-error-analysis</id><content type="html" xml:base="https://fancy666888.github.io/blog/2026/yolo-segmentation-workflow-and-error-analysis/"><![CDATA[<p>2026 年 7 月，蓝莓视觉实验从“能够训练模型”进入“能够复现实验并解释错误”的阶段。我把标注转换、数据划分、训练参数、验证方式和错误分析整理成固定流程，并重点检查了模型对 <code class="language-plaintext highlighter-rouge">semi_ripe</code>（转色期蓝莓）的识别问题。</p> <h2 id="固定实验输入">固定实验输入</h2> <p>当前任务为三类别实例分割，类别顺序固定为：</p> <div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0 ripe
1 unripe
2 semi_ripe
</code></pre></div></div> <p>类别编号一旦确定就不能随意调整，因为 YOLO 标签只保存编号。实验使用固定随机种子将数据划分为训练、验证和测试集，并记录模型、图像尺寸、epoch、batch、设备与输出目录。</p> <h2 id="从-json-到可训练数据集">从 JSON 到可训练数据集</h2> <p>AnyLabeling/LabelMe 的多边形标注需要转换为 YOLO segmentation 格式。转换完成后，除了检查文件是否生成，还需要统计成功转换的图片数、每个 split 的图片数、各类别实例数以及异常多边形或未知类别。</p> <p>训练前我会抽样把转换后的多边形重新绘制到原图上。这样可以尽早发现坐标归一化、图片尺寸或类别映射错误，避免模型在错误标签上完成一次耗时训练。</p> <h2 id="训练结果不应只看一张曲线">训练结果不应只看一张曲线</h2> <p>一轮实验至少保存以下信息：</p> <ul> <li>数据来源与划分方式；</li> <li>模型和完整训练参数；</li> <li><code class="language-plaintext highlighter-rouge">best.pt</code> 与结果目录；</li> <li>box 和 mask 的 mAP50、mAP50-95；</li> <li>分类别指标与混淆矩阵；</li> <li>问题记录、结论和下一步。</li> </ul> <p>当精度不足时，应先检查数据与标注，再考虑提高输入分辨率或更换更大的模型。对小数据集而言，增加模型规模并不一定比补充困难样本更有效。</p> <h2 id="semi_ripe-错误归因">semi_ripe 错误归因</h2> <p>在一次 YOLO11s-seg 测试中，测试集共有 115 个 <code class="language-plaintext highlighter-rouge">semi_ripe</code> 真值实例。以类别正确且 mask IoU 不低于 0.75 为成功条件，47 个实例成功匹配，占 40.9%。</p> <table> <thead> <tr> <th>失败类型</th> <th style="text-align: right">数量</th> <th style="text-align: right">占全部 semi_ripe 实例</th> </tr> </thead> <tbody> <tr> <td>误分类</td> <td style="text-align: right">61</td> <td style="text-align: right">53.0%</td> </tr> <tr> <td>漏检</td> <td style="text-align: right">2</td> <td style="text-align: right">1.7%</td> </tr> <tr> <td>类别正确但 mask 质量不足</td> <td style="text-align: right">5</td> <td style="text-align: right">4.3%</td> </tr> <tr> <td>成功</td> <td style="text-align: right">47</td> <td style="text-align: right">40.9%</td> </tr> </tbody> </table> <p>61 个误分类实例几乎平均流向两端：30 个被判为成熟，31 个被判为未熟。这说明主要问题不是“看不到蓝莓”，而是转色阶段本身具有连续性，三分类标签与视觉特征之间存在模糊边界。</p> <p>距离分层也显示，30 cm 条件下成功率为 32.1%，低于 15 cm 条件下的 43.7%。这提示后续数据采集和评估需要同时考虑目标尺度、清晰度、遮挡与光照，而不能只比较总体准确率。</p> <h2 id="下一步实验">下一步实验</h2> <ol> <li>复核 <code class="language-plaintext highlighter-rouge">semi_ripe</code> 标注一致性，明确颜色过渡区的判定标准；</li> <li>增加不同地点、距离和光照下的转色期样本；</li> <li>尝试把成熟度从硬分类改为具有顺序关系的标签或连续指数；</li> <li>分别报告识别错误与 mask 几何误差，避免把两类问题混在一起；</li> <li>保持独立测试集，使用同一评估脚本比较后续模型。</li> </ol> <p>这次分析让我认识到，模型指标下降不一定意味着网络“没学会”。数据定义、标签边界和采集条件都可能是误差来源。把失败样本按原因分类，比单纯继续训练更多 epoch 更能指导下一轮实验。</p>]]></content><author><name></name></author><category term="项目日志"/><category term="计算机视觉"/><category term="实验记录"/><category term="机器人"/><summary type="html"><![CDATA[记录从标注转换、数据划分、YOLO11-seg 训练到 semi_ripe 错误归因的完整实验思路。]]></summary></entry><entry><title type="html">蓝莓实例分割与三维定位：从检测任务到采摘感知</title><link href="https://fancy666888.github.io/blog/2026/blueberry-instance-segmentation-and-3d-localization/" rel="alternate" type="text/html" title="蓝莓实例分割与三维定位：从检测任务到采摘感知"/><published>2026-07-24T11:32:10+00:00</published><updated>2026-07-24T11:32:10+00:00</updated><id>https://fancy666888.github.io/blog/2026/blueberry-instance-segmentation-and-3d-localization</id><content type="html" xml:base="https://fancy666888.github.io/blog/2026/blueberry-instance-segmentation-and-3d-localization/"><![CDATA[<p>2026 年 7 月，我重新梳理了蓝莓采摘机器人的视觉研究主线。前期目标检测能够回答“画面中有没有蓝莓”，但机械臂真正需要的是每一颗果实的轮廓、成熟度和三维位置。于是问题逐渐从目标检测转向实例分割与稳健三维定位。</p> <figure> <picture> <img src="/assets/img/projects/blueberry-detection-result.jpg" class="img-fluid rounded z-depth-1" width="100%" height="auto" title="真实枝叶背景下的蓝莓检测结果" loading="eager" onerror="this.onerror=null; document.querySelectorAll('.responsive-img-srcset').forEach(function (n) { n.remove(); });"/> </picture> </figure> <h2 id="为什么检测框还不够">为什么检测框还不够</h2> <p>蓝莓通常成簇生长，果实之间相互遮挡，叶片与枝条也会切割可见区域。矩形检测框容易包含相邻果实和背景，直接在框内取深度会受到叶片、空洞和边缘噪声影响。</p> <p>实例分割为每一颗果实输出独立 mask，可以把成熟度分类、深度估计和簇内计数都落实到实例级。它不只是更精细的可视化结果，而是从二维识别连接到三维操作的接口。</p> <h2 id="任务管线">任务管线</h2> <p>当前感知路线可以拆成四个阶段：</p> <ol> <li>对 RGB-D 图像进行时间同步和空间对齐；</li> <li>使用实例分割模型识别未熟、转色和成熟蓝莓；</li> <li>在 mask 内筛除无效深度与离群点，估计果实的稳健深度和三维质心；</li> <li>将相机坐标转换到机械臂坐标系，为接近和采摘提供目标点。</li> </ol> <p>基线模型需要在同一数据划分、输入分辨率和训练策略下比较。除了 mask AP、AP50 和 AP75，我还需要关注小目标表现、分类别指标、推理速度以及不同遮挡与距离条件下的定位误差。</p> <h2 id="蓝莓场景的特殊困难">蓝莓场景的特殊困难</h2> <ul> <li>果实小而密集，相邻实例边界不明显；</li> <li>果粉和高光会导致深度空洞或异常值；</li> <li>未熟、转色和成熟之间存在连续过渡，标签边界并不绝对；</li> <li>被遮挡果实的可见区域不一定等于真实几何中心；</li> <li>训练数据来自不同地点、光照和距离，需要防止划分泄漏。</li> </ul> <h2 id="当前研究判断">当前研究判断</h2> <p>单纯“更换或轻微改进 YOLO 检测蓝莓成熟度”很难形成有说服力的研究贡献。更值得推进的是把问题绑定到采摘需求：利用实例 mask 提高深度估计稳定性，处理果粉高光造成的深度缺失，并研究遮挡条件下三维质心的校正。</p> <p>现阶段这些内容仍属于研究方案，不应写成已经完成的成果。接下来需要用实际数据完成基线比较、消融实验和三维真值测量，才能判断哪一种方法真正有效。</p> <h2 id="下一步">下一步</h2> <ul> <li>核对 RGB-Depth 对齐、成熟度标签和数据划分；</li> <li>统一复现 Mask R-CNN、YOLOv8-seg 与 YOLO11-seg 等基线；</li> <li>建立遮挡、距离和光照分层测试集；</li> <li>设计三维定位真值采集与手眼标定流程；</li> <li>用定位误差和机械臂接近成功率验证方法价值。</li> </ul> <p>这次整理让我更清楚地区分了“模型能识别”与“系统能采摘”之间的距离。感知模块最终需要服务于动作，而不是停留在一张带框的结果图上。</p>]]></content><author><name></name></author><category term="研究随笔"/><category term="机器人"/><category term="计算机视觉"/><category term="论文阅读"/><category term="实验记录"/><summary type="html"><![CDATA[梳理蓝莓采摘机器人感知主线，说明为什么从目标检测进一步转向实例分割、稳健深度和三维定位。]]></summary></entry><entry><title type="html">RealSense D435i 实践：如何采集可用的蓝莓 RGB-D 数据</title><link href="https://fancy666888.github.io/blog/2026/realsense-d435i-rgbd-data-collection/" rel="alternate" type="text/html" title="RealSense D435i 实践：如何采集可用的蓝莓 RGB-D 数据"/><published>2026-05-26T12:38:28+00:00</published><updated>2026-05-26T12:38:28+00:00</updated><id>https://fancy666888.github.io/blog/2026/realsense-d435i-rgbd-data-collection</id><content type="html" xml:base="https://fancy666888.github.io/blog/2026/realsense-d435i-rgbd-data-collection/"><![CDATA[<p>2026 年 5 月，蓝莓采摘机器人项目进入 RGB-D 数据采集阶段。我们的目标不只是获得彩色照片，而是建立一套能支持成熟度识别、实例分割和三维定位的数据：每一帧都要有对齐的彩色图、深度图、相机参数和采集条件记录。</p> <figure> <picture> <img src="/assets/img/projects/blueberry-rgbd-system.png" class="img-fluid rounded z-depth-1" width="100%" height="auto" title="D435i 彩色与深度图同步预览" loading="eager" onerror="this.onerror=null; document.querySelectorAll('.responsive-img-srcset').forEach(function (n) { n.remove(); });"/> </picture> </figure> <h2 id="先明确相机要回答的问题">先明确相机要回答的问题</h2> <p>在真实种植环境中，我们需要验证五件事：RGB 图像能否看清果实；深度图在果粉、高光和边缘处是否稳定；模型能否区分未熟、转色和成熟蓝莓；遮挡、距离与光照会造成多大影响；采集结果能否形成可复用的数据集。</p> <p>这使采集工作从“多拍照片”变成了有变量、有检查点的实验。</p> <h2 id="接入与对齐">接入与对齐</h2> <p>相机通过 USB 3.0 连接，RGB 与深度流使用统一的分辨率和帧率。程序读取帧后，将深度图对齐到彩色图坐标系，并导出彩色相机内参、深度尺度和曝光等元数据。</p> <p>对齐十分关键：如果 RGB 中的蓝莓轮廓和深度图中的位置不一致，后续即使实例分割准确，也会取得错误的深度值。</p> <h2 id="数据不只是两张图片">数据不只是两张图片</h2> <p>每个采集 session 同时记录以下条件：</p> <table> <thead> <tr> <th>维度</th> <th>记录示例</th> </tr> </thead> <tbody> <tr> <td>拍摄距离</td> <td>25、35、50、70 cm</td> </tr> <tr> <td>视角</td> <td>正视、侧视、俯视、低角度</td> </tr> <tr> <td>光照</td> <td>散射光、直射光、背光、阴影</td> </tr> <tr> <td>成熟度</td> <td>未熟、转色、成熟、混合果簇</td> </tr> <tr> <td>遮挡</td> <td>无遮挡、叶片遮挡、果实互遮、严重遮挡</td> </tr> </tbody> </table> <p>这些元数据可以在模型评估时把错误按场景分层，而不是只报告一个总体指标。</p> <h2 id="深度质量检查">深度质量检查</h2> <p>蓝莓表面的果粉与镜面反光可能造成深度空洞，果实边缘也容易出现混合像素。因此我不能直接取检测框中心的单点深度，而需要检查有效深度比例、空洞率和不同距离下的误差。</p> <p>后续定位流程计划采用实例 mask 内的稳健统计，例如中值深度和离群点剔除，再结合相机内参将像素坐标反投影到三维坐标：</p> \[X=\frac{(u-c_x)Z}{f_x},\qquad Y=\frac{(v-c_y)Z}{f_y}.\] <h2 id="目录和备份同样属于实验设计">目录和备份同样属于实验设计</h2> <p>每一帧保存 <code class="language-plaintext highlighter-rouge">color.png</code>、16 位 <code class="language-plaintext highlighter-rouge">depth.png</code>、深度可视化图和 <code class="language-plaintext highlighter-rouge">meta.json</code>；全局保存相机内参与 <code class="language-plaintext highlighter-rouge">dataset_index.csv</code>。原始数据在采集当天完成检查与备份，后续清洗和标注只处理副本。</p> <h2 id="阶段认识">阶段认识</h2> <p>这次实践让我意识到，三维视觉项目的瓶颈往往不只是模型。相机参数、坐标对齐、现场变量、文件结构和真值测量共同决定了实验是否可信。只有先建立稳定的数据链路，后面的实例分割和机械臂定位才有可靠基础。</p>]]></content><author><name></name></author><category term="项目日志"/><category term="自动化"/><category term="机器人"/><category term="计算机视觉"/><category term="实验记录"/><summary type="html"><![CDATA[从相机接入、RGB-Depth 对齐到现场变量设计，记录蓝莓采摘项目的 RGB-D 数据采集方法。]]></summary></entry><entry><title type="html">让工程资料可复现：标注、AI 辅助开发与数据管理</title><link href="https://fancy666888.github.io/blog/2026/reproducible-engineering-toolchain/" rel="alternate" type="text/html" title="让工程资料可复现：标注、AI 辅助开发与数据管理"/><published>2026-04-14T04:20:49+00:00</published><updated>2026-04-14T04:20:49+00:00</updated><id>https://fancy666888.github.io/blog/2026/reproducible-engineering-toolchain</id><content type="html" xml:base="https://fancy666888.github.io/blog/2026/reproducible-engineering-toolchain/"><![CDATA[<p>这组记录始于 2026 年 4 月，并在 5—7 月随着蓝莓 RGB-D 项目持续补充。相比单独学会一个软件，我更关心怎样让数据、标注、代码和实验记录能够被自己或团队成员再次复现。</p> <h2 id="anylabeling先隔离环境再开始标注">AnyLabeling：先隔离环境，再开始标注</h2> <p>我使用独立的 Conda 环境安装标注工具，避免把依赖直接装进 <code class="language-plaintext highlighter-rouge">base</code> 环境。基本流程包括创建环境、启动工具、加载自动标注模型、人工修正轮廓并保存 JSON。</p> <div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">conda</span><span class="w"> </span><span class="nx">create</span><span class="w"> </span><span class="nt">-n</span><span class="w"> </span><span class="nx">anylabeling</span><span class="w"> </span><span class="nx">python</span><span class="o">=</span><span class="mf">3.10</span><span class="w"> </span><span class="nt">-y</span><span class="w">
</span><span class="n">conda</span><span class="w"> </span><span class="nx">activate</span><span class="w"> </span><span class="nx">anylabeling</span><span class="w">
</span><span class="n">pip</span><span class="w"> </span><span class="nx">install</span><span class="w"> </span><span class="nx">anylabeling</span><span class="w">
</span><span class="n">anylabeling</span><span class="w">
</span></code></pre></div></div> <p>自动标注可以减少重复操作，但不能代替人工检查。实例边界、遮挡区域、类别名称和漏标都会直接影响后续训练，因此我把“模型建议—人工修正—格式检查”看成一个完整标注流程。</p> <h2 id="ai-辅助开发限定范围并保留验证步骤">AI 辅助开发：限定范围并保留验证步骤</h2> <p>在使用 VS Code 中的 AI 编程工具时，我逐渐形成了几个原则：先让工具阅读项目规则并提出计划；一次只处理一个小任务；明确允许修改的文件；完成后运行构建或测试；最后检查实际差异。</p> <p>AI 可以帮助理解代码、生成脚手架和分析报错，但输出仍需要验证。尤其是路径、依赖版本、接口名称和运行命令，不能因为文字看起来完整就直接相信。</p> <h2 id="数据管理网站把散乱文件变成可追踪的数据集">数据管理网站：把散乱文件变成可追踪的数据集</h2> <p>蓝莓项目中的 RGB、深度图、元数据和标注文件数量快速增长后，仅靠文件夹很难回答“哪些数据已检查”“哪些用于训练”“哪些是困难样本”。因此项目中建立了一个本地数据管理工具，用于：</p> <ul> <li>扫描室内和室外 RGB-D session；</li> <li>读取距离、光照、遮挡、成熟度和深度质量等字段；</li> <li>浏览 RGB 图与深度可视化图；</li> <li>管理质量状态、标注状态和论文分类标签；</li> <li>导出 AnyLabeling 标注批次并校验回传 JSON；</li> <li>汇总论文需要的统计表。</li> </ul> <figure> <picture> <img src="/assets/img/projects/blueberry-rgbd-system.png" class="img-fluid rounded z-depth-1" width="100%" height="auto" title="蓝莓 RGB-D 本地采集与数据管理界面" loading="lazy" onerror="this.onerror=null; document.querySelectorAll('.responsive-img-srcset').forEach(function (n) { n.remove(); });"/> </picture> </figure> <h2 id="最重要的数据保护原则">最重要的数据保护原则</h2> <p>原始数据应保持只读，清洗结果、导出副本、标注副本和数据库放在独立目录。这样即使筛选或导入流程出错，也能从原始数据重新生成结果。</p> <h2 id="阶段总结">阶段总结</h2> <p>工程工具的价值不在于安装了多少软件，而在于减少不可追踪的手工操作。独立环境、明确目录、固定类别顺序、批次清单、原始数据只读和可重复的检查命令，共同构成了比单次运行成功更重要的实验基础。</p>]]></content><author><name></name></author><category term="学习笔记"/><category term="自动化"/><category term="计算机视觉"/><category term="实验记录"/><summary type="html"><![CDATA[从 AnyLabeling 环境配置到 AI 辅助开发和 RGB-D 数据管理，整理一套可复现的工程工作流。]]></summary></entry><entry><title type="html">工创赛智能救援小车：从视觉原型到完整闭环</title><link href="https://fancy666888.github.io/blog/2026/intelligent-rescue-car-retrospective/" rel="alternate" type="text/html" title="工创赛智能救援小车：从视觉原型到完整闭环"/><published>2026-04-01T09:59:32+00:00</published><updated>2026-04-01T09:59:32+00:00</updated><id>https://fancy666888.github.io/blog/2026/intelligent-rescue-car-retrospective</id><content type="html" xml:base="https://fancy666888.github.io/blog/2026/intelligent-rescue-car-retrospective/"><![CDATA[<p>2026 年 4 月，我参与了校级工程实践与创新能力竞赛智能救援赛项。小车需要在模拟场地中自主识别不同颜色的目标，完成接近、夹取、转运和返回搜索。项目最终获得校级二等奖。</p> <figure> <picture> <img src="/assets/img/projects/rescue-car.jpg" class="img-fluid rounded z-depth-1" width="100%" height="auto" title="智能救援小车实物" loading="eager" onerror="this.onerror=null; document.querySelectorAll('.responsive-img-srcset').forEach(function (n) { n.remove(); });"/> </picture> </figure> <h2 id="早期方案先把感知与控制链路跑通">早期方案：先把感知与控制链路跑通</h2> <p>初期笔记围绕 K210/CanMV 展开。我把系统拆成颜色识别、串口通信、任务状态机和麦克纳姆轮底盘四部分，并先验证“摄像头发现目标—发送类别与偏差—底盘调整方向”这条最小链路。</p> <p>这个原型的价值不是成为最终方案，而是帮助我们尽早发现接口问题：视觉端应该输出什么信息、STM32 如何判断一帧数据是否完整、搜索与跟踪状态怎样切换、底盘运动方向与图像偏差怎样对应。</p> <h2 id="最终方案openmv--stm32f407">最终方案：OpenMV + STM32F407</h2> <p>经过现场调试与方案比较，最终系统使用 OpenMV4 H7 Plus 完成颜色阈值分割、色块筛选和目标定位，STM32F407 负责底盘控制、任务状态切换与执行机构控制。</p> <p>视觉模块输出目标类别、水平偏差和尺度信息；主控将其转换为底盘速度指令，再通过麦克纳姆轮逆运动学得到四个车轮的目标速度。编码器反馈和 PID 控制用于减小电机差异造成的跑偏。</p> <h2 id="状态机让复杂任务可调试">状态机让复杂任务可调试</h2> <p>我将连续任务分成搜索、跟踪、接近、夹取或转运、返回搜索等状态。每个状态只处理有限条件，并规定清晰的进入和退出规则。这比把所有判断都堆在主循环中更容易定位问题，也方便单独测试视觉、底盘和夹取机构。</p> <h2 id="调试中真正困难的部分">调试中真正困难的部分</h2> <ul> <li>摄像头画面中的左右偏差需要与底盘横移方向保持一致；</li> <li>四轮编号、安装方向和运动学公式必须统一；</li> <li>串口需要处理帧头、数据长度和异常数据，不能只读取单个字符；</li> <li>PID 参数要在实际负载下调整，空载结果不能直接代表比赛状态；</li> <li>识别成功不等于任务成功，接近距离、对准精度和夹取动作必须一起验证。</li> </ul> <h2 id="项目反思">项目反思</h2> <p>这次比赛让我第一次较完整地经历了从传感器输入到执行机构动作的系统联调。我学到的重点不只是 OpenMV 或 STM32 的某个函数，而是怎样定义模块边界、怎样用状态机组织任务，以及怎样通过逐层验证把一个复杂系统拆成可定位的问题。</p> <p><a href="/projects/intelligent-rescue-car/">查看项目详情与夹取演示</a></p>]]></content><author><name></name></author><category term="项目日志"/><category term="自动化"/><category term="控制"/><category term="机器人"/><category term="计算机视觉"/><category term="实验记录"/><summary type="html"><![CDATA[复盘智能救援小车从 K210 视觉原型到 OpenMV 与 STM32F407 最终方案的迭代过程。]]></summary></entry><entry><title type="html">现代优化算法学习：模拟退火、遗传算法与蚁群算法</title><link href="https://fancy666888.github.io/blog/2025/modern-optimization-algorithms/" rel="alternate" type="text/html" title="现代优化算法学习：模拟退火、遗传算法与蚁群算法"/><published>2025-09-02T07:29:02+00:00</published><updated>2025-09-02T07:29:02+00:00</updated><id>https://fancy666888.github.io/blog/2025/modern-optimization-algorithms</id><content type="html" xml:base="https://fancy666888.github.io/blog/2025/modern-optimization-algorithms/"><![CDATA[<p>2025 年 8—9 月准备数学建模时，我集中学习了模拟退火、遗传算法和蚁群算法。它们都不保证得到严格的全局最优解，但能在解析方法困难、搜索空间很大或目标函数不可导时寻找质量较好的可行解。</p> <h2 id="模拟退火允许暂时走向更差的解">模拟退火：允许暂时走向更差的解</h2> <p>模拟退火从一个初始解出发，不断产生邻域解。新解更好时直接接受；新解更差时，仍以一定概率接受：</p> \[P=\exp\left(-\frac{\Delta E}{T}\right).\] <p>温度较高时，算法具有更强的探索能力；温度逐渐降低后，搜索趋于稳定。其关键参数包括初始温度、降温系数、每个温度下的迭代次数和终止温度。它实现简单、对小规模组合优化很实用，但冷却过快容易陷入局部最优，冷却过慢又会增加计算时间。</p> <h2 id="遗传算法在种群中进行选择和变异">遗传算法：在种群中进行选择和变异</h2> <p>遗传算法同时维护一组候选解。每个候选解被编码为“个体”，再经历适应度评价、选择、交叉和变异。选择保留较好的方向，交叉组合已有信息，变异则维持种群多样性。</p> <p>它适合连续或离散参数优化，也能处理没有显式梯度的黑盒目标函数。不过，种群规模、交叉概率和变异概率都会影响收敛速度；如果适应度设计不合理，算法可能优化了错误的目标。</p> <h2 id="蚁群算法用信息素积累搜索经验">蚁群算法：用信息素积累搜索经验</h2> <p>蚁群算法常用于路径与组合优化。蚂蚁从可行邻域中选择下一节点时，同时考虑边上的信息素浓度和局部启发信息：</p> \[P_{ij}^{k}=\frac{\tau_{ij}^{\alpha}\eta_{ij}^{\beta}} {\sum_{s\in\mathcal{N}_{k}(i)}\tau_{is}^{\alpha}\eta_{is}^{\beta}}.\] <p>较短路径会留下更多信息素，使后续搜索更倾向于优质路径；信息素挥发则避免历史经验无限累积。它与路径结构结合自然，但在节点很多时计算量较大，而且信息素过快集中会导致早熟收敛。</p> <h2 id="三种算法怎样选择">三种算法怎样选择</h2> <table> <thead> <tr> <th>算法</th> <th>搜索对象</th> <th>优点</th> <th>主要风险</th> </tr> </thead> <tbody> <tr> <td>模拟退火</td> <td>单个当前解及其邻域</td> <td>结构简单，容易实现</td> <td>对降温策略敏感</td> </tr> <tr> <td>遗传算法</td> <td>一组候选解</td> <td>适用范围广，可并行评价</td> <td>参数较多，适应度设计关键</td> </tr> <tr> <td>蚁群算法</td> <td>多条逐步构造的路径</td> <td>适合 TSP、VRP 等路径问题</td> <td>收敛较慢，可能信息素停滞</td> </tr> </tbody> </table> <h2 id="这次学习带来的认识">这次学习带来的认识</h2> <p>我最初把这些算法理解成可以直接套用的“高级工具”，后来意识到真正重要的是解的表示、邻域或生成规则、目标函数、约束处理和停止条件。算法名称并不能替代建模：只有先把问题表达正确，搜索过程得到的结果才有意义。</p> <p>下一步我希望在同一组 TSP 数据上统一实现三种算法，记录最优值、平均值、运行时间和多次重复实验的方差，而不是只展示一次看起来不错的路径图。</p>]]></content><author><name></name></author><category term="学习笔记"/><category term="自动化"/><category term="控制"/><category term="实验记录"/><summary type="html"><![CDATA[从搜索机制、参数和适用问题出发，对比三类常见启发式优化算法。]]></summary></entry><entry><title type="html">STM32 入门阶段：从 GPIO 到 I²C、UART 与中断</title><link href="https://fancy666888.github.io/blog/2025/stm32-peripherals-and-communication/" rel="alternate" type="text/html" title="STM32 入门阶段：从 GPIO 到 I²C、UART 与中断"/><published>2025-07-16T03:17:59+00:00</published><updated>2025-07-16T03:17:59+00:00</updated><id>https://fancy666888.github.io/blog/2025/stm32-peripherals-and-communication</id><content type="html" xml:base="https://fancy666888.github.io/blog/2025/stm32-peripherals-and-communication/"><![CDATA[<p>这组笔记形成于 2025 年 6—7 月。当时我正在为电子设计竞赛补齐 STM32 基础，学习目标并不是记住所有 HAL 函数，而是理解单片机怎样感知外部信号、怎样控制执行器，以及不同模块之间怎样传递数据。</p> <h2 id="gpio先理解引脚的工作方式">GPIO：先理解引脚的工作方式</h2> <p>GPIO 是我接触 STM32 外设的起点。输出模式中，推挽输出可以主动输出高、低电平，适合 LED 和普通数字控制；开漏输出在输出高电平时呈高阻态，通常需要上拉电阻，便于多个器件共享信号线。</p> <p>输入模式则需要根据电路状态选择上拉、下拉或浮空输入。学习过程中我逐渐意识到，CubeMX 里每个配置选项都对应真实的电路行为：如果输入端没有稳定的默认电平，程序读到的状态就可能随机变化。</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">HAL_GPIO_WritePin</span><span class="p">(</span><span class="n">GPIOC</span><span class="p">,</span> <span class="n">GPIO_PIN_13</span><span class="p">,</span> <span class="n">GPIO_PIN_RESET</span><span class="p">);</span>
<span class="n">GPIO_PinState</span> <span class="n">state</span> <span class="o">=</span> <span class="n">HAL_GPIO_ReadPin</span><span class="p">(</span><span class="n">GPIOA</span><span class="p">,</span> <span class="n">GPIO_PIN_9</span><span class="p">);</span>
</code></pre></div></div> <h2 id="中断从轮询转向事件驱动">中断：从轮询转向事件驱动</h2> <p>轮询适合最初验证功能，但 CPU 会不断检查状态。外部中断则让主程序继续执行其他任务，只有触发条件到来时才进入中断服务流程。</p> <p>我在这一阶段重点理解了两组概念：</p> <ul> <li>EXTI 负责检测外部引脚事件；</li> <li>NVIC 负责管理中断使能和优先级。</li> </ul> <p>抢占优先级决定一个中断能否打断另一个中断，响应优先级用于安排同一抢占级别下的执行顺序。优先级数值越小，代表优先级越高。</p> <h2 id="uart适合点对点异步通信">UART：适合点对点异步通信</h2> <p>UART 不需要额外时钟线，通信双方需要约定波特率、数据位、停止位和校验方式。硬件连接时 TX 与 RX 交叉，且两端必须共地。</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">HAL_UART_Transmit</span><span class="p">(</span><span class="o">&amp;</span><span class="n">huart1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">tx_byte</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">HAL_MAX_DELAY</span><span class="p">);</span>
<span class="n">HAL_UART_Receive</span><span class="p">(</span><span class="o">&amp;</span><span class="n">huart1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">rx_byte</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">HAL_MAX_DELAY</span><span class="p">);</span>
</code></pre></div></div> <p>阻塞式收发适合调通链路，但在需要实时控制时，应进一步学习中断或 DMA 收发、数据帧设计、超时处理与校验机制。</p> <h2 id="ic用两根信号线连接多个器件">I²C：用两根信号线连接多个器件</h2> <p>I²C 使用 SDA 和 SCL，两条线通常采用开漏结构并通过上拉电阻保持高电平。一次典型通信由起始条件、地址与读写位、应答、数据传输和停止条件组成。需要特别注意：地址后的读写位中，<code class="language-plaintext highlighter-rouge">0</code> 表示写，<code class="language-plaintext highlighter-rouge">1</code> 表示读。</p> <p>与 UART 相比，I²C 更适合在同一电路板上连接多个低速外设，例如 OLED、传感器和存储器；UART 则更适合控制器之间或控制器与计算机之间的点对点通信。</p> <h2 id="阶段总结">阶段总结</h2> <p>这段学习让我建立了一个基本框架：GPIO 负责直接读写引脚，中断负责及时响应事件，UART 负责点对点通信，I²C 负责总线式外设连接。之后再接触编码器、电机驱动、摄像头或上位机时，我可以先判断它属于输入、输出、事件还是通信问题，再选择对应的外设和程序结构。</p>]]></content><author><name></name></author><category term="学习笔记"/><category term="自动化"/><category term="控制"/><category term="实验记录"/><summary type="html"><![CDATA[整理电赛备赛阶段对 GPIO、外部中断、I²C 和 UART 的基础理解，并把分散知识串成一条外设学习路线。]]></summary></entry></feed>