室内机器人地图模块实操:栅格建图、代价地图与导航避障

做机器人项目这几年,地图模块给我的印象可以用四个字概括:又爱又恨。爱它,是因为形态直观,一张栅格图导出来,客户和老板都能看懂场景结构;恨它,是因为只要导航、定位出了问题,第一个被怀疑的就是这张图,而真把图拆开查一遍,往往发现源头在坐标没对齐、时间戳乱掉、更新策略不合适这些不起眼的环节。lingbot-map 就是我们为一个室内服务机器人项目单独整理出来的地图模块,名字听起来只是个地图库,实际上它串起了从传感器原始数据、到占据栅格构建、再到路径规划使用的整条链路。这篇文章会完整复盘我们为什么把它独立成一个模块、地图格式怎么选、建图和导航的工程细节怎么落地,以及跑测试时踩过的几个真实坑,适合正在做室内机器人导航、或者准备自己维护一套地图数据的工程师参考。

1. 立项动机:从“会画图”到“能导航”的边界重构

1.1 最初的场景其实特别朴素

项目起点很简单:某室内配送机器人要在办公园区里完成从充点桩到几个固定工位的物资配送,工作区域大概几百平方米。最初设想的方案非常直接——机器人在部署当天用激光雷达原地转一圈,把墙和障碍物的轮廓描出来,存成一张图,后面导航就按这张图走。听起来一天就能搞定,甚至连专职地图工程师都不用配。

真正动手才发现,这张“图”远不止是一张图。导航程序要判断机器人当前处于哪个房间,需要地图提供参考;路径规划要拐过走廊转角,需要地图里有清晰的空闲区域和障碍区域;就算部署完成,工位附近的椅子被人挪到通道上,也得靠地图层面感知变化。地图一旦被当成静态图片对待,整个系统后面就会处处受制。可以说,地图是所有上层模块的“公共底账”,底账记乱了,后面每一本账都会对不上。

1.2 把它做成独立模块的三个具体理由

把 lingbot-map 从项目代码里拆出来,不是因为“代码结构优雅”之类的原因,而是有三个很现实的问题逼着我们做了这个决定。

第一,多个上层模块都依赖地图,但地图自己没有生命周期管理。定位模块要做地图重定位、导航模块要加载地图做规划、避障模块要把动态障碍标到地图上,谁来负责地图的初始化、更新和销毁,最初完全没有归属。每个人都在自己的模块里各自加载一份地图,参数稍微不一致,地图对不上,问题就变成“谁的地图才是真的”。

第二,离线建图和在线运行这两条路径,对地图的格式、坐标系、精度要求并不一样。部署阶段我们习惯离线建图、反复调优;运行时则需要快速加载、实时更新局部区域。如果每个人都按自己的方式读图写图,后面改一版地图数据结构,所有代码都要跟着改一遍,维护成本直线上升。

第三,地图数据必须可调试、可回放、可评估。第一次测出机器人撞墙时,我们发现撞的位置在图上完全看不出来,因为既没有保存当时的传感器日志,也没有办法把机器人的估计轨迹叠加到地图上。那天晚上我们对着静态地图看了一小时,最后还是靠猜才定位到是局部地图更新策略的问题。为了不再靠猜,lingbot-map 的边界就定下来了:它负责从传感器流生成、更新、存储地图数据,对外提供统一的查询接口,让定位、规划、避障都从同一个入口访问地图。

这也是我后来反复跟团队强调的一句话:地图模块的边界,不是“画出一张图”,而是“让所有模块在同一个空间认知上协作”。列表里四个上层依赖,恰好说明了这个模块的实际分量。

上层模块需要的核心能力典型的失败表现
定位给定机器人位姿,返回附近栅格占用特征地图局部模糊或空白,重定位找不到正确位置
全局规划给定起点终点,返回不碰障碍的路径路径穿墙、绕远、贴着障碍物走
局部避障实时返回障碍物存在的局部区域明明有障碍物,机器人刹车晚或者根本没看到
地图维护支持局部区域刷新,而不是整图覆盖部署后环境轻微变化,被迫整图重建

2. 地图模型选型:为什么放弃纯拓扑,改做栅格加语义分层

2.1 三种地图模型的直观对比

