news 2026/10/17 5:11:26

清扫机器人强化学习:10项复合奖励函数让训练从100分涨到778分

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
清扫机器人强化学习:10项复合奖励函数让训练从100分涨到778分

前阵子我把清扫机器人项目的强化学习训练分数从 100 分抬到了 778 分,网络结构没动,算力没加,甚至训练集都没扩大,唯一的变量是奖励函数。这件事让我彻底相信:在复杂的机器人任务里,奖励工程的优先级,往往比算法选型更高。清扫看似简单,实际是个典型的多步决策问题——机器人要决定往哪走、扫不扫、扫完去哪,每一个动作都要在时间和能耗上精打细算。用最基础的稀疏奖励,等于让机器人从一句“干得好”里自己悟出所有步骤,太难了。我梳理了从 100 分到 778 分背后的一整套奖励工程实践,核心就是 10 项复合奖励,下面逐个拆开讲。不管你做的是扫地机、机械臂抓取还是机器人导航,这份经验应该都用得上。

1. 清扫任务为什么会卡在稀疏奖励上

1.1 清扫任务的双重难点:目标稀疏与动作长程

强化学习要能跑通,最关键的是让智能体在一个多步决策过程中不断获得“信号”来修正策略。清扫机器人尤其考验这一点,因为它的状态空间是连续的:机器人当前位姿、障碍物分布、已经覆盖过的栅格区域、剩余未覆盖区域,每一个维度都在变。而动作空间也是连续的,我这边用的是差分驱动底盘,输出是线速度和角速度。在这样一个连续空间里,如果只告诉机器人“最后扫干净了就奖励”,它根本没法把一个长期目标拆解到每个时刻的微小动作上。

举个更直观的例子:一个刚出生的孩子,如果家长从不说话、不指路,只在二十年后说一句“你会不会整理房间”,那他一辈子也不可能学会整理。稀疏奖励就是这个效果——任务完成信号离单步动作太远,梯度几乎传不回来。清扫任务的目标尤其稀疏,因为“清扫干净”是一个整体状态,几乎没有中间反馈。机器人扫过一格新区域时,它其实不知道这算不算做对了,只有在回合结束时看到一个覆盖率分数,这时才有一点信号,但早不知道是哪一步的功劳了。

1.2 稀疏奖励的失败曲线:100分是个什么概念

我这个项目的评估方式很简单:自定义一个综合分,由三部分构成——栅格地图的最终覆盖率乘 100 作为主要得分,每步时间惩罚扣一点,每次碰撞再扣一点。我用这个综合分作为报告用的指标,也用来判断一个奖励函数到底好不好用。

一开始我用的就是最朴素的稀疏奖励:清扫完成且覆盖率超过 90% 时给 +1 分,其余时刻奖励为 0。这个设置下训练了 100 万步,综合分始终在 100 分附近震荡。那“100 分”具体是个什么状态?就是机器人从头到尾几乎没扫出有效覆盖,路径基本是随机游走,一会儿撞墙,一会儿原地转圈,回合结束时覆盖率可能只有 8% 到 15%。由于碰撞扣分和时间扣分的存在,勉强把分数压在 100 分上下。这其实不是机器人蠢,而是梯度信号太弱,PPO 在这种反馈下学到的策略和一个随机策略没什么区别。我以为加一个最终完成奖励就够了,后来才发现,清扫任务里的“大目标”必须被拆碎,才能让机器人看得见摸得着。

2. 我最初的奖励函数是怎么把训练带进死胡同的

2.1 第一版奖励函数的组成与直觉

被稀疏奖励教育之后,我的第一反应是常见的做法:加几个密集型奖励,让机器人每一步都能收到反馈。当时我设计了这样一套奖励:

奖励项表达式权重设计意图
覆盖面积增量每新扫一个栅格+0.05/格鼓励多扫
清扫电机开启开启清扫电机且移动+0.02/步确保机器人边动边扫
时间惩罚每步-0.01/步提高效率
碰撞惩罚每次碰撞-0.1/次避免撞墙
完成奖励覆盖率大于90%+1.0/次任务完成

