news 2026/9/26 3:49:53

区域综合能源系统双层优化调度:计及需求响应的Matlab完整复现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
区域综合能源系统双层优化调度:计及需求响应的Matlab完整复现

做核心期刊论文复现这件事,老读者都知道我的习惯:不把代码丢出来就完事,一定要把模型顶层设计、数学原理、代码架构和踩坑过程全部讲清楚。这篇要拆解的,是“计及需求响应的区域综合能源系统双层优化调度策略研究”,Matlab代码实现。这个方向这几年在《电网技术》《中国电机工程学报》《电力系统自动化》等期刊上出镜率非常高,也是研究生开题、毕业设计、小论文投稿的热门切入点。区域综合能源系统本身涉及电、气、热、冷多种异质能源的耦合,再叠加上需求响应这一层“用户侧资源调动”,模型复杂度直接上一个台阶,双层优化的求解更是劝退了不少刚入门的同学。我自己之前帮几位师弟调过这类代码,深知这里面真正的坑不在“双层”这个概念,而在层与层之间怎么衔接、迭代怎么收敛、整数变量怎么处理、求解器怎么选这些实操细节。这篇就把整套方案的建模思路、代码实现和调试经验一次性讲透,适合正在复现论文、准备竞赛或者搞毕设的电气工程、能源动力专业学生参考。

1. 项目核心思路与整体模型架构

要理解这个题目,先得把“区域综合能源系统”和“双层优化调度”这两个词拆开。区域综合能源系统,覆盖一个园区、一个社区或者一个县城级别的能源网络,内部有风、光、储、燃气轮机、电锅炉、吸收式制冷机这些设备,同时通过配电网、天然气管网与外部进行能量交互。传统调度只盯着“源-网-荷”中的源侧做文章,也就是机组怎么启停、出力怎么分配。但需求响应引入之后,“负荷”不再是固定刚性的,它变成了一个可以被价格信号撬动的柔性资源。用户会根据你定的电价调整用电行为,削峰填谷就成了双向互动,而不是单向命令。

这就是“双层优化”出现的根本原因。上层决策者(系统运行商)想通过制定合理的售能价格和调度方案让系统总运行成本最低;下层决策者(用户)会根据上层给定的价格,通过调整自身的用能策略让自己的用能成本最小。两层之间不是一个主从串行关系,而是相互嵌套的博弈关系——上层动一下价格,下层就换一套响应策略,上层再基于新的负荷分布重新优化,一直迭代到某个稳定状态。

从代码实现的角度,这套模型在Matlab里可以清晰地拆成几个模块:

  • 上层优化模块:以系统运行成本最小为目标,决策变量包括购电、购气量、各设备出力、储能充放电以及售能价格策略。
  • 下层优化模块:以用户用能成本最小为目标,决策变量包括可转移负荷的启停时段、可削减负荷的削减量、弹性负荷的调节比例等。
  • 数据交互模块:上层的售能价格作为参数传入下层,下层的最优负荷响应结果作为参数返回上层。
  • 约束处理模块:网络潮流约束、设备出力上下限、爬坡约束、储能SOC连续性、需求响应比例约束等各类等式不等式约束。
  • 算法求解模块:调用YALMIP工具箱建模,接口CPLEX或Gurobi求解线性规划、混合整数线性规划和二次规划。

这两层模型的嵌套关系,是整套代码最核心的逻辑。很多同学写双层优化,最后写成了两个独立优化问题轮流跑一次然后结束了,这不对。双层优化的本质是“下层问题的最优解是上层问题的约束或目标的一部分”,也就是说,你必须在上层模型中显式地把下层的优化行为包含进来,或者通过迭代的方式让上下层达成均衡。

抛开复杂的数学推导不谈,这套逻辑在实现思路上要分清两种模式。第一种是“主从递推法”,也就是所谓的一主一从迭代收敛,上层先订价,下层按价格响应,不断修正直到前后两轮结果差距小于阈值。第二种是“单层化转化法”,通过KKT条件把下层优化问题等价转化为上层模型的约束集合,这样一个双层问题就退化为一个可以被商业求解器直接处理的单层数学规划问题。核心期刊里面大多数涉及严格数学推导的文章,用的都是后一种方法。

