MTC基础知识
一、MTC 到底是什么?
一句话:MTC 是一个任务级规划框架,把“抓取—移动—放置”这种复杂操作,拆成很多小步骤,每一步自动规划,最后拼成一条完整可行的机器人轨迹。
传统 MoveIt 你只能做:
-
“从 A 点规划到 B 点”
-
“沿直线走一段”
但真实任务是这样的:
打开手爪 → 移动到物体上方 → 生成抓取位姿 → 求 IK → 闭合手爪 → 附着物体 → 抬起 → 移动到放置点 → 下放 → 打开手爪 → 分离 → 撤退 → 回 home
这么多步骤,每步还有约束、碰撞、IK、成功/失败分支……
MTC 就是用来描述、规划、执行这种多步骤任务的。
二、MTC 的核心世界观:Stage(阶段)
MTC 把整个任务看成一棵树,树上的每个节点叫 Stage(阶段)。
每个 Stage 代表任务中的一步,比如:
-
“打开手爪”
-
“接近物体”
-
“生成抓取位姿”
-
“闭合手爪”
-
“抬起物体”
每个 Stage 有:
-
输入:一个或多个“世界状态”(机器人关节 + 场景)
-
输出:一个或多个“新世界状态”
-
规划器:怎么从输入算出输出
三、三类最关键的 Stage
MTC 里 Stage 分成三大类,这是最核心的知识点:
| 类型 | 作用 | 输入 | 输出 |
|---|---|---|---|
| Generator(生成器) | 凭空产生新状态 | 0 或 1 个 | 多个候选状态 |
| Propagator(传播器) | 从输入状态推导出输出状态 | 1 个 | 多个候选状态 |
| Connector(连接器) | 连接两个已有状态 | 2 个 | 中间轨迹 |
理解这三类,MTC 就懂一半了。
1. Generator(生成器)—— “凭空造状态”
特点:不需要输入状态,或者只需要一个参考状态,就能产生一批候选。
例子:
-
CurrentState:产生“当前世界状态”作为起点。 -
GenerateGraspPose:根据物体位姿,生成一堆可能的抓取位姿。 -
GeneratePlacePose:根据放置目标,生成一堆放置位姿。 -
DeepGraspPose:调用深度学习 action,生成抓取位姿候选。
类比:
你站在空地上,Generator 说:“我给你 10 个可能的抓取姿势,你挑。”
2. Propagator(传播器)—— “从一个状态推到下一个状态”
特点:有一个输入状态,输出一个或多个新状态。它不连接两个已知状态,而是“从当前状态出发,算出下一步”。
例子:
-
MoveTo:从当前关节状态,移动到指定关节目标。 -
MoveRelative:从当前位姿,沿某方向相对移动一段。 -
ComputeIK:从目标笛卡尔位姿,算出关节解。 -
ModifyPlanningScene:修改场景(附着物体、允许碰撞)。
类比:
你站在 A 点,Propagator 说:“从 A 出发,我带你走到 A'。”
3. Connector(连接器)—— “把两个状态接起来”
特点:有两个输入状态(前一个阶段的结束状态 + 后一个阶段的开始状态),生成中间轨迹。
例子:
-
Connect:把“打开手爪后的状态”和“抓取容器开始的状态”连接起来。 -
MoveTo在某些情况下也能当连接器用,但标准连接器是Connect。
类比:
你站在 A 点,目标在 B 点,Connector 说:“我帮你规划一条从 A 到 B 的路。”
关键区别:
-
Propagator:只知道自己从哪来,往哪走是它自己决定的。
-
Connector:知道起点和终点,负责把中间补上。
四、Container(容器)—— 把多个 Stage 打包
SerialContainer 和 ParallelContainer 是容器,不是阶段本身。
1. SerialContainer(串行容器)
把多个 Stage 按顺序串起来,前一个的输出是后一个的输入。
text
[接近物体] → [生成抓取] → [求IK] → [闭合手爪] → [附着物体] → [抬起]
整个串行容器对外看起来就像一个大阶段,可以整体插入任务。
2. ParallelContainer(并行容器)
把多个 Stage 并行组合,比如:
-
一个分支规划机械臂
-
一个分支规划手爪
-
最后合并
用于“同时做多件事”的场景。
五、Task(任务)—— 整棵树
Task 是 MTC 的顶层对象,里面是一棵 Stage 树。
cpp
Task t; t.add(std::move(stage1)); t.add(std::move(stage2)); ... t.plan(10); // 最多找 10 个解
规划时,MTC 会:
-
从
CurrentState出发 -
逐个展开 Stage
-
每个 Stage 产生多个候选
-
组合成多条完整解
-
返回前 N 个可行解
六、Interface(接口)—— Stage 之间传什么
每个 Stage 有输入接口和输出接口,里面存的是“世界状态”。
关键接口:
-
START:输入状态 -
END:输出状态 -
FORWARD/BACKWARD:方向
Stage 之间通过接口连接,前一个的 END 接到后一个的 START。
七、Solution(解)—— 一条完整轨迹
Task::plan() 返回多个 Solution,每个 Solution 是一条从开始到结束的完整轨迹。
执行时:
cpp
task_->solutions().front()->fillMessage(execute_goal.solution); execute_.sendGoal(execute_goal);
把第一条解发给 ExecuteTaskSolution action 执行。
八、用你给的代码串一遍
回到你那份 DeepPickPlaceTask:
cpp
Task t;
t.add(CurrentState + PredicateFilter); // Generator:当前状态
t.add(MoveTo "open hand"); // Propagator:开手爪
t.add(Connect "move to pick"); // Connector:移动到抓取前
t.add(SerialContainer "pick object"); // 容器:抓取流程
├── MoveRelative "approach object" // Propagator:接近
├── DeepGraspPose + ComputeIK // Generator + Propagator:生成抓取位姿并求IK
├── ModifyPlanningScene // Propagator:允许碰撞
├── MoveTo "close hand" // Propagator:闭合手爪
├── ModifyPlanningScene attach // Propagator:附着物体
├── MoveRelative "lift object" // Propagator:抬起
└── ...
t.add(Connect "move to place"); // Connector:移动到放置点
t.add(SerialContainer "place object"); // 容器:放置流程
├── MoveRelative "lower object"
├── GeneratePlacePose + ComputeIK
├── MoveTo "open hand"
├── ModifyPlanningScene detach
└── MoveRelative "retreat"
t.add(MoveTo "move home"); // Propagator:回 home
每一行都对应 MTC 里的一个概念。
九、一张总图
text
Task(整棵树)
│
├── Stage(阶段)
│ ├── Generator(生成器) → 凭空产生候选
│ ├── Propagator(传播器) → 从一个状态推到下一个
│ └── Connector(连接器) → 连接两个状态
│
├── Container(容器)
│ ├── SerialContainer(串行)
│ └── ParallelContainer(并行)
│
├── Interface(接口)
│ ├── START / END
│ └── FORWARD / BACKWARD
│
└── Solution(解)
└── 一条完整轨迹
十、最小记忆口诀
Generator 造,Propagator 推,Connector 接。
Serial 串,Parallel 并。
Task 是树,Solution 是路。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)