刚上手时训练曲线确实涨了一波,从 100 分爬到了 150 分左右。但再往后就卡住了,而且卡得很诡异:覆盖率停在 30% 出头,epsode 长度越来越长,机器人看起来忙忙碌碌,但扫过的区域始终只有那么一小块。我把训练日志调出来看,发现了一个典型的“奖励钻空子”问题——机器人学会了原地抖动。

2.2 卡住的原因:奖励分量之间的冲突与漏洞

问题出在“清扫电机开启 + 移动”这个持续奖励上。机器人在墙角附近来回磨蹭,轮子在转,电机在开,但它实际上反复压着同一小片区域,新覆盖几乎没有增加。因为这组动作既能吃到电机开启奖励,又不会因为碰撞被扣太多分,时间惩罚的力度又不足以压过这个收益。于是策略收敛到了一种“伪勤奋”状态:有动作、有移动、有清扫声,就是不干活。

另一个问题是覆盖面积增量的权重太轻。假设一个新栅格只有 0.05 分,而原地抖动每步能拿 0.02 分,只要抖上三步就超过扫一个新格的收益。更麻烦的是,实际清扫中每扫一个新格需要跨越一段距离,这段距离里没有任何奖励,只有时间扣分。这让机器人更倾向于“短周期高频率的小动作”,而不是“长距离高效清扫”。第一版奖励的坑在于:我奖励的是“行为过程的表面特征”,而不是“清扫目标的行为结构”。每个拆出来的奖励项都依赖一个具体可观测的信号,但如果信号本身可以被廉价伪造,策略就会去伪造信号。

所以后来我做了一个决定:不再单纯堆正奖励,而是把“清扫覆盖率”“动作连贯性”“路径效率”和“安全性”拆成一组互相牵制的复合奖励,让每一项都对应一个不能轻易钻空子的行为指标。

3. 10 项复合奖励的拆解与设计动机

3.1 设计总原则:每一项都要能独立被观测、被问责

复合奖励不是简单地把很多小奖励加起来,而是要设计一套“互相补位、互相约束”的体系。我在设计时给自己立了三条规矩:

  • 每一项奖励都必须能准确计算出数值,而且这个数值不能被机器人通过高频重复动作刷爆。
  • 每一项奖励的期望贡献要设一个上限,不允许某一项在梯度中占据绝对主导地位。
  • 每一项奖励都要对应一个我真正关心的行为:覆盖新区域、避免重复、保持连贯、保证安全、尽快收工。

基于这三条,我把最终版本梳理成 10 项,分为四个维度:覆盖率、路径效率、安全约束、任务完成。下面先把完整清单列出来,再逐个讲我为什么这么设计。

3.2 最终版 10 项复合奖励清单

编号奖励项计算方式建议权重作用
R1覆盖新网格奖励每新增一个被清扫的栅格+0.3/格直接推动覆盖率提升
R2覆盖保持奖励当前覆盖率与上一步覆盖率之差+0.8 × Δcoverage让覆盖率上升趋势本身成为信号
R3区域探索奖励机器人首次进入一个宏观子区域+1.0/次鼓励去远的地方,避免局部过扫
R4重复覆盖惩罚每压过一次已覆盖栅格-0.02/格阻断原地蹭奖励的路径
R5清扫效率奖励单位时间新覆盖面积 ≥ 阈值时+0.05/步平衡速度与清扫效果
R6急转弯惩罚角速度绝对值超过阈值-0.2/次防止原地转圈和抖动
R7碰撞惩罚发生碰撞-0.5/次训练避障能力
R8贴近边界惩罚与障碍物或墙体距离小于安全距离-0.1 × (1 - d/d_safe)让机器人能沿着墙走但不硬贴
R9任务完成奖励覆盖率首次达到 95%+10.0/次强化完整清扫的收尾行为
R10时间惩罚每个仿真步-0.001/步保持基本效率,但不做主导