我在实际复现的时候,明显感觉第二种方法对新手并不友好。因为KKT条件的推导需要引入拉格朗日乘子、互补松弛条件以及大M法线性化,涉及到大量繁琐的变量扩展。尤其是下层问题存在多个用户类型时,每个用户的KKT条件都会引入一批新变量,模型规模爆炸式增长,Gurobi和CPLEX即使能解,求解时间也会显著拉长。相比之下,主从递推法虽然数学上不能严格证明收敛到全局最优,但胜在实现直观、调试方便,配合足够精细的迭代控制条件,对于工程场景已经完全够用。核心期刊复现的核心诉求是“把方法和逻辑跑通了”,而不是“把论文的每一条引理都重新证明一遍”。

所以我的第一建议是:如果只是想复现论文并理解思路,先走主从递推路线,拿到正确结果后再对照论文判断是否需要升级成KKT单层化。这套方案的天花板在于迭代步数和收敛判据的合理性,合理设计完全可以保证精度。

1.1 为什么选择双层结构而不是集中式优化模型

这个问题很多人在开题答辩时都被评委问过。集中式优化不是更简单吗?把所有用户负荷纳入统一调度不就行了吗?答案是可以,但违背了实际场景中的信息结构。在区域综合能源系统里,系统运营商和终端用户之间不存在完全的信息透明,用户不会把自己的舒适度曲线、偏好约束全部上报给运营商,运营商也不可能直接控制每一个空调、热水器和工业负荷。双层结构天然刻画了这种“分散决策、层层诱导”的信息特征:上层只能通过价格信号间接影响下层决策,下层拥有对自己用能行为的最终决定权。

从博弈论的视角,这个机制类似主从博弈(Stackelberg Game),系统运营商是领导者,用户是跟随者。领导者提前承诺一个价格策略,跟随者在看到这个价格后做出最优反应。因为用户的数量远多于运营商,用户的策略空间高度分散化,集中式统一调度在现实中根本行不通。双层优化的模型假设和现实的信息结构完全吻合,这也是核心期刊偏好这种建模方式的重要原因。

我在论文复现前,会把模型结构画成一页纸的三层图:上层是系统运营商的调度中心和设备模型,中间是价格信号和负荷响应信息的双向传递通道,下层是分类用户的需求响应模型。这一页纸我建议你也画,因为在Matlab中写代码时,你能不能清楚地知道哪个变量从哪来、到哪里去,直接决定代码能不能调通。

1.2 模型适用范围与场景设定

这套模型适合的场景是:有明确售能关系、用户端具备负荷调节能力、系统侧有多个能源耦合设备的区域级综合能源网络。比如典型工业园区的冷热电联供系统,夏季冷负荷占比高、冬季热负荷占比高,同时配有一定比例的可中断工业负荷和可转移生产班次。又比如含有商业综合体、居民小区和轻工业用户的社区型能源站,电价峰谷差显著,具备实施分时电价和激励型需求响应的基础。

初始场景参数包括电网购电分时电价、天然气价格、光伏和风电的预测出力曲线、各类负荷的基础预测曲线、储能系统容量与SOC上下限、各设备的效率系数与出力范围。这些参数直接决定后续运行成本和最优调度方案,参数设置不当不仅会让结果偏离实际,还可能导致模型无解,这一点在第三节会展开细说。

2. 需求响应机制设计与建模要点

需求响应分成两大类:基于价格的响应和基于激励的响应。基于价格的典型手段就是分时电价、实时电价、尖峰电价;基于激励的典型手段是可中断负荷补偿、直接负荷控制、需求侧竞价。在区域综合能源系统的双层模型中,上层价格策略通常作为“激励信号”输出,下层用户根据该信号进行负荷转移或削减。下层的负荷变化,又反过来改变了上层的负荷预测曲线,进而影响系统整体的经济调度结果。

2.1 负荷侧柔性资源分类建模

在Matlab代码中,需求响应模型不是简单在负荷曲线上乘一个弹性系数,而是要对负荷进行分类型建模。我的做法是将用户负荷拆成三类:

固定负荷:对价格不敏感,比如安防系统、基础照明。这类负荷在任何时段都必须满足,属于模型中的不可调度项。

可转移负荷:在一天内的总用电量不变,但用电时段可以平移。典型代表是洗衣机、消毒柜、工业间歇性生产线。建模时引入0-1整数变量表示负荷在某一时段的启动状态,转移的约束是“启动后必须连续运行若干小时”以及“一天内启动次数不超过指定值”。