地图表达方案不少,主流的有三类:拓扑地图、特征地图、占据栅格地图。拓扑地图把环境抽象成节点和连线,比如房间A连着走廊B、走廊B通向房间C,适合做跨区域的路径决策,但对房间内部的精确形状基本没有表达能力。特征地图把墙、门、柱子用几何元素描述,内存占用小,但对传感器噪声和动态环境很敏感,一帧激光数据里多了一个行人点,就可能被拟合成一堵假墙。占据栅格地图则是把环境切成一格一格,每个格子记录占用、空闲还是未知,通俗地说,它像一张低成本的像素画,简单、直观、好更新。

当时有同事觉得拓扑地图更“聪明”,但项目真正跑起来之后,占据栅格的优势非常明显:激光雷达的每一帧数据都能直接落进对应格子做概率更新,不需要额外拟合几何模型;导航模块判断“这个通道够不够宽”,直接查栅格区域就行;环境里偶尔出现的动态物体,也能通过局部栅格的更新被纳入避障决策。所以我们最终没有用纯拓扑,也没有用纯特征地图,而是以占据栅格为底图,在它外面包一层拓扑关系,用来表达“哪个区域属于哪个房间”。这种混合结构既保住了底层精度,又给上层语义留了口子,实际效果比单用任何一种都要稳。

2.2 分辨率、内存与精度的三角关系

选占据栅格之后,第一个要拍板的是分辨率。分辨率太粗,门缝、桌腿、通道边界都看不清;分辨率太细,内存和计算量线性上升,单帧点云更新耗时也跟着涨。我们当时先做了一版估算:假设工作区域是 120m × 100m,选 5cm 分辨率,网格数就是 (120 / 0.05) × (100 / 0.05) = 4,800,000 个。每个格子用 2 字节存对数赔率,单张底图约 9.6MB,奔腾年代级别的老硬件也能扛得住。如果把分辨率改成 2cm,网格数直接跳到 30,000,000 个,存储涨到 60MB,而且每次激光束扫到的格子数量变多,单帧更新耗时几乎翻倍。

所以我们把 5cm 定为默认分辨率,在需要对接口精度要求很高的小面积区域(比如充电桩对接位置)再单独开一块 2cm 的高精度局部图。这个取舍没有绝对对错,但它需要在建图之前就想清楚。分辨率一旦定下来,后续所有接口、缓存策略、可视化工具都要跟着这个假设走,中途改分辨率,等于把底图重做一遍。

坐标系的约定同样要早定。lingbot-map 使用部署现场某个固定点为原点,x 轴对准走廊主方向,y 轴与之垂直。不同传感器之间的外参误差如果没校准干净,一帧数据就可能把所有格子带偏。我们专门写了一个标定脚本,把激光雷达相对车体的安装偏移量测量好并写入配置。很多人觉得这是小事,等导航时发现地图横向漂移十几厘米才回头查,一查就得重做整个建图流程。坐标系的统一,是地图能被多个模块信任的前提。

3. 建图主链路:预处理、概率更新与回环修正的取舍

3.1 点云预处理与时间戳对齐

lingbot-map 的建图链路,第一步是传感器数据预处理。激光雷达输出的每一帧点云,首先要修正由于车体运动造成的点云畸变——低速直线行驶时还好,一旦急转或经过颠簸地面,一帧扫描在几十毫秒内采集完成,车体位置早已发生变化,直接画进地图就会形成边缘扭曲。我们的做法是用里程计内插出每个激光点的采集时刻对应的位姿,再把点云重新投影到扫描起始时刻的坐标系下,从源头消掉运动畸变。

接下来是时间戳对齐。雷达、里程计、IMU 三路数据的采集频率各不相同,而频率低的往往更关键。我们给每个传感器数据包都打了硬件时间戳,在预处理阶段把最接近雷达帧时刻的里程计数据做线性插值,而不是简单用最近一帧。这个细节决定了后面所有建图步骤的稳定性——时间戳对不齐的时候,地图上会出现类似“重影”的双层轮廓,肉眼很难一眼看出原因,但导航时机器人就会犹豫到底该躲哪条边。这里没有捷径,只能老老实实对齐每一帧。

3.2 占据栅格的概率更新逻辑