你可能已经发现了,这套奖励里没有“清扫电机开启”这种过程性奖励。我刻意删掉了所有“做了某个动作就给分”的设计,转而只奖励“产生了某个可验证的结果”。比如 R1 奖励新增的栅格,这必须是真的扫到了之前没扫过的地方;R5 奖励效率,要求新覆盖面积对照行驶距离不能太低。这些信号机器人不容易伪造,因为它要同时满足多个条件才能拿到奖励。

3.3 每项奖励到底在牵制什么行为

R1 和 R4 是一对天然的对抗组合。R1 鼓励去没扫过的地方,R4 惩罚扫过的地方,合在一起,机器人就不会在原地反复磨蹭,因为原地动作不仅没有新覆盖,还会因为重复覆盖被倒扣分。R4 的权重不能太大,否则机器人会为了不重复覆盖而刻意避开一些必须经过的路径,导致覆盖率永远上不去。我的 R4 权重从 -0.05 一路试到 -0.02,最终在覆盖率上限和重复行为之间找到了平衡。

R3 是为了解决一个很隐蔽的问题:覆盖率奖励容易让机器人只扫入口附近的一片区域,因为那里起点近、风险低,扫起来“性价比高”。如果没有区域探索奖励,它永远不会主动离开舒适区。我在地图上预先划分了一些宏观子区域,只要机器人第一次进入某个子区域,就给一个一次性奖励。这个奖励不需要很大,但它能在早期训练中非常有效地把机器人“推”向远方。

R6 和 R5 共同压制动作抖动。急转弯惩罚直接给角速度绝对值设了一个物理上的“红线”,一旦超过阈值就扣分。在连续控制任务里,很多策略都会出现高频抖动,这在物理仿真里看起来是“微操”,实际上完全是噪声。急转弯惩罚把这种噪声的收益压成负数,倒逼策略输出平滑的角速度命令。

R7 和 R8 是安全礼仪。碰撞惩罚用于训练基本的避障反射,但光有碰撞惩罚不够,因为机器人可以离墙一毫米前进,不碰墙,但视野全被墙挡住。R8 的贴近边界惩罚让它和墙体、障碍物保持一个合理的距离,这样既不会撞,又能留出清扫通道。这两个奖励合起来,能稳定避免“贴着墙走但不扫墙边”的行为。

R9 的单次奖励很大,但只在覆盖率首次达到 95% 时触发。这个值不能设得太低,否则机器人学到的策略是“扫个八九成就收工”;也不能设得太高,比如超过 100%,那几乎永远拿不到,形同虚设。95% 是我测试下来比较合适的完成线,既能让机器人有动力去覆盖边边角角,又不至于因为地图上某几个不可达栅格而一直卡着完成不了。

4. 权重标定:让每一项奖励都“可感知、不打架”

4.1 单个奖励项的量纲必须单独标定

10 项复合奖励的坑点不是“项太多”,而是“每一项的量纲和量级完全不同”。R1 是每格 +0.3,R4 是每格 -0.02,R6 是每次 -0.2,R9 是一次 +10。如果直接全开,梯度一定会被 R9 和其他高频奖励之间的数量级差距搅乱。更麻烦的是,同一个项在不同训练阶段出现的频率不一样:早年间可能一次回合只扫 20 个新格,后期能扫 200 个新格,所以同一个权重在早晚期的贡献占比是动态变化的。

我的做法是先做“单因子标定”:把除某一项之外的所有奖励全部关掉,只保留这一项,然后用同一个环境跑 10 万步,观察机器人会收敛成什么行为。比如只开 R1,机器人会向远处冲,因为远处新栅格多;只开 R4,机器人会原地一动不动,因为不动就不会重复覆盖;只开 R6,机器人会直直地走直线,因为连续直行角速度为零。这个实验虽然原始,但非常直观地告诉我每一项的“能力上限”和“副作用区间”。

4.2 用奖励预算控制每个维度的贡献比例