可削减负荷:根据补偿价格,用户允许系统在一定时段削减掉一部分负荷。典型代表是空调的设定温度调节、非核心生产设备的临时停工。建模时引入连续变量表示削减量,并设置削减比例上限。

三种负荷加起来构成用户的综合响应模型。在Matlab中用结构体数组承载各负荷类型的时序特性非常方便,比如load_profile.period_start、load_profile.energy_per_day、load_profile.max_curtail这样一个“可读性优先”的数据结构设计,比一大坨矩阵传参要容易调试得多。

2.2 价格弹性矩阵与用户行为建模

除了物理机理建模之外,还有一条经济学建模路线,就是基于价格弹性矩阵的用户响应模型。价格弹性系数表示“价格变化1%时负荷变化百分之多少”,自弹性系数和交叉弹性系数组成弹性矩阵。自弹性系数对应当前时段的负荷变化,交叉弹性系数对应其他时段价格变化对当前时段负荷的影响。

在Matlab里,弹性矩阵是一个T×T的矩阵,T是调度周期时段数。当T取24,矩阵规模就是24×24,数据量完全可控。算负荷响应时,直接用当前价格向量和基准价格向量的比值取对数,再乘弹性矩阵,加上原始负荷,就得到响应后的负荷曲线。这种方法的优势是代码极其简洁,核心运算只需要一次矩阵乘法,也更贴近部分核心期刊模型中“需求价格弹性”的数学表达。

不过这条路线有一个需要注意的坑:弹性矩阵怎么设定。很多复现代码直接拍脑袋给一组常系数,结果算出来的负荷转移幅度大得离谱或者小到忽略不计,整体结果失去参考意义。我的建议是分时段设置自弹性系数,峰时段取-0.2到-0.3,谷时段取-0.1左右,交叉弹性系数通常比自弹系数小一个数量级,取0.01到0.05之间。这样算出来的负荷响应变化率通常在5%到15%区间,符合实际工程经验。

2.3 需求响应约束的工程化处理

实际代码编写过程中,需求响应约束的处理是出错率最高的环节,归纳为三类常见问题。

第一类问题:可转移负荷的“连续性”约束写错。如果只约束启停状态,没有约束“启动后连续运行时长”,优化算法会给出一个非常“碎片化”的调度结果,比如洗碗机每隔二十分钟开关一次,这在物理上完全不可行。处理办法是引入启动变量u_start(i,t),它定义为u(i,t) - u(i,t-1)的正部分,并添加约束:任意连续区间内,一旦u_start=1,后续dur-1个时段必须保持u=1。

第二类问题:削减量约束不正确。可削减负荷削减的是“用户获得的服务量”,而不是“设备出力”。空调削减负荷实际体现为温度设定点变化,减少的制冷量和服务舒适度相关。所以削减比例上限应该按各时段最大可调能力设置,而不是统一设置一个总削减上限封顶。

第三类问题:用户响应后的负荷曲线PAC(价格弹性曲线)存在震荡。迭代过程中,上下层数值来回跳动,导致总负荷曲线出现不合理的锯齿。解决手段一是设置合理的收敛阈值,二是对迭代信号添加阻尼系数,也就是新一轮的负荷值取上一轮和本轮响应结果的加权平均,防止过冲。

3. 双层优化数学模型与求解方法

3.1 上层模型的目标函数和约束条件

上层以系统日运行总成本最小作为目标,总成本由购电成本、购气成本、设备运维成本、需求响应补偿成本四部分构成。用公式表达就是:

min F = sum(ce(t) * Pe_buy(t)) + sum(cg(t) * Pg_buy(t)) + sum(Com * Pdevice(t)) + sum(cdr(t) * Pcurtail(t))

这里面ce(t)和cg(t)分别是分时电价和天然气价格,Pe_buy(t)是时段t的购电量,Pg_buy(t)是购气量,Com是设备单位出力的运维成本系数,cdr(t)是需求响应补偿单价。设备运维成本需要将各设备的出力曲线乘以对应系数后求和。

约束条件包括:电功率平衡约束、热功率平衡约束、冷功率平衡约束、设备出力上下限约束、爬坡约束、储能充放电功率限制和SOC状态转移约束、与外网交互功率限制。这里面最容易出错的是多能平衡约束。区域综合能源系统里热电联产机组发电的同时会产生热,电锅炉耗电的同时产生热,吸收式制冷机耗热制冷,电制冷机耗电制冷。如果不小心把同一份能量用了两次,模型就有可能出现“免费的午餐”,导致成本低到不合理。我的调试经验是:每加一台设备,手动追一遍它的输入输出端口,把所有能量流画成表格,避免在Matlab中写矩阵约束时漏掉某个设备项。

3.2 下层模型的目标函数和约束条件

下层模型描述用户侧在给定价格策略下的最优响应行为。目标函数为用户用能成本最小:

min f = sum(price_e(t) * Pe_load_after(t)) + sum(price_h(t) * Ph_load_after(t)) - sum(compensation(t) * Pcurtail(t))

等号右边第一项是购电费用,第二项是购热费用,第三项是参与需求响应获得的补偿收益。约束条件包括:转移负荷的电量守恒约束(一天的转移总量为0)、可削减负荷的上限约束、各类负荷的调节速率约束和时间约束。

写代码的时候需要注意,下层的目标函数里的price_e(t)在上层模型中是决策变量,但在下层模型中它变成了参数。这个“变量-参数”的角色转换,在实现递推算法时靠接口函数完成;在实现KKT单层化的时候,则要把变量角色的一致性处理好,避免重复定义导致求解器报错。

3.3 KKT条件与大M法线性化处理

把下层问题并入上层模型的最标准做法,是写下层问题的KKT条件,然后将KKT条件转化为上层模型的约束。KKT条件分为三部分:下层目标函数对各决策变量的一阶偏导等于0(驻点条件)、下层约束对应的不等式约束(可行性条件)、各不等式约束乘以对应拉格朗日乘子等于0(互补松弛条件)。

互补松弛条件是典型的非线性约束,形式是lambda_i * g_i(x) = 0,其中lambda_i是拉格朗日乘子,g_i(x)是不等式约束的左侧表达式。Matlab中的YALMIP可以声明这类双线性等式约束,但CPLEX和Gurobi求解非线性问题能力有限,因此必须线性化。常规做法是引入0-1辅助变量,将互补约束拆成一对带大M的不等式:

lambda_i >= 0, g_i(x) >= 0, lambda_i <= M * z_i, g_i(x) <= M * (1 - z_i)

其中z_i是0-1变量,M是足够大的常数。大M的取值很考验经验,取得太大,求解器的数值稳定性会下降,甚至出现整数规划长时间无法收敛;取得太小,可能剪掉真正的可行域,导致结果错误。我一般取约束量级最大数值的100倍左右,然后做一个敏感性测试:把M乘10,看结果变不变,如果变了就把M往大调。

3.4 主从递推法与单层化方法的收敛性对比

这个项目我两种方法都跑过,差异相当明显。主从递推法在Matlab中的实现就是for循环迭代。每轮迭代先解上层优化,把最优价格传给下层;下层基于这个价格重新优化自己的负荷曲线,再把新的负荷传回上层。程序结构简洁,调试起来每一步都能输出中间结果。但需要注意,这个迭代不是随便就能收敛的。上下层的决策变量之间有耦合,可能存在多个均衡点,而且初值不一样,最终收敛到的均衡点可能不同。

我建议实际使用时加一个“逐步松弛”的迭代策略:把上层价格变量的单次变化幅度限制在上一轮值的某个百分比以内,防止价格信号剧烈波动导致下层响应和上层预期反复横跳。比如每轮价格变化不超过前一轮的20%。这样迭代曲线虽然看起来多走了几步,但稳定性明显改善。

KKT单层化方法的收敛性在数学上更有保障,因为MILP问题的全局最优解由求解器保证,不需要考虑初值问题。这也是核心期刊文章更喜欢展示的方法。但代码实现复杂度和调试难度也更高,尤其是模型写完后,YALMIP中变量数量上千,一个约束索引写错,排查难度很大。我的经验是:分层构建约束块,每一类约束单独写成一个函数,并且用注释标明对应论文公式编号,这样调试时能快速定位。

4. Matlab代码实现与工程化落地

4.1 代码目录结构与模块划分

一套能长期使用的双层优化代码,目录结构建议这样组织:

figures/ % 仿真结果图 data/ % 基础数据:负荷曲线、分时电价、设备参数 utils/ % 工具函数:负荷聚合、收敛控制、绘图脚本 models/ % 上层设备模型、下层用户模型、需求响应模型 solvers/ % 主从递推主程序、KKT单层化求解程序

主程序入口文件建议命名main_bi_level.m,里面只做参数初始化和函数调用,不写具体逻辑。这样别人拿到你的代码,第一眼就能看懂运行流程。我自己写复现代码的惯例是:每个模块文件开头放一段注释,写明模型对应的论文公式编号、输入输出变量含义、修改历史。代码写得好不好,看结构化程度就够了,不需要等运行结果。

4.2 YALMIP建模与CPLEX求解器配置

Matlab上做优化模型,目前最常见的组合是YALMIP加CPLEX,偶尔也有人用Gurobi。YALMIP是一个建模层工具箱,你把变量和目标函数写进去之后,它自动分类问题类型(LP、QP、MILP、MIQP),选择合适的求解器处理。我强烈建议用YALMIP而不是手写求解代码,原因简单:双层规划无论是迭代还是单层化,最终落到求解器层面只需要处理LP、QP或MILP,手写单纯形和分支定界完全没必要。

配置过程有几点要注意。首先是CPLEX版本:CPLEX 12.10之后,Matlab接口是基于cplexmilp函数族的,需要安装配套的Matlab支持包,且对Matlab版本有要求。如果你是Matlab R2022a以上的版本,建议用最新版的CPLEX,老版本在install阶段会有兼容性报错。其次是路径问题,CPLEX安装目录下的cplex/examples/src/matlab文件夹必须添加到Matlab路径中,不然Cplex类不能被识别。

YALMIP中定义决策变量时要注意变量类型。双层递推法里上层价格是连续变量,下层响应负荷是连续变量或0-1变量;KKT单层化之后,所有拉格朗日乘子是非负连续变量,z_i是0-1变量。用sdpvar和binvar明确定义,避免混用。

4.3 双层递推迭代主程序框架

迭代主程序的核心框架,写成伪代码就是:

  1. 初始化基础数据,读取负荷曲线和价格参数
  2. 初始化策略参数:价格初值、收敛阈值 epsilon、最大迭代次数 K
  3. 进入迭代循环
  4. 以上一轮负荷响应结果为输入,调用上层求解函数,得到本轮最优调度方案和价格策略
  5. 将新价格策略传给下层求解函数,得到用户最优负荷响应结果
  6. 计算本轮与上一轮的调度成本差值或价格差值
  7. 如果差值小于 epsilon,终止循环输出结果;否则更新参数并继续
  8. 对输出结果做后处理,绘制曲线图和表格

实际代码中每一轮迭代都需要保存中间结果,用元胞数组存储每轮的设备出力矩阵、负荷曲线矩阵、成本值,方便最后绘制收敛曲线。我见过很多同学不存中间结果,最后想查看迭代轨迹时无从下手,只能重跑一遍。建议代码从第一版就把结果存储模块加上去。

4.4 仿真算例设计与参数取值参考

算例参数要尽量接近核心期刊论文的典型数据。以一个中等规模园区为例:日峰值电负荷约12MW,热负荷约8MW,冷负荷约6MW;光伏装机容量5MW,风电3MW;储能容量4MWh,最大充放电功率1MW;燃气轮机额定功率6MW,电效率35%,热效率45%;电锅炉容量3MW,制热效率1.1;吸收式制冷机容量4MW,性能系数1.2。电网分时电价峰谷平时段设置是峰段10点-12点、14点-19点电价1.1元/kWh,平段7点-10点、12点-14点、19点-22点电价0.68元/kWh,谷段22点-次日7点电价0.32元/kWh。天然气价格取2.8元/m³,低热值按9.7 kWh/m³折算。

这些参数不是凭空拍的,而是综合了典型文献数据和工程算例设定。参数设置的第一个原则是设备耦合关系要对得上,比如燃气轮机热电比必须和电效率、热效率匹配,不然热平衡约束和电平衡约束会互相矛盾。第二个原则是外购价格要保持合理的峰谷价比,峰谷电价差超过3倍时需求响应的效果才会凸显,差价太小用户没有响应动机,差价太大模型结果又可能失真。

4.5 需求响应后的结果分析与绘图技巧

算例跑完,通常是两套结果对比:一套是无需求响应的传统调度结果,一套是计及需求响应的双层优化结果。对比维度包括系统总成本、设备出力计划、购电曲线、各时段负荷曲线、可再生能源消纳比例、储能充放电策略等。

绘图建议用两组子图对比,左列无DR,右列有DR。负荷曲线的对比用阶梯图更能反应不同时段的变化,耗能设备出力用柱状堆叠图展示。Matlab的tiledlayout函数可以做模态化排版,比subplot更灵活。绘图时注意中文字体问题,Matlab默认字体对中文支持不好,可以在figure创建后设置FontName为SimHei或直接全部使用英文标签,避免乱码。

4.6 双层模型代码调试与问题排查记录

我实际跑这套代码时,遇到过几个非常典型的问题。第一个是模型不可行。报错信息通常是Infeasible problem中间结果显示某个约束严重冲突。常规排查路径是:先检查各类负荷是否满足能量守恒,再检查储能SOC递推约束的初值是否合理,最后检查设备出力上下限和爬坡约束是否能同时满足。90%的情况是某个约束的常数项写错,比如容量单位从MW写成kW,忘记除以1000。

第二个是整数规划求解时间过长。YALMIP下MILP问题规模一大,CPLEX默认参数可能要很久才能收敛。解决手段有三个:给求解器设置相对间隙mip_tolerances_mipgap,设置为0.01时就够了,不必等精确最优;设置单条求解时间限制;如果条件允许,把0-1整数变量的数量尽量压缩,比如可转移负荷不用“每时刻的启停状态”而用“启动时段”作为整数变量,规模下降明显。

第三个是迭代不收敛。主从递推法的常见病。多数情况是上下层目标函数匹配不上,下层用户响应后的负荷曲线在上层中没有体现对应的补偿成本,导致上层不断要求用户削峰,下层不断拒绝,来回震荡。还有一个原因是收敛阈值设置过小,工程上成本相对偏差在0.1%以内已经足够,没必要追求1e-6级别的精度。

4.7 常见问题速查表

症状可能原因处理手段
YALMIP报No suitable solverCPLEX路径未配置将cplex文件夹加入Matlab路径
模型求解结果为NaN某个参数未初始化或除以0检查常数项和效率系数,添加非零判断
运行时间过长MILP规模大设置mipgap,减少整数变量数
迭代反复震荡上下层信号未加阻尼对价格更新添加变化限幅
结果成本低到离谱能量平衡约束遗漏手绘能量流图,逐一核对各设备端口
图出现中文乱码系统缺少中文字体使用SimHei或英文标签
双层结果与论文对不上价格初值、收益分成方式不同检查论文的博弈规则设定,调整参数

4.8 个人经验收尾

这套代码我完整写完并跑通,大概花了两周时间,中间大部分时间耗费在KKT条件推导和求解器数值稳定性调整上。如果你也在做同方向的研究,我的建议是从小算例起步,先跑一个三天、三个用户类型的简化模型,确认逻辑闭环后再扩展到24时段多用户场景。小算例很快就能暴露建模错误,而大算例一旦出错,定位成本会高很多。另外,主从递推法虽然不像KKT单层化那样“证明严密”,但对理解双层优化的交互机制非常有帮助,建议作为入坑的第一站。最后的体会是:双层优化的难点从来不在求解器,而在层与层之间的信息传递设计和模型一致性维护,把这一层想清楚,代码就成功了一大半。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 3:48:49

TRAE × 英特尔 Agentic PC:用 DeskMate 给智能体加一层本地过程记忆

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

作者头像 李华
网站建设 2026/9/26 3:48:38

TRAE + Doubao-Seed-Evolving + Android Studio:旧 App 项目跑通配置与验证

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

作者头像 李华
网站建设 2026/9/26 3:46:33

【STM32 HAL库】01 - LED闪烁实验(GPIO输出)

【STM32 HAL库】01 - LED闪烁实验&#xff08;GPIO输出&#xff09;一、实验目的熟悉 STM32CubeMX 图形化配置工具的基本使用流程掌握 GPIO 引脚配置为输出模式的方法理解 HAL 库中 GPIO 相关函数的使用实现 LED 周期性闪烁&#xff0c;验证开发板下载、运行链路正常二、硬件平…

作者头像 李华
网站建设 2026/9/26 3:45:41

Postgres mcp server 配置 TaoToken:settings.json 骨架与连通性验证

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

作者头像 李华