预处理之后就是核心的栅格更新。占据栅格地图并不是直接存“这个格子是障碍还是空闲”,而是存一个概率的“对数赔率”,术语叫 log-odds。为什么要绕这一圈?因为传感器有噪声,单次观测不能完全改变一个格子的状态,但多次观测的证据可以累积;用加法的形式做累积,比反复做概率乘法方便得多,还能设定上下限,避免某个格子的状态被少数异常帧带偏。

代码上可以缩成一个很短的更新函数:

def update_cell(log_odds, state, sensor_config): if state == "occupied": log_odds += sensor_config.l_occ elif state == "free": log_odds += sensor_config.l_free return min(max(log_odds, sensor_config.lo_min), sensor_config.lo_max)

建图过程中,我们把打到障碍物的格子标记为 occupied,把激光束穿过的那一段格子标记为 free。这里有个容易被忽略的点:激光束和障碍物之间经过的格子,不能一刀切全部设置成极强的 free,而应根据“格子离雷达越近,观测信息越可靠”的原则设置不同的更新步长。近处格子更新强度高,远处格子更新强度低,否则远处噪声误差会积累成莫名其妙的空洞。我们调参时专门在走廊尽头放了一排纸箱,反复建图验证远处格子的阈值行为,才找到一个比较合理的衰减系数。

3.3 回环修正与误检的平衡

单帧点云要落到栅格地图里,靠的是机器人位姿。位姿最初由轮式里程计累积,但轮子打滑、地面不平都会让位姿漂移。漂移在小区域不明显,走得远就会出现“地图拼接错位”——同一面墙看起来像两段错开的线段。解决这个问题的标准方式是回环检测与位姿图优化:当机器人回到曾经访问过的区域时,扫描匹配会发现当前观测和已有地图高度一致,这个“一致性”反过来就能修正此前累积的所有位姿偏差。

我们实现回环检测时,没有把所有历史帧都拿来匹配,那样性能完全扛不住。做法是每隔一段距离保存一个关键帧,当新关键帧和某个旧关键帧距离小于设定阈值、且两者之间没有直接连通时,触发一次匹配。匹配成功后,把回环约束丢给位姿图优化器,重新分配关键帧位姿,再把这些位姿反馈到栅格地图的坐标变换上。要提醒的是,回环不要开得太激进,否则两条相似的平行走廊会误判成同一区域,反而把地图拉坏。这个部分我们前后调了两周,最终选择“宁可漏掉真回环,也不让假回环混进来”,效果比追求高召回更好。

4. 导航侧集成:代价地图分层与 A* 落地的工程细节

4.1 代价地图为什么要分层

建图完成只是第一步,真正导航时,机器人看的不是那张静态底图,而是一张动态更新的代价地图。代价地图可以理解成在底图之上叠加多层信息:静态层来自 lingbot-map 构建好的离线栅格图,负责告诉机器人墙在哪里;障碍层来自实时激光雷达点云,负责告诉机器人当前有什么东西出现;膨胀层则是把障碍物向外“吹”一圈,让机器人始终和真正的障碍物保持安全距离。

之所以要分层,是因为不同层的信息生命周期差异很大。墙不会突然消失,静态层可以长期保存;一个行人站在走廊里,可能几秒后就走开了,障碍层必须在几百毫秒内反映变化;膨胀半径又取决于机器人当前速度和制动距离,速度越快膨胀半径越大。把三者混在一张图里维护,必然出现要么旧信息清不掉、要么新信息频繁覆盖有效底图的尴尬局面。分层之后,各层有自己的更新节奏,遇到行人突然靠近,机器人也能快速感知并重新规划绕行路线,这套结构我们从建图第一天就定了,后面几乎没返工。

4.2 全局路径规划的工程细节

静态底图建好之后,路径规划要用它找出一条从A到B的通道。我们的全局规划器基于 A* 算法做了工程化封装。算法本身不复杂,但工程落地有两个坑很值得说。

第一,格子之间的移动代价不能只看欧氏距离。如果机器人只能前进和差速转向,那么斜对角移动和直线移动的代价差异就不一样;如果机器人还有最小转弯半径,转弯动作本身也要计入代价。我们的实现里,对角移动代价设为直线移动的 1.414 倍,同时给紧贴障碍物的格子加一笔惩罚项,路径就不会贴着墙根走得太难看。后来在仿真里对比过,加上惩罚项之后,路径平均离障碍物的距离多出将近 20%,机器人的急转次数也明显减少。

