1. 项目概述当大语言模型真正开始“写控制软件”而不是“聊控制软件”ICRA 2026上这个标题一出来我第一时间在实验室白板上画了个三层结构图最底下是真实产线上的AGV小车、机械臂、无人叉车组成的物理集群中间层是传统运筹优化求解器跑出的调度指令流最上面——不是人类工程师写的C控制逻辑而是一个LLM调用工具链后自动生成的、可直接编译部署的嵌入式控制软件包。这不是概念演示标题里那个“工业级”三个字是经过某汽车零部件厂3个月实测验证的硬指标生成代码在ROS 2 Humble STM32H7平台上的实时性抖动83μs故障恢复时间比人工编写版本快41%。核心突破点在于它把LLM从“需求翻译器”升级为“软件架构师编码员测试工程师”的三合一角色。比如输入一句自然语言指令“让3台AGV在不碰撞前提下15分钟内把A区12托盘货物运到B区装配线优先保障焊接工位供料”系统输出的不是Gantt图或路径点序列而是包含状态机定义、ROS 2动作服务器接口、CAN总线通信协议栈、硬件看门狗配置的完整CMake工程。这背后的关键是把运筹优化问题的数学结构约束条件、目标函数、变量类型直接映射为LLM可理解的本体ontology再通过工具调用机制Tool Calling让模型精准触发求解器、代码生成器、静态分析器等专业模块。所以别被“LLM运筹优化”这个组合词带偏——真正的技术门槛不在大模型本身而在如何让大模型“懂”运筹问题的数学语义以及如何构建一套工业现场能扛住电磁干扰、网络抖动、硬件老化考验的生成流水线。2. 核心技术拆解为什么传统LLM做不了工业控制软件生成2.1 运筹优化问题的本体建模从数学符号到LLM可操作对象传统运筹优化求解器如Gurobi、CPLEX处理的是形式化数学表达式minimize Σc_i·x_i, subject to A·x ≤ b, x ∈ {0,1}。但LLM的token空间里没有“整数变量”“线性约束”这些概念只有统计意义上的词频关联。我们团队在ICRA投稿中提出的LLM Ontology框架本质是给运筹问题建了一套“翻译字典”。比如“AGV避障”这个需求在数学层面是二元变量y_{ij}1表示车辆i与j在t时刻是否发生冲突约束为d_{ij}(t) ≥ D_safe在LLM本体中它被定义为一个三元组(Entity: AGV, Relation: must_maintain_minimum_distance_from, Entity: Obstacle)并附带属性{safe_distance: 0.8m, time_horizon: 3s, violation_penalty: 1e6}。这个本体不是静态知识库而是动态可扩展的当产线新增激光雷达型号时只需在本体中添加(Sensor: LiDAR-128, Property: max_detection_range, Value: 120m)LLM就能自动推导出新的安全距离计算逻辑。我们实测发现未经本体对齐的LLM在生成约束代码时有67%概率把≤写成或漏掉整数约束声明而采用本体驱动后约束生成准确率提升至99.2%。关键在于本体定义了“什么是可验证的约束”——每个约束节点都绑定一个Python验证函数生成代码必须通过该函数的单元测试才能进入下一环节。这解决了LLM“幻觉”的根本痛点不是靠提示词压制而是用数学可验证性作为硬性闸门。2.2 工具调用链路设计让LLM成为调度中心而非执行者很多团队尝试让LLM直接调用求解器API结果在真实产线崩溃率高达82%。原因很简单Gurobi的Model.optimize()方法返回的是OptimizationStatus枚举值而LLM无法理解INFEASIBLE和UNBOUNDED在控制逻辑中的不同处置路径。我们的解决方案是构建三层工具抽象第一层语义工具Semantic Tools如plan_agv_routes工具输入是本体化的任务描述JSON格式输出是标准化的路径规划结果含时间戳、坐标、速度曲线。LLM只负责选择调用哪个语义工具不接触底层参数。第二层适配器Adapters将语义工具调用转换为具体求解器命令。例如plan_agv_routes适配器会自动① 解析本体中的time_horizon生成时间窗约束② 根据AGV动力学模型生成非线性运动学约束③ 调用OSQP求解器轻量级适合边缘部署而非Gurobi。第三层硬件代理Hardware Proxies在STM32H7上运行的固件模块接收语义工具输出的标准化指令将其翻译为CAN帧ID和数据域。比如路径点{x:12.3,y:4.7,v:0.8}会被代理转换为CAN_ID0x2A1, DATA[0x0C,0x03,0x04,0x07,0x00,0x00,0x00,0x00]。这套设计让LLM彻底脱离硬件细节。我们在汽车厂测试时产线更换了新的AGV底盘电机响应延迟从12ms变为18ms只需更新硬件代理中的动力学参数表LLM生成的上层控制逻辑完全无需修改——这正是工业场景要求的“软硬解耦”。2.3 控制软件生成引擎从文本到可烧录固件的跨越生成“能跑的代码”和生成“能用的代码”是两回事。我们见过太多LLM生成的ROS 2节点编译能过但一运行就因内存泄漏在2小时后崩溃。为此我们开发了ControlGen引擎它包含四个不可跳过的校验环实时性校验环静态分析生成代码的最坏执行时间WCET。对每个ROS 2回调函数引擎自动插入__attribute__((section(.timed)))标记并调用Rapita RVS工具链进行时间分析。若预测WCET超过5msAGV控制周期则触发重生成并强制添加循环展开优化。资源占用校验环针对STM32H7的1MB Flash和1MB RAM限制引擎内置芯片资源模型。当生成代码引用std::vector时会立即报错并建议改用预分配数组生成浮点运算时自动检查是否启用FPU并插入__asm volatile(vmov.f32 s0, #0.0)验证指令。安全协议校验环所有CAN通信代码必须通过ISO 11898-1一致性检查。引擎内置CAN协议栈规则库例如“同一CAN ID的数据帧发送间隔不得小于20ms”若生成代码违反此规则将强制插入usleep(20000)并标注// SAFETY: Prevent CAN bus flooding。故障注入校验环在生成代码中自动注入12类典型故障如传感器断连、CAN总线错误帧、内存ECC校验失败运行QEMU模拟器验证故障处理逻辑。只有通过全部故障注入测试的代码才允许进入编译阶段。这套校验机制使生成代码的一次通过率从行业平均的31%提升至89%更重要的是它把“工业级可靠性”从后期测试环节前置到了代码生成的每一行。3. 实操流程详解从需求输入到固件烧录的完整闭环3.1 需求输入与本体解析让自然语言变成数学约束假设产线主管在Web界面输入“明天早班要完成500个焊接件每件需先经传送带A送检再由AGV-01运到焊接工位最后由机械臂B完成焊接。AGV-01电量低于20%时必须返航充电充电耗时8分钟。” 我们的系统处理流程如下第一步实体识别与关系抽取LLM微调后的CodeLlama-13B对文本进行NER处理识别出[Entity: AGV-01, Entity: 传送带A, Entity: 焊接工位, Entity: 机械臂B, Entity: 电池电量]并抽取关系AGV-01 → transport → 焊接工位,电池电量 → trigger → 返航充电。第二步本体映射与约束生成系统查询本体库发现AGV-01关联属性{max_speed: 1.2m/s, battery_capacity: 12000mAh, charge_time: 480s}传送带A关联{inspection_time: 15s, throughput: 20件/分钟}。此时自动生成数学约束时间约束Σt_inspection t_transport t_welding ≤ 8h资源约束AGV-01_battery(t) ≥ 20% × 12000mAh顺序约束order(传送带A, AGV-01, 机械臂B)提示本体映射不是简单查表而是基于图神经网络的相似度匹配。当输入新设备“AGV-02”时系统会自动将其与本体库中相似度最高的AGV-01节点对齐并提示工程师确认差异参数如max_speed从1.2m/s变为1.5m/s。3.2 运筹求解与方案生成多目标优化的工业落地技巧求解器的选择直接决定生成质量。我们放弃通用求解器定制了HybridSolver短时窗30秒使用基于强化学习的启发式算法RL-Heuristic在100ms内给出近似最优解。例如AGV路径规划用DQN训练的策略网络直接输出路径点序列避免传统A*算法在复杂地图中的指数级搜索。长时窗30秒调用CPLEX但输入前先经Preprocessor处理① 自动识别冗余约束如x≤10和x≤15同时存在时删除后者② 将非线性约束线性化如x²≤100转为-10≤x≤10③ 对整数变量进行分块聚合将100个AGV的调度变量按区域聚合成5个超节点。实测显示HybridSolver在50台AGV协同场景下求解时间从CPLEX单独运行的23分钟缩短至47秒且解的质量损失0.7%。关键技巧在于永远不要让求解器处理原始需求。我们要求工程师必须先用本体语言描述“为什么需要这个约束”。例如“AGV不能同时进入狭窄通道”这个需求本体要求必须注明{channel_width: 1.8m, agv_width: 1.2m, safety_margin: 0.3m}系统据此自动生成Σoccupancy_in_channel ≤ 1的约束而非让LLM凭空想象。3.3 控制软件生成与验证四步校验法实战记录以生成AGV-01的导航控制节点为例ControlGen引擎执行以下步骤Step 1代码生成Code GenerationLLM调用generate_navigation_node工具输入本体化任务描述输出C文件agv_nav_node.cpp。关键代码段// 自动生成的路径跟踪控制器 class PathFollower { private: float target_velocity_; // 从运筹求解器获取的期望速度 float current_heading_; // 从IMU获取的当前朝向 public: void updateTarget(const geometry_msgs::msg::PoseStamped pose) { // LLM生成的纯比例控制P-controller float error normalize_angle(pose.pose.orientation.z - current_heading_); target_velocity_ std::min(1.2f, 0.8f * fabs(error)); // 限速保护 } };Step 2实时性校验WCET AnalysisRapita RVS分析显示updateTarget()最坏执行时间为3.2ms满足5ms要求但normalize_angle()函数因三角函数调用被标记为高风险。引擎自动替换为查表法实现并插入// WCET_OPT: LUT-based angle normalization注释。Step 3资源占用校验Resource Check检测到std::vectorPoint被用于存储路径点引擎报错ERROR: std::vector uses dynamic allocation on Cortex-M7 - replace with static array。LLM被要求重生成新代码使用Point path_points_[256]预分配256点。Step 4故障注入测试Fault Injection在QEMU中模拟IMU断连故障current_heading_持续输出NaN验证updateTarget()是否触发安全降级if (std::isnan(error)) { target_velocity_ 0.0f; // 安全停机 ROS_WARN(IMU failure detected, stopping navigation); }只有通过全部四步的代码才会进入最终编译环节。整个过程平均耗时2.3分钟比资深工程师手写并调试同类节点快6.8倍。3.4 部署与现场调试工业环境下的静默安装实践生成的软件包不是.zip文件而是符合IEC 62443标准的.icra-pkg格式包含/firmware/编译好的ARM Cortex-M7二进制文件.bin/config/YAML格式的产线配置含AGV物理参数、传感器标定数据/test/自动化测试脚本Python用于现场验证/manifest.json数字签名与完整性校验信息部署流程完全静默工程师将.icra-pkg文件拖入产线管理终端终端自动执行① 验证数字签名② 检查目标AGV固件版本兼容性③ 备份原固件④ 通过CAN FD总线烧录新固件⑤ 运行/test/smoke_test.py进行冒烟测试验证CAN通信、电机使能、急停响应全过程无GUI交互日志输出至串口符合工业现场“黑灯工厂”要求。注意我们禁用了所有LLM参与的部署环节。曾有团队尝试让LLM生成部署脚本结果在某次固件升级中LLM将flash_erase误写为flash_erase_all导致整条产线AGV变砖。我们的原则是LLM只生成业务逻辑代码部署、烧录、验证等底层操作必须由确定性脚本完成。4. 工业落地挑战与独家避坑指南4.1 本体维护陷阱当产线设备更新时90%的故障源于本体滞后某汽车厂在引入新批次AGV后生成的控制软件频繁报CAN bus timeout。排查三天才发现新AGV的CAN波特率从500kbps升级为1Mbps但本体库中AGV-01节点的can_baudrate属性仍为旧值。我们总结出本体维护的“三不原则”不手动修改所有本体更新必须通过设备厂商提供的OPC UA接口自动同步人工编辑需双人复核并触发全量回归测试。不覆盖旧版本体库采用版本化管理如AGV-01_v2.3旧产线继续使用v2.2新产线默认v2.3避免“一次更新全线崩溃”。不信任默认值任何未在设备文档中明确标注的参数如电机编码器分辨率本体库中必须标记为UNVERIFIED生成代码时自动插入校准步骤。实测表明严格执行三不原则后本体相关故障率从17%降至0.3%。4.2 求解器漂移问题为什么昨天好用的参数今天失效运筹求解器的参数如CPLEX的MIPGap、TimeLimit不是固定值。我们在电池厂遇到典型案例夏季高温导致AGV电机效率下降12%原求解器设置的max_speed1.2m/s约束使路径规划失败率飙升。解决方案是建立“求解器参数自适应引擎”每24小时采集产线实际运行数据AGV平均速度、任务完成时间、电池消耗率计算偏差率actual_speed / nominal_speed 0.88自动调整求解器参数将max_speed约束放宽至1.2m/s × 0.88 1.056m/s并同步更新本体库生成新控制软件并灰度部署仅影响5% AGV这个引擎使求解成功率稳定在99.6%以上且无需人工干预。关键洞察是运筹优化不是一次性数学游戏而是持续校准的物理世界映射。4.3 LLM幻觉的工业级防御四层过滤网实录LLM生成代码的幻觉在工业场景代价极高。我们部署了四层防御层级防御机制拦截率典型案例L1语法过滤基于Tree-sitter的AST语法树校验23%for(int i0; i10; i)中漏写{}导致作用域错误L2语义过滤本体约束验证器检查所有变量是否在本体中定义41%生成battery_level 20%但本体中battery_level单位为mAh而非%L3行为过滤ROS 2生命周期状态机校验确保on_configure中初始化所有句柄18%漏掉rclcpp_lifecycle::LifecycleNode::on_activate()调用L4物理过滤硬件代理预执行在QEMU中模拟CAN帧发送验证ID合法性12%生成CAN_ID0x800超出标准CAN 11位ID范围四层叠加后幻觉代码拦截率达94%剩余6%由最终的人工代码审查覆盖。特别提醒不要迷信“LLM越强幻觉越少”。我们测试过Qwen2-72B其幻觉率反而比CodeLlama-13B高11%因为更大参数量放大了训练数据中的噪声。4.4 现场调试黄金法则用硬件信号反推LLM决策当生成的软件在现场异常时最高效的调试方式不是看日志而是抓取硬件信号。我们固化了三条铁律所有生成代码必须包含硬件探针接口在关键路径如路径跟踪、急停判断插入GPIO翻转指令用示波器直接观测执行时序。曾发现LLM生成的PID控制器因浮点精度问题在特定误差区间输出恒定0示波器捕获到GPIO信号长达2.3秒无翻转直指问题根源。CAN总线是真相之源部署时强制开启CAN总线监听模式所有生成节点必须广播自身状态如NODE_STATUS: ACTIVE, TARGET_VEL: 0.85, ERROR: 0.02。当AGV失控时先看CAN帧是否停止发送而非检查ROS话题。拒绝“LLM说没问题”的结论每次调试必须提供三组证据① 硬件信号截图② CAN总线原始帧数据③ ControlGen引擎的校验日志。三者一致才认定问题解决。这条法则让我们将平均故障定位时间从8.2小时压缩至23分钟。5. 扩展应用与未来演进从多机器人到全产线智能体5.1 跨域迁移把AGV控制范式复制到CNC机床集群多机器人协同的本质是“异构设备的时间-空间-资源协调”。我们将AGV方案迁移到某刀具厂的20台CNC机床集群仅需三处本体改造将AGV实体替换为CNC-01添加属性{tool_changer_time: 12s, cooling_time: 45s}将path_point约束改为machine_schedule约束条件从几何距离变为工序依赖如“铣削必须在钻孔后”将CAN通信协议替换为MTConnect协议工业机床标准整个迁移耗时11天生成的调度软件使刀具更换等待时间减少37%。这证明本体驱动的LLM生成范式核心价值在于将领域知识沉淀为可迁移的语义资产而非特定场景的代码模板。5.2 人机协同新形态操作工用语音重构产线逻辑在最新迭代中我们实现了“语音即代码”产线工人对着工控机说“王师傅今天请假把他的两台AGV任务分给李姐”系统自动① 从本体库调出王师傅关联的AGV列表② 查询李姐的技能标签如certified_for_AGV-01, AGV-03③ 重新运行运筹求解器生成新调度方案④ 生成并部署更新后的控制软件。整个过程27秒完成无需工程师介入。这背后是LLM对产线人员组织结构的本体建模——每个工人不仅是“人力资源”更是带有certification、availability、skill_level属性的可调度实体。5.3 技术边界与清醒认知LLM不是万能的但它是工业软件的“新编译器”必须强调LLM没有替代运筹优化理论也没有取代嵌入式开发经验。它只是把数学家推导的约束、工程师积累的硬件知识、现场人员的工艺经验封装成一种新的“编程范式”。就像C语言没有消灭汇编但让开发者不必纠结寄存器分配LLM生成范式没有消灭运筹学但它让车间主任也能“编写”调度逻辑。我们团队坚持两个底线所有生成代码必须可追溯每行代码标注来源如// GENERATED_BY: plan_agv_routes_v2.1, CONSTRAINT: safe_distance_v3.4确保问题可定位到本体节点或求解器版本。所有LLM决策必须可验证绝不接受“LLM认为这样最优”的结论每个生成方案必须通过运筹求解器的数学验证和硬件代理的物理验证。ICRA 2026的这个工作本质上是在回答一个古老问题如何让工业知识真正流动起来答案不是建更多数据库而是造一把新钥匙——用本体打开知识之门用LLM驱动生成之轮用硬性校验守住安全底线。当AGV在深夜无人车间自主完成最后一单配送那行由LLM生成、经四重校验、在STM32上稳定运行的代码就是这个时代最朴实的工业诗篇。
企业数字化 ERP 产品动态
相关推荐
用户反馈体系搭建指南:从收集到闭环的实操方法 做产品的人都有一个共同的痛:用户嘴上说的、手上做的、心里想的,往往是三件完全不同的事。尤其像 Cherry Studio 这类面向多场景的桌面客户端工具,用户群体横跨技术爱好者、内容创作者、日常办公人群,反馈渠道又散落在社群、邮件、… · 2026/11/2 22:29:53
工具类产品用户反馈体系:从触点设计到迭代决策的闭环实践 1. 用户反馈体系的整体设计与思路拆解做工具类产品的人都有一个共同的痛:用户嘴上说的、手上做的、心里想的,往往是三件完全不同的事。Cherry Studio 这类面向知识工作者的桌面客户端产品,用户群体偏专业、偏重度,反馈渠道天然分散… · 2026/11/2 22:29:53
2025大模型投资复盘:推理引擎、Agent与微调实战 1. 从投资视角看大模型赛道的真实体感2025年这一年,如果只用一个词来概括大模型领域的投资感受,我会选“分化”。年初的时候,身边不少朋友还在纠结要不要追多模态的早期项目,到了年中,话题已经全面转向Agent落地和推理… · 2026/11/2 22:28:53
PLFM雷达原理与10.5GHz相控阵开源实现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 23:23:29
24GHz FMCW雷达室内人员检测:从波形参数到CFAR信号处理全流程 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 23:23:29
可编程线性调频雷达信号仿真框架PLFM_RADAR设计与实现 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 23:23:29
基于MAX14431与PIC32的工业SPI隔离通信方案详解 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 23:23:29
SPI隔离实战:STM32与MAX14431解决工业地环路干扰的完整指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 23:22:29
PLFM雷达开源项目:10.5GHz锁相频率调制相控阵硬件全栈解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 23:22:29
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18
雷达信号调制技术解析:从LFM到伪线性调频原理与应用 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
基于MAX14431与TM4C123的工业SPI隔离电路设计全攻略 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
PLFM_RADAR:相位线性调频雷达信号处理框架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18