深夜的夜市,阿明端着一碗滚烫的酸辣汤在窄巷里赶路,迎面来了同样端着汤的阿花。没有人喊“你往左我往右”,两人却像排练过一样,各自往右挪了半步,擦肩而过,汤一滴没洒。ORCA(Optimal Reciprocal Collision Avoidance,最优互惠碰撞避免)算法,就是想让机器人学会这套“夜市默契”:不靠通信、不靠中央指挥,每个智能体自己扫一眼周围人的位置和速度,判断“继续这么走会不会撞”,然后每个人都只改一点点方向——你让一半,我让一半——最后选一个“既能最快到达目标、又不会撞上任何人”的速度。这个判断在每一瞬间重复:看一眼,算一下,迈一步。整个过程决定了人群仿真里成千上万虚拟行人的流动、仓库里几百台机器人的穿梭,是“规划与控制”中最贴近日常直觉的一课。
对 AI 从业者而言,ORCA 是“感知—决策—执行”闭环中决策层的经典范式。理解它,你就能读懂多智能体系统、机器人导航项目的核心模块,也是从仿真走向实际部署的必经之路。
可视化演示
可视化展示ORCA算法速度障碍几何构造、多智能体互惠避障策略及参数调节效果,交互调节参数体验动态障碍物避障核心原理。
本节配有交互动效(进入视口后自动加载,约 3KB)。
速度障碍几何构造 速度障碍VO为禁止速度集合的锥形区域 智能体需选择VO外速度避免碰撞 VO = {v : ∃t>0, λ(v)∈D} 速度障碍是ORCA算法的理论基础
动态避障难题
阿明第一次去夜市摆摊,打开导航 App,里面画着一条从家到街口的蓝色路线。可真的走起来,他发现地图是死的:昨天的糖葫芦摊今天换成了套圈摊;前面的大爷忽然停下拍照;一个小孩从摊位间蹿出来。如果每遇到一次变化就掏出手机重新规划路线,等他走到摊位,酸辣汤早就凉透了。
机器人在真实世界也面临同样的尴尬。传统路径规划算法(如 A*、RRT)会先在地图上算出一条“从起点到终点”的几何路线,它默认世界是静止的。可一旦出现动态障碍——别的机器人、行人、车辆——这条预规划路线立刻失效。于是研究者把决策的粒度从“走哪条路”细化到“下一步用哪个速度”:不必预演整段路,只需在每个瞬间回答“此刻往哪走、走多快”。这个思路把问题搬进了“速度空间”:它像一张以速度分量为坐标的图纸,横轴是东西方向的速度,纵轴是南北方向的速度,图纸上的每个点都代表一种走法。再叠加“不能超速”的限制,就得到一个圆形的可达速度集合。
阿明恍然大悟:导航 App 管“长远方向”,而夜市里他真正需要的是“脚下这一步的速度”——目标由导航定,步伐由“速度空间里的安全集合”定。动态世界不欢迎“背地图”的人,只奖励“边走边看”的人。
- 速度平面把机器人的每个可能速度都当作平面上的一个坐标点
- 速度大小点到原点的距离就是“走多快”
- 上限约束物理极限画出一个圆,圆内才是可达速度
- 决策画布后面所有“找安全速度”的运算,都在这张圆盘上完成
速度障碍构造
阿明在窄巷里终于迎上了阿花。要判断会不会撞,他不需要预测阿花接下来十秒的完整轨迹——那太难了,夜市里也没人按轨迹走。他只需要盯住“相对速度”:把阿花的运动“叠加”到自己身上,假设自己静止、阿花以两人的速度差朝自己冲来。这道合成速度像一支箭,箭头的方向决定了会不会相撞。
更精确地说,从阿明的位置看过去,阿花不是一个小点,而是“阿明半径 + 阿花半径”这么粗的一根柱子。从自己脚下向柱子两侧各画一条切线,两条切线之间就形成一个锥形区域——如果“相对速度箭头”落在这个锥里,继续走就会撞上。这个锥形区域在数学上叫速度障碍(Velocity Obstacle,VO),它把所有“会撞的速度”集合成了一个几何对象。
速度障碍的胖瘦完全由几何决定:两人距离越近,锥越胖;半径和越大,锥越胖。距离无限远时,锥会缩成一条线,等于没有威胁。注意,这片锥形不是“地上不能走的路”,而是“不能用这些速度走路”——同样的位置,换个速度方向照样过得去。
阿明发现这招很省脑力:不用猜阿花要去哪,只看“相对箭头”在不在锥里。箭头在锥外,放心走;箭头进了锥,就要想办法了。
- 相对速度把 B 的运动叠到 A 头上,两个人都在动就变成“一个人动、一个人静”
- 视线向量从 A 指向 B 的方向,是判断“有没有迎面而来”的基准线
- 夹角判定相对速度方向与视线的夹角小于半锥角,就判定为危险速度
- 半锥角由两人距离和安全半径之和反推,距离越近、半径越大,锥越胖
互惠避让策略
箭头进了锥,怎么办?最简单的想法是“我全让”:阿明猛往右闪。可如果阿花照直走,两人还是可能撞成一团——而且全让的效率极低,相当于两个人里只有一个人长眼睛。ORCA 的创始人想得更妙:既然双方都长着眼睛,为什么不让每个人都承担一半?
数学上,“全让”等于把相对速度箭头完全掰出锥;“各让一半”等于只做让箭头转出危险区所需的最小改动,记为向量 u,然后阿明承担 u 的一半,阿花承担另一半。这样两人的实际轨迹都只偏了一点点,擦肩而过的动作小到几乎看不出来。
这半步妙在何处?妙在约束的形态:把一个弯曲的“危险锥”变成一条直线。速度平面被一条直线切成两半,阿明只需要保证自己的新速度落在“安全的那一半”,这一半就叫半平面(half-plane)。约束从弯曲变直线,后续求解一下子就简单了。这也是 ORCA 里 "Optimal" 的含义——避让代价对双方都最优,而不是某一方独自吃下全部成本。
夜市里两人没有喊话、没有眼神确认,却同时右移半步——因为双方都默认对方“懂规矩”。ORCA 把这种默契写进了公式:我让一半,你也让一半,谁也不吃亏。
- 脱险向量把相对速度“掰”出碰撞锥的最小改动,像把弓弦掰回安全方向的最短一推
- 责任对半互惠的核心,阿明只承担一半改动,另一半留给阿花
- 新基准速度A 被期望偏转后的参考点,半平面的边界从它出发
- 安全侧判定与法向量 n 的点积非负,意味着新速度待在“安全这一半”里
最优速度求解
巷子不止有阿花。阿明左侧是烤串摊的油锅,右侧一个蹲着玩手机的小孩,后面还有一只横穿的小狗。每个“威胁对象”都给阿明贡献一条安全线(半平面的边界),这些线一围,就在速度图纸上圈出一块可以安全使用的区域。
问题变成:在这块可行区域里选哪个速度?选得太慢,到摊位时汤都凉了;选得离原本路线太远,可能撞进另一个摊。最自然的答案是:选“离自己想用的速度最近”的那个点。
那个“想用的速度”叫期望速度(preferred velocity),就是“没有障碍时我朝目标全速冲”的速度。找一个点,满足“所有安全线都不能越界 + 不超速”,同时离期望速度最近——这是一个典型的二维线性规划问题:约束全部是直线,目标是最短距离,现代实现里可以在毫秒级完成。
阿明把这套“圈禁区、找最近”演练了几次,发现它像夜市里走路的本能:眼睛扫一圈,心里把每个人“应该让开的方向”画成线,然后脚自动踩在“最顺又不撞”的那个速度上。
- 期望速度没有障碍时,朝目标全速走的“理想步伐”
- 可行域所有邻居半平面与速度圆盘的交集,通常是一个凸多边形
- 最近点目标在可行域里找离理想步伐最近的速度,安全与效率的平衡点
- 线性规划约束全是直线、目标是最短距离,这类 2D 问题求解极快
参数调节方法
阿明后来把另一个摊主也教会了这套避让法,却发现各人“性格”不同:有人远远看到人就绕开,走得四平八稳;有人贴着别人肩膀滑过去,惊险但快。差别在哪?在于三个旋钮。
第一个旋钮是时间视界 τ:只看未来几秒内会撞上的威胁。τ 大,30 米外的人也算进去,走得像过雷区,保守但绕路;τ 小,临到面前才躲,反应快但风险高。第二个旋钮是安全半径:在两人半径和之上额外加的余量 δ,相当于“礼貌距离”,留得越宽,走得越稳,路也越绕。第三个是最大速度,管体能上限。
工程上 τ 还直接决定了邻居搜索范围:只有“双方以最大速度相向而行、在 τ 秒内能碰面”的对象,才值得为它建约束。超出这个范围的智能体现在根本撞不上,理它纯属浪费算力。
阿明总结出一句口诀:敢闯夜市不是眼睛多尖,而是“看多远、留多宽、走多快”三个旋钮调得合适。调得太怂,汤凉了;调得太野,汤洒了。
- 安全间距把两人身体半径与额外余量加起来,等于把“礼貌距离”编码进了几何
- 锥角反推间距在总距离中占比越大,锥角越大,避让越早越保守
- 搜索半径时间视界乘上双方最大速度,圈出“眼下真有威胁”的距离范围
- 调参旋钮τ 管“看多远”,δ 管“留多宽”,v^max 管“能多快”
工程实现要点
避让规则想清楚了,还要能跑起来。阿明在夜市里走十米,眼睛扫了不下几十圈:看看谁靠近了,心里给每个人画个锥,把所有人的安全线叠在一起,选个速度,迈步。下一秒,世界变了,重来。
工程上这就是逐帧循环:感知(找邻居)→ 建锥(算 VO)→ 合并约束(所有半平面取交集)→ 解 LP(选最优速度)→ 更新位置(积分)。为了不卡顿,优化的重中之重是“邻居搜索”:用空间网格或哈希把世界分块,只查身边一小圈,而不是遍历全图所有对象。RVO2 这类成熟库就是靠这个技巧,把上千个智能体的仿真跑进了实时帧率。
每一步的数学非常简单:先用最优速度公式算出本帧速度,再用它推进位置。所谓“滚动时域”,就是永远只规划眼前一小步,世界变了就重算,绝不闭眼按预演走。
这套循环的本质是“滚动时域”思维:夜市的路况每秒钟都在变,但阿明只要保证“这一秒的速度是安全的”,走完全程自然安全。
- 每帧求解每个控制周期都重新解一次“最优速度”,而不是用上一次的结果
- 位置积分用当前速度把位置往前推一小步,速度是“怎么走”,位置是“走到哪”
- 步长与帧率或控制频率配合,一般取 10~100 毫秒一个周期
- 滚动时域永远只规划眼前一小步,路况变了就重算,这就是“边走边看”
应用与局限
阿明的默契法则,从两个人扩展到了五百人的庙会:所有人都不说话,人群却像鱼群一样自动分流、绕行——这就是人群仿真。把“人”换成仓库里的几百台送餐机器人,同一套“各让一半”让它们在货架间互不撞车,不需要中央调度逐帧指挥。
但默契也有失灵时刻。如果有个醉汉横冲直撞(不合作障碍),你让一半他补过来,照样撞上;如果巷口只容一人通过,两人都各让一半,可能僵在门前谁也没进去——这叫死锁。ORCA 是局部算法,它看不见全局,在 U 形墙、迷宫里会原地打转。它能保证“你让、我也让”时双方不错碰,却不能保证“你无论怎样都会到达目的地”。
这个“默契假设”在公式里藏得很深:B 的新速度也按“减去一半改动”来计算。只有当双方都遵守同一协议时,等式才成立。遇到墙、车、不看路的行人,这一假设就破裂了。
所以工程上 ORCA 从来不是孤军奋战:全局规划负责“去哪”,ORCA 负责“别撞”,再加上急停逻辑兜底。正如阿明的智慧是“看路”而不是“背地图”——看路的本事再大,也得先知道要去哪。
- 另一边的让步B 也承担一半责任,且方向与 A 相反
- 隐含协议公式成立的前提,是双方都按 ORCA 规则行动
- 假设破裂遇到墙、车辆等不合作物体,等式不再成立,需要额外兜底
AI 应用场景
游戏与 VR 人群仿真
阶段:决策与导航(局部避障层)
解决的问题:传统人群仿真让每个 NPC“照剧本走”,遇到动态行人只能排队等待或瞬移穿模,真实感差。用 ORCA 后,每个 NPC 实时看邻居、算速度障碍、各让一半,无需集中调度就能呈现自然流动的人群。
具体案例:某 VR 消防疏散演练系统用 RVO2 库驱动 500 名虚拟行人。疏散命令下达后,人群在烟雾与障碍物之间自动避让、分流、绕行,全程帧率稳定在 60 fps,训练者看到的拥堵与绕行模式与真实疏散高度一致。
仓储机器人集群导航
阶段:规划与控制(局部运动层)
解决的问题:传统 AGV 靠磁条或统一调度,增加车辆就要重铺场地,调度系统一旦宕机整场停摆。采用“全局任务规划器 + ORCA 局部避让”的分层架构后,机器人彼此不通信也能互让,系统鲁棒性大幅提升。
具体案例:某电商仓库部署 300 台潜伏式 AGV。顶层系统只下发“去哪个货架取哪个料箱”的目标,底层 ORCA 在交叉路口实时避让,车辆不再需要“红绿灯式”的排队等待,吞吐量提升约 35%。
无人机集群编队避障
阶段:决策与导航(机间安全层)
解决的问题:无人机集群执行灯光秀或巡检时,位置偏差、阵风扰动会造成机间碰撞;集中调度在大机群下延迟高、风险大。ORCA 作为机间安全层,让每架无人机用自己的感知估计邻居速度并实时微调。
具体案例:某 500 架无人机编队项目,在预设航点之外叠加 ORCA 避让层。当一架无人机因气流偏离预定位置时,相邻几架自动各让一半,编队整体在 0.3 秒内恢复队形,全程零碰撞。
Python 演示
import math class Agent: def __init__(self, x, y, gx, gy, radius, name, color): self.pos = [float(x), float(y)] self.goal = [float(gx), float(gy)] self.vel = [0.0, 0.0] self.radius = radius self.name = name self.color = color self.max_speed = 1.2 def norm_dir(v): length = math.hypot(v[0], v[1]) if length < 1e-9: return [0.0, 0.0] return [v[0] / length, v[1] / length] def wrap_angle(a): while a > math.pi: a -= 2 * math.pi while a < -math.pi: a += 2 * math.pi return a def preferred_velocity(agent): toward = [agent.goal[0] - agent.pos[0], agent.goal[1] - agent.pos[1]] dx, dy = norm_dir(toward) dist = math.hypot(toward[0], toward[1]) speed = min(agent.max_speed, dist) return [dx * speed, dy * speed] def orca_pair(a, b): diff = [b.pos[0] - a.pos[0], b.pos[1] - a.pos[1]] dist = math.hypot(diff[0], diff[1]) if dist < 1e-9: return False sight_angle = math.atan2(diff[1], diff[0]) cone_half = math.asin(min(0.95, (a.radius + b.radius + 0.1) / dist)) rel_v = [a.vel[0] - b.vel[0], a.vel[1] - b.vel[1]] rel_angle = math.atan2(rel_v[1], rel_v[0]) if abs(wrap_angle(rel_angle - sight_angle)) >= cone_half: return False target_angle = sight_angle + cone_half if wrap_angle(rel_angle - sight_angle) > 0 else sight_angle - cone_half speed = math.hypot(rel_v[0], rel_v[1]) new_rel = [math.cos(target_angle) * speed, math.sin(target_angle) * speed] u = [new_rel[0] - rel_v[0], new_rel[1] - rel_v[1]] a.vel[0] += u[0] / 2 a.vel[1] += u[1] / 2 b.vel[0] -= u[0] / 2 b.vel[1] -= u[1] / 2 return True def simulate(steps=120, dt=0.1): a = Agent(0.0, 0.0, 10.0, 0.0, 0.5, "A", "indigo") b = Agent(10.0, 0.0, 0.0, 0.0, 0.5, "B", "green") hit = False for step in range(steps): a.vel = preferred_velocity(a) b.vel = preferred_velocity(b) orca_pair(a, b) a.pos[0] += a.vel[0] * dt a.pos[1] += a.vel[1] * dt b.pos[0] += b.vel[0] * dt b.pos[1] += b.vel[1] * dt gap = math.hypot(b.pos[0] - a.pos[0], b.pos[1] - a.pos[1]) if step % 20 == 0: print("step{:>3d} | A=({:5.2f},{:5.2f}) | B=({:5.2f},{:5.2f}) | gap={:4.2f}".format( step, a.pos[0], a.pos[1], b.pos[0], b.pos[1], gap)) if gap < a.radius + b.radius: hit = True break print("结果:", "发生碰撞!" if hit else "互惠避让成功, 两智能体安全擦肩而过") print("最终位置: A =", a.pos, ", B =", b.pos) if __name__ == "__main__": simulate()
cone_half = math.asin(min(0.95, (a.radius + b.radius + 0.1) / dist))算出碰撞锥半角:距离越近、安全半径越大,锥越胖rel_v = [a.vel[0] - b.vel[0], a.vel[1] - b.vel[1]]计算相对速度,把“两人都在动”变成“一人动一人静”if abs(wrap_angle(rel_angle - sight_angle)) >= cone_half:判断“相对箭头”是否落在危险锥内,不在锥内就不需要避让target_angle = sight_angle + cone_half if ... else sight_angle - cone_half把相对速度方向“掰”到锥边界,这是最小改动u = [new_rel[0] - rel_v[0], new_rel[1] - rel_v[1]]求出让相对速度脱险的最小改动向量a.vel[0] += u[0] / 2` 与 `b.vel[0] -= u[0] / 2互惠核心:两人各承担一半改动gap = math.hypot(b.pos[0] - a.pos[0], b.pos[1] - a.pos[1])每步检查实际间距,验证是否真的没撞
常见误区
误区我以为 VO 圆锥是物理空间里的一片禁区,规划路径时要专门绕过那片红色扇形,就像绕开一堵墙一样。
正解VO 住在“速度空间”里,它的横纵坐标是速度分量而不是位置坐标。它回答的是“用什么速度会撞”,不是“哪里不能走”。同一个位置,只要换一个安全速度,照样过得去。就像夜市里两人迎面,危险的不是“你站的地方”,而是“你现在这个走法”。
为何常见:图形画在两人之间呈锥形,视觉上太像地图上的障碍区,让人误以为它在物理空间里。
误区把时间视界 τ 设得很大,把所有未来可能碰撞都考虑进来,应该最安全、最稳妥。
正解τ 太大意味着几十米外有人稍微偏一下你都要绕,路径极端保守,可能走走停停甚至死锁;τ 太小又来不及反应。τ 是“预见力”与“果断力”的平衡,工程上通常取 1~5 秒,并不是越大越好。
为何常见:直觉上“想得越远越稳”,却忽略了预测越远越不可靠、约束越多路越绕这个反效果。
误区只要用了 ORCA,机器人就再也不会发生碰撞了,可以放心大胆地跑。
正解ORCA 的保证建立在“所有智能体都按同一互惠规则行动”之上。换成不合作的障碍——静止的墙、不看路的行人、突然加速的车辆——互惠假设破裂,照样会撞。生产中常把 ORCA 当作“局部安全层”,配合全局规划与急停逻辑一起使用。
为何常见:演示视频里全是规规矩矩的智能体,协作得过于完美,给人一种“万能”的错觉。
误区有了 ORCA,就不需要 A*、RRT 这些全局规划了,机器人自己就能找到路。
正解ORCA 只解决“当前这一小步怎么迈”,不回答“往哪个方向最终能到目的地”。它在 U 形墙、迷宫等凹形障碍前会原地打转(局部最优),必须靠全局规划提供目标方向和期望速度。两者是“长远路线 + 脚下灵活”的分工,谁也替代不了谁。
为何常见:ORCA 本身就能让两个小球互相躲闪,看起来像“自己会走路”,掩盖了它依赖目标输入这一事实。
面试题
Q1. ORCA 中“互惠”(reciprocal)最核心的含义是?
- A.智能体之间需要频繁通信
- B.双方各承担一半避让责任← 正确答案
- C.由中央服务器统一调度
- D.跟随前一个智能体轨迹
答案:B。ORCA 的“互惠”指两个面临碰撞的智能体各自承担一半避让责任,即把相对速度的最小改动 u 对半分摊。它恰恰不需要通信(A 错),也不是集中式调度(C 错)或队列跟随(D 错),而是“你我各让半步”的对等协作。
Q2. 速度障碍(VO)描述的是?
- A.物理空间中不可通行的区域
- B.会导致碰撞的速度的集合← 正确答案
- C.地图上的障碍物轮廓信息
- D.机器人刹车距离的计算值
答案:B。VO 是速度空间里的危险集合:只要 A 的速度落在集合内,就会在时间视界内与 B 相撞。A 把它当物理禁区是常见误解;C 是静态地图信息;D 是运动学估算,都与 VO 的定义不符。
Q3. 碰撞锥半角 α 主要由哪两项决定?
- A.双方距离与安全半径之和← 正确答案
- B.机器人最大加速度数值
- C.目标点与起点间长度
- D.邻居搜索树的深度
答案:A。α = arcsin((rA+rB)/‖pB−pA‖),距离越近、半径和越大,锥越胖,危险速度越多。加速度(B)、路径长度(C)、搜索树深度(D)都不进入这个几何公式,属于干扰项。
Q4. ORCA 半平面表示的是?
- A.三维速度空间中的一个平面
- B.速度平面中安全线的一侧← 正确答案
- C.物理位置空间中的半边圆弧
- D.加速度平面上的约束线
答案:B。从危险锥中取一条切线,把二维速度平面切成两半,安全的那一半就是半平面。因为责任对半分,A 只需待在自己这半边。A 的三维说法、C 把概念搬回位置空间、D 说成加速度空间,都搞错了所在的决策空间。
Q5. 多个邻居时,ORCA 如何选出最终速度?
- A.直接取所有邻居速度的平均
- B.交集中取离期望速度最近点← 正确答案
- C.始终选择最大速度向目标冲刺
- D.随机挑选一个邻居求解结果
答案:B。线性规划的目标正是“在可行域内最小化与期望速度的距离”,可行域是各邻居半平面与速度圆盘的交集。A 只做平均会无视避让约束;C 可能冲进危险速度;D 随机不保证安全。
Q6. 关于时间视界 τ,下列说法正确的是?
- A.τ越大避让越保守易绕路← 正确答案
- B.τ越小路径必然越短
- C.τ与邻居搜索范围无关
- D.τ越大越能保证零碰撞
答案:A。τ 把“未来几秒内可能撞”的危险速度都算进 VO,τ 越大避让越早越保守,路径更绕甚至死锁;τ 越小则临危才躲。D 错在:对不合作障碍,τ 再大也保证不了绝对安全。
Q7. 邻居搜索半径通常与哪个量直接相关?
- A.双方最大速度乘时间视界← 正确答案
- B.机器人自身质量多少
- C.全局规划路径长度
- D.目标点分布密集度
答案:A。邻居搜索只需覆盖“时间视界内双方可能接近的范围”,即 (vA^max + vB^max)·τ,超出这个范围的智能体现在撞不上,不必建约束。质量、路径长度、目标密度都与“哪些障碍当下有威胁”无关。
Q8. 下列哪种场景最容易让 ORCA 的互惠假设失效?
- A.两个机器人面对面相遇
- B.机器人遇到不看路的行人← 正确答案
- C.三个机器人交叉汇聚
- D.机器人最大速度偏小
答案:B。ORCA 假设“对方也会让一半”,行人若完全不改向,互惠分摊就不成立,可能相撞。A 与 C 中各方都按规则行动,存在可行解;D 只是速度慢,仍可按规则避让。
Q9. ORCA 属于“局部避让”,与全局规划配合时正确的认识有?
- A.可用 ORCA 完全替代全局路径规划
- B.全局规划负责给出目标与期望速度← 正确答案
- C.ORCA 负责实时处理动态障碍← 正确答案
- D.两者必须共享同一个坐标系
答案:BC。ORCA 只决定“当前这一步用多快的速度、朝哪偏一点”,需要全局规划提供目标方向(期望速度);它在 U 形墙前会陷入局部最优,替代不了全局规划,故 A 错。坐标系通常统一是工程要求,但并非 ORCA 算法的前提,D 过于绝对。
Q10. 工程实现 ORCA 时,常见的性能优化手段有?
- A.只用邻近智能体构造约束← 正确答案
- B.空间网格加速邻居搜索← 正确答案
- C.对全体智能体建立约束
- D.每帧把上一步速度当初值← 正确答案
答案:ABD。远处智能体在时间视界内撞不上,用空间网格只查近邻、只给近邻建约束,是 RVO2 等库的核心加速手段;C“全量建约束”浪费算力且无必要。D 是热启动技巧,把上一步解作为线性规划初值,能显著减少迭代次数。