第二,A* 扩展时会走斜线。如果斜线恰好擦过一个障碍格子的角,路径视觉上没问题,但机器人实际通过时车体会撞到墙角。因此每次加入新节点时,要检查这条斜线上的四个邻居格子里是否有两个同时被占据,如果是,就不允许斜向跨越。这个检查很琐碎,但少了它,实测十次有八次会卡在障碍角上,不是什么高深算法问题,纯粹是细节决定成败。

4.3 局部避障与速度约束

全局路径是静态底图上算出来的,但运行环境里总有地图上没有的动态障碍物。局部规划器要做的事,是在全局路径指引下,结合实时代价地图,输出每一时刻机器人该用的线速度和角速度。

我们采用动态窗口法的思路:在允许的速度范围内采样若干组“线速度 + 角速度”,按当前位姿向前模拟一小段,然后从模拟轨迹里选一条距离目标近、距离障碍远、和全局路径方向最一致的来执行。速度约束这里给一个参考值:我们把最大线速度设成 1.2m/s,最大角速度 0.8rad/s,模拟时长 1.5s。速度设得太高,局部规划器一看到远处有障碍就要急刹,反而频繁停下来;设得太低,配送效率完全不行。膨胀层半径设为车体半径加 10cm 安全余量,再额外留 5cm 给定位误差。这几个参数是调了一个下午才定下来的,如果你的项目参数差别大,一定要从车体尺寸和制动能力出发重新推算,不能直接抄。

5. 实测踩坑:地图能看却不能用时,我们排查出的三类问题

5.1 激光雷达高度带来的“鬼影障碍”

第一次把 lingbot-map 建出来的图加载进导航模块测试时,机器人总在几个固定位置莫名其妙地停下来,现场看起来明明很空旷。我们把实时点云叠加到地图上一看,发现那些位置凭空多了一圈弧形障碍物。排查下来,根因是激光雷达安装高度偏低,扫到了地面坡坎边缘和排水沟盖板,这些点在建图时被当成障碍物写进了底图,导航模块自然不敢穿过去。

这类问题只靠调地图参数很难彻底解决。我们最终从两个方向入手:一是调高雷达安装位置并略微上仰,让扫描平面避开低矮的地面起伏;二是在点云预处理环节加高度过滤,只保留地面以上 5cm 到 80cm 范围内的点。高度过滤听起来简单,但它要求我们清楚工作空间里哪些障碍物可能超过 80cm、哪些必须保留,这一步需要和机械设计的人反复确认。这个坑给我的收获是:地图质量的问题不一定在地图算法里,一张干净地图往往来自传感器安装和前置约束层面的严格把控。

5.2 回环误检把地图拉成“手风琴”

在办公走廊区测试时,我们发现机器人绕回起点附近时,整张地图的走廊形态会突然错动,像手风琴被拉扯了一下。第一次遇到时还以为是回环约束加少了,于是提高回环触发频率,结果地图反而更乱。后来我们回看关键帧匹配日志,才发现两条相距很近的平行走廊被反复误匹配——局部形状几乎一样,但在全局坐标系里并不是同一个地方。

解决办法有两个方向:一是在回环匹配前增加粗匹配验证,用语义层的“机器人当前应该在哪个区域”来排除明显不可能的匹配;二是对匹配得分设置更严格的阈值,宁可漏掉真回环,也不让假回环进入优化。我们权衡之后选了后者,把回环匹配分数阈值提升了约 30%。代价是长距离建图时偶尔出现细微累积误差,但总比整张地图错动级别的灾难好得多。这件事给我的教训是:回环检测不是阈值越低越好,它和误检率强相关,必须按地图复杂度去调参。

5.3 地图存储:别只存一张图就收工

建图完成后,我们最初的做法是把栅格地图直接导出成一张灰度图片存进文件夹就完事。直到有一次需要回到几周前的某个版本,才发现灰度图根本回不去——分辨率、原点坐标、建图时的传感器配置全丢了。后来我们把地图存储格式重新设计成“图片文件 + 元数据文件”的结构。元数据文件里记录分辨率、地图原点在地图坐标系中的位置、建图日期、采集轨迹摘要,以及关键参数配置,比如雷达高度、扫描频率、回环阈值等。