在单因子标定之后,我把每一项在“成功清扫一个完整回合”中的理论最大贡献算了一遍。一个成功回合大约需要 1000 步,覆盖 2800 个栅格,走过大约 15 米路径,碰撞 0 次。我按这个成功轨迹估算各项的最大累计奖励:

  • R1 新网格:2800 × 0.3 = 840
  • R2 覆盖保持:覆盖率从 0 到 95%,总差大约 0.95 × 1200 = 1140(取决于我设定的覆盖区域总数)
  • R4 重复覆盖惩罚:如果只在必要路径上重复,约 -30
  • R9 任务完成:+10
  • R10 时间惩罚:-1

这样一看,R1 和 R2 加在一起占据了整场奖励的绝大部分,这符合“清扫覆盖率是主目标”的定位。但 R3、R5、R7、R8 加起来也不能完全忽略,它们负责约束行为边界。我给自己定的规则是:非覆盖率类奖励的总预算不超过 15%。如果某次训练发现探索奖励的总贡献快要追上覆盖率奖励了,就说明探索奖励权重太高,机器人会为了探路而忘了清扫,需要调低。

4.3 权重调整的实操经验

在权重试错阶段,我踩过一个典型的坑:把 R1 从 0.3 调到 1.5,以为“覆盖率动力更足”,结果训练反而更差了。原因是覆盖率栅格传感器存在边缘噪声,机器人反复移动会让某些边界栅格被重复判定为“新增”,它学会了利用这个噪声刷 R1。后来我把权重调回 0.3,同时把 R4 的惩罚力度从 -0.01 调到 -0.02,才把这个投机行为压制住。

我还发现,R8 贴近边界惩罚最好配合 R5 效率奖励一起调。如果只加 R8,机器人会离墙太远,扫不到墙角;如果只加 R5,它会为了效率指标专门挑空旷区域跑,把墙角全留给未覆盖状态。最后我的组合是:R8 权重 0.1,R5 权重 0.05,让机器人在“离墙近一点”和“单位时间覆盖面积达标”之间自己找一个折中策略。这个折中结果比较接近人类扫地的方式:沿着边缘扫,但不死贴。

5. 分阶段课程训练:从“会走路”到“会扫地”再到“扫得划算”

5.1 为什么要分阶段,而不是一次性全量奖励

10 项复合奖励一次性全开,会让 PPO 的策略网络在刚开始训练时面对一个过于复杂的目标函数。前 30 万步里,机器人连“不撞墙”都还没学会,就要同时考虑“覆盖率增量”“重复惩罚”“探索奖励”和“任务完成”,结果样样都想要,样样都学不好。我在实验里对比过两种打开方式:全项从 0 万步开始,和前 50 万步只开部分项、之后逐步加项。第二个方案的综合分不仅最终更高,而且训练曲线的方差明显更小。

这其实就是课程学习最简单的应用:把任务难度按阶段拆开。清扫任务的难度阶梯在我看来是——先保证能安全移动,再学会覆盖新区域,最后优化路径重复和效率。每个阶段只改变一到两个奖励项,让策略网络在相对稳定的目标下收敛,而不是频繁被新增的梯度方向打断。

5.2 三个阶段的具体划分与分数里程碑

阶段 A:基础运动与避障,0 到 50 万步。

这个阶段只开 R6、R7、R8、R10。目标是让机器人知道“移动是安全的,但有代价;碰撞和急转要尽量避免”。评估指标不是覆盖率,而是单个回合中平均累计碰撞次数、平均移动距离和任务完成时间。大约 20 万步后,机器人已经能稳定地在一片空地图里绕圈走不撞墙,单回合平均移动距离从十米提升到五十米。在这个阶段结束时,我测过综合分,已经在 220 分左右了,因为覆盖率虽然还是不高,但碰撞扣分大幅减少,时间惩罚也降了下来。

阶段 B:学习清扫覆盖,50 万到 150 万步。

在阶段 A 的基础上,打开 R1、R2、R9。R9 的任务完成奖励从阶段 B 开始就存在,因为此时机器人已经能安全移动,应该开始理解“完成一个清扫任务”是什么概念。这一阶段的训练目标是让覆盖率从 30% 爬到 70% 以上。150 万步结束时,单回合平均覆盖率能到 78%,综合分爬到 430 分左右。但这时候路径效率很糟,会出现大量“回头路”:把一个地方扫干净后,又要绕个圈子再回到未覆盖区域,时间浪费明显。

阶段 C:优化路径效率与行为细节,150 万到 300 万步。

最后打开 R3、R4、R5,并把 R1、R2 的权重保持住。这一阶段重点惩罚重复覆盖和过远绕行,同时用 R3 鼓励探索新子区域。训练曲线在阶段 C 开始后的前 20 万步有过一次小回退,综合分从 430 掉到 380 左右,原因是 R4 的出现让机器人暂时“不敢动”了——它害怕走过已覆盖区域被扣分。我把 R4 的权重在过渡期做成了线性上升:先 0.0,用 5 万步慢慢升到 -0.02。这样策略有时间适应新约束。阶段 C 后半段,覆盖率开始稳定在 90% 以上,单回合碰撞几乎归零,综合分最终爬到 778 分并且稳定住了。

5.3 阶段切换的过渡技巧

阶段切换不是直接改奖励函数,那样会让策略突然面对一个完全不同的目标函数,很容易发生灾难性遗忘。我用了“权重线性插值”的方式:假设阶段 B 的 R4 权重是 0,阶段 C 的目标权重是 -0.02,那么我让它在 5 万步内从 0 线性变化到 -0.02。同理,R3、R5 也是线性引入。这个方法效果很好,策略没有出现明显的崩溃,只有短时间的适应波动。

每个阶段结束后,我会冻结当前权重,多跑 2 万步做一次评估,确保分数不是偶然结果。如果两次评估的差值超过 20 分,我就要检查是不是某个奖励项的观测值有噪声,或者权重设定过于极端。稳定性的价值在奖励工程里被很多人低估,一次偶然的高分不值得信任,必须连续多次采样取平均。

6. 训练配置、可复现代码与奖励钻空子的围堵

6.1 环境、算法与超参数

我用的仿真环境是自己搭的 2D 栅格清扫环境:一个 20m × 20m 的房间,里面有固定障碍物,机器人是一个差分驱动小车,车头装了一个可以检测“当前栅格是否已被清扫”的传感器。状态向量包含机器人位姿、当前时刻已覆盖栅格的位置索引(压缩成一个小的网格矩阵)、近程激光雷达测距值。动作是二维连续向量:线速度范围 [-0.5, 0.5] m/s,角速度范围 [-1.5, 1.5] rad/s。

算法用的是 PPO,因为它在连续控制任务里最稳定,调参空间不大。网络结构很简单,两层 MLP,每层 256 个神经元,没有用 LSTM。超参数如下:

参数值
γ0.99
GAE λ0.95
学习率3e-4
n_steps2048
batch size64
clip range0.2
训练步数300 万

这个配置不是我拍脑袋定的,而是从大量网格搜索里选出来的。学习率 3e-4 是 PPO 比较稳的起点,batch size 太小容易让奖励方差变大,太大又会让策略更新太慢。我没有刻意调网络宽度,因为奖励工程已经是主要优化点,网络只要能把状态映射到动作就行,复杂结构反而容易过拟合到奖励噪声上。

6.2 核心奖励函数代码示例

下面是我在环境 step 中计算 10 项奖励的核心代码,省略了部分环境内部函数,但奖励逻辑是完整可读的:

def compute_reward(robot_state, env_state, action, prev_state): """ 返回 reward, info 其中 prev_state 记录了上一帧的覆盖率信息,用于计算增量 """ reward = 0.0 info = {} # 环境提供的信息 coverage_now = env_state["coverage_ratio"] # 当前覆盖率 0-1 new_covered_grids = env_state["new_covered_grids"] # 本步新增覆盖栅格数 repeated_grids = env_state["repeated_grids"] # 本步重复覆盖栅格数 collision = env_state["collision"] # 本步是否碰撞 min_dist_to_obstacle = env_state["min_dist_to_obstacle"] angular_velocity = action[1] moved_distance = env_state["moved_distance"] step_cost = env_config["step_cost"] # R1: 覆盖新网格奖励 r1 = 0.3 * new_covered_grids reward += r1 info["r1_new_grid"] = r1 # R2: 覆盖保持奖励(覆盖率上升的增量) delta_coverage = coverage_now - prev_state["coverage_ratio"] r2 = 0.8 * max(0.0, delta_coverage) reward += r2 info["r2_coverage_hold"] = r2 # R3: 区域探索奖励(首次进入新子区域) r3 = 0.0 if env_state["enter_new_subregion"]: r3 = 1.0 reward += r3 info["r3_explore"] = r3 # R4: 重复覆盖惩罚 r4 = -0.02 * repeated_grids reward += r4 info["r4_repeat"] = r4 # R5: 清扫效率奖励(单位距离新覆盖面积不低于阈值) r5 = 0.0 if moved_distance > 0 and new_covered_grids / moved_distance > 0.5: r5 = 0.05 reward += r5 info["r5_efficiency"] = r5 # R6: 急转弯惩罚 r6 = 0.0 if abs(angular_velocity) > 0.8: r6 = -0.2 reward += r6 info["r6_sharp_turn"] = r6 # R7: 碰撞惩罚 r7 = -0.5 if collision else 0.0 reward += r7 info["r7_collision"] = r7 # R8: 贴近边界惩罚 r8 = 0.0 safe_dist = 0.3 if min_dist_to_obstacle < safe_dist: r8 = -0.1 * (1 - min_dist_to_obstacle / safe_dist) reward += r8 info["r8_near_wall"] = r8 # R9: 任务完成奖励 r9 = 0.0 if coverage_now >= 0.95 and not prev_state["task_done"]: r9 = 10.0 reward += r9 info["r9_task_done"] = r9 # R10: 时间惩罚 r10 = -step_cost reward += r10 info["r10_time"] = r10 return reward, info

这个函数在实际训练里会放在环境的 step 里,每个仿真步调用一次。建议每次调用后把 info 里的各个分量都塞进 TensorBoard,而不是只看总 reward。因为总 reward 会掩盖单个分量的异常,只有把每个 r1 到 r10 拆开看,才能知道策略到底在钻哪个空子。

6.3 我遇到的三次奖励钻空子事件及围堵手段

第一次是刷探索奖励。阶段 C 引入 R3 后,机器人学会了在地图上沿子区域边界来回横跳:一只脚踏进新子区域拿奖励,马上退回来,再踏进去再拿奖励。我一开始给 R3 设的是“每次进入子区域 +1.0 且不限制次数”,结果它一回合能横跳几十次。后来我把 R3 改成“每个子区域只能触发一次”,并在代码里用 set 记录已触发过的子区域编号,这个漏洞就堵上了。

第二次是刷覆盖率增量。R2 的覆盖率增量奖励本意是鼓励覆盖率持续上升,但机器人发现通过反复小幅度移动,可以让栅格地图边缘的传感器噪声把某些已覆盖栅格判定为“新覆盖”,从而反复获得 R2。我加了两个限制:一是覆盖率增量需要连续 N 步为正才给奖励;二是对“新增栅格数”做一个绝对下限,新增太少就不算有效增量。这两个限制一起用,策略就不再去抠传感器噪声了。

第三次是刷效率奖励。R5 的条件是“单位距离新覆盖面积大于阈值”,机器人学到的方法是高速冲进一片开阔空区,一口气扫很多新格,然后立刻停下,因为这个条件只看单步的比例。后来我把 R5 改成了“滑动窗口平均”:取最近 20 步的新覆盖总面积除以总行驶距离,超过阈值才给奖励。这个修改让机器人没办法用单步冲量来骗奖励,必须持续保持合理的扫动节奏。

这三件事让我养成一个习惯:每次新增一个奖励项,先只开这一项,盯着该项的累计曲线跑 10 万步,确认没有漏洞后再和其他项合并。奖励工程一半的功夫在防钻空子上,这句话一点不夸张。

7. 778 分之后:奖励工程的边界与下一步

778 分并不是一个“刷分”的结果,它对应的是当前环境、当前地图布局下,覆盖率接近 95%、碰撞接近零、时间惩罚也很低的稳定状态。我试过把 R1 权重继续往上加到 0.5,分数没有明显变化,反而因为过分强调覆盖率增量,机器人开始在小角落来回磨蹭。这说明 778 分附近已经进入了奖励函数能压榨出的物理上限——在杂乱地图里,覆盖率和路径效率本质上存在矛盾,想 100% 覆盖必然要绕一些重复路,想完全没有重复覆盖就不可能扫干净角落。

要继续涨分,不应该再继续调奖励权重了,而是要换环境。我目前在做两件事:第一,对不同房间布局做域随机化,让机器人在多样化的起点、障碍物位置和房间长宽比中训练,提升泛化能力;第二,把奖励项本身也做随机化,举个例子,让 R1 的权重在训练过程中以很小的幅度抖动,这样可以让策略不记忆某个固定的权重,在更大的奖励空间里找到更鲁棒的策略。

最后说一点个人体会。奖励工程是强化学习落地里最便宜也最危险的部分。它不需要大算力,不需要复杂模型,但每一个奖励项都是你作为人类先验塞进学习系统里的。先验塞得太少,训练不收敛;塞得太多,策略过拟合。我在这个项目里学到的平衡方式是:只把“清扫干净、避免重复、动作连贯、保持安全”这几条核心的人类常识编码进奖励,剩下的路径规划、转向策略、避障方式,全部交给算法自己去探索。10 项复合奖励只是我的答案,你的机器人、你的任务、你的环境可能只需要 8 项,也可能需要 15 项。真正值钱的是我搭起来的这套工作流——单因子标定、奖励预算控制、分阶段引入、分量日志监控。有了这套工作流,任何一项奖励的增加或修改都可以被快速观察、快速验证、快速回滚,这比纠结某一次的具体权重有用得多。

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

JMeter脚本助手Skill:让AI生成BeanShell与Groovy压测片段

做接口压测这些年&#xff0c;我在 JMeter 里写过的脚本片段&#xff0c;加起来能绕线程组转三圈。BeanShell 断言、JSR223 前置处理器、Groovy 签名、参数化文件读取——每一样都是现用现搜&#xff0c;或者从旧项目里翻出来改。时间长了你会发现&#xff0c;真正花时间的不是…

作者头像 李华
网站建设 2026/10/17 5:10:48

达芬奇Configurator模块复制全指南:配置备份迁移与避坑实战

用达芬奇做了几年项目之后&#xff0c;我越来越明确一个体会&#xff1a;真正决定效率的往往不是电脑配置&#xff0c;而是软件打开那一刻&#xff0c;整个界面、快捷键、数据库连接、缓存路径能不能和以前一模一样。谁都会有换工作站的经历&#xff0c;系统装好、软件装好只是…

作者头像 李华
网站建设 2026/10/17 5:10:47

Unity坐标空间解析:裁剪/视口/屏幕空间取值范围与转换陷阱

1. 为什么“视口空间到屏幕空间坐标范围”这个问题总在深夜报错时才浮出水面我第一次被这个问题按在地上摩擦&#xff0c;是在一个跨平台UI动效项目收尾阶段。当时所有逻辑在编辑器里跑得飞起&#xff0c;可一打包到安卓真机&#xff0c;按钮点击区域就整体偏移了三分之一——明…

作者头像 李华
网站建设 2026/10/17 5:10:45

用Python玩转正态分布:生成、可视化与检验实战指南

在数据分析这个行当里&#xff0c;“正态分布”大概是出现频率最高的统计名词。我早先接手过一个交易数据清洗的项目&#xff0c;需求很简单&#xff1a;把异常订单挑出来。当时第一反应就是用均值加减三倍标准差做过滤&#xff0c;结果筛出来的全是正常订单&#xff0c;真正的…

作者头像 李华
网站建设 2026/10/17 5:09:44

libuv idle句柄详解:事件循环空闲任务与CPU优化实践

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

作者头像 李华