这份元数据看似不起眼,后续却帮了大忙。有一次客户现场反馈“机器人找不到路了”,我们把地图元数据和实时定位数据比对,发现是现场重新装修、墙面位置变了,和底图对不上。元数据里清晰的建图时间让我们快速判断出“这张图已经过期”,而不是对算法瞎折腾。建议所有把机器人地图当长期资产的项目,从第一天就把元数据字段设计好,不然后面补数据一定比重新建图更痛苦。

6. 落地清单与经验沉淀

6.1 给团队的一页纸 checklist

如果前面的内容太长,可以直接把我们沉淀下来的一页纸清单拿去用。这些条目每一条都对应真实踩过的坑,不是纸上谈兵:

  • 建图前确认坐标系定义、传感器外参、雷达安装位置和扫描平面高度;
  • 记录地图元数据:分辨率、原点、坐标系、传感器配置、建图时间;
  • 地图更新使用对数赔率形式,设定上下限,避免单帧噪声污染;
  • 回环检测阈值按场景标定,谨防相似环境误匹配;
  • 导航前把离线底图、实时障碍层、膨胀层分开,各自管理生命周期;
  • 全局路径 A* 要注意斜角障碍检查和移动代价,不能只算直线距离;
  • 局部规划器参数按车辆制动能力和车体尺寸推算,不要直接抄默认参数;
  • 每次建图保存原始传感器日志,便于后续复现和调试。

6.2 我最后悔没早点做的两件事

回顾 lingbot-map 的整个推进过程,最让我后悔的是没有尽早做一个地图可视化调试工具。早期建图、导航、定位的人各看各的数据,定位的人说地图不对,地图的人说定位飘了,谁也说服不了谁。后来把地图、机器人实时位姿、规划路径、代价膨胀区域叠到同一个窗口里回放,很多争执当场就平息了。可视化工具本身不产生算法价值,但它能让复杂系统里的人快速对齐问题,这比任何参数优化都见效。

第二个体会是地图模块的接口设计要尽早统一。我们早期对“查询栅格占用状态”这个接口用过好几种表达方式,有的返回概率值,有的返回 0/1 布尔值,有的返回“自由空间/未知/障碍”枚举,每次对接新模块都要做转换。后来 lingbot-map 统一成只返回一个连续的可占用度,由使用方自行决定阈值,接口一下子清爽很多。如果现在让我重新排序优先级,我会把“统一接口”放在“调通算法”前面——接口决定了整个系统能走多远,算法决定的是走多快,而多数团队真正缺的恰恰是前者。

相关新闻

技能管理:把个人能力变成可复利、可迁移的体系

技能管理:把个人能力变成可复利、可迁移的体系

聊聊 skills:如何把你的本事变成一套可复利、可管理、可迁移的体系这么多年我带过不少人,也见过太多人把"技能"挂在嘴边,但真要问他"你会什么",他能说出一堆名词,却说不清每一项到底值多少钱、能解…

2026/10/22 14:41:27 阅读更多 →
OCR在数字化转型中的落地实践:从发票识别到降本增效

OCR在数字化转型中的落地实践:从发票识别到降本增效

这些年帮企业做数字化落地,我观察到一个很有意思的现象:很多管理者一谈数字化转型,首先想到的是上ERP、建数据中台、搞BI大屏,投入动辄几百万,周期按年算。但真正在后期被高频使用、被一线员工认可、甚至能让财务和运营…

2026/10/21 4:27:47 阅读更多 →
Flutter鸿蒙化适配:用brotli压缩攻克网络传输与资源体积瓶颈

Flutter鸿蒙化适配:用brotli压缩攻克网络传输与资源体积瓶颈

做鸿蒙应用适配的时候,我最头疼的不是 Flutter 本身,而是流量和体积。业务代码写得再花哨,真正卡住用户体验的往往是资源体积和网络传输。尤其是在鸿蒙 HarmonyOS 上跑 Flutter,包体、首包资源、接口回包,每一项都会被…

2026/10/21 4:26:47 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →