Repository navigation
Expand file tree
/
Copy pathgap.html
More file actions
242 lines (235 loc) · 157 KB
/
Copy pathgap.html
File metadata and controls
242 lines (235 loc) · 157 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Five six-minute visual essays and interactive experiments about task and motion planning.">
<title>Motion & Meaning — Five visual essays on robot planning</title>
<style>:root{--bg:#0b111b;--panel:#131d2b;--panel2:#182536;--ink:#edf2fa;--muted:#98a9bf;--line:#29384b;--accent:#69d5ec;--cyan:#69d5ec;--green:#82e1b0;--yellow:#f2c86d;--red:#f79c84;--purple:#b4a1ff;color-scheme:dark;font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font-size:15px;line-height:1.6}button,input,select{font:inherit}button,a,input,select{-webkit-tap-highlight-color:transparent}button,a{touch-action:manipulation}button{cursor:pointer}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,canvas:focus-visible{outline:2px solid var(--accent);outline-offset:5px}button:disabled{opacity:.4;cursor:not-allowed}.skip{position:fixed;top:-80px;left:20px;z-index:100;padding:12px;background:var(--ink);color:var(--bg)}.skip:focus{top:10px}.sidebar{position:fixed;inset:0 auto 0 0;width:238px;border-right:1px solid var(--line);padding:33px 23px;display:flex;flex-direction:column;background:#0f1722;z-index:20}.brand{display:flex;gap:13px;align-items:center;color:var(--ink);font-size:21px;font-weight:650;line-height:1.15;letter-spacing:-.7px}.brand:hover{text-decoration:none}.brand svg{width:44px;height:50px;flex:none;stroke:var(--cyan);fill:var(--bg);stroke-width:1.6}.brand>span{width:110px}.amp{font-family:Georgia,serif;font-style:italic;color:var(--cyan);margin-right:3px}.rail-label,.small-label,.section-label,.eyebrow,.topbar,.current-idea>span,.scope-tag{font-size:10px;letter-spacing:1.8px;font-weight:650}.rail-label{color:#778aa3;margin:55px 0 17px}.episode-button{display:flex;gap:11px;align-items:center;position:relative;width:100%;padding:15px 12px;border:1px solid transparent;background:transparent;color:var(--muted);border-radius:9px;text-align:left;margin-bottom:8px;line-height:1.35}.episode-button:hover{background:#182331}.episode-button.selected{border-color:#34475c;background:#1c2a3a;color:var(--ink)}.episode-button.selected:before{content:"";position:absolute;left:-24px;top:11px;bottom:11px;width:3px;background:var(--accent)}.ep-num{font-size:12px;color:var(--ep-color);font-variant-numeric:tabular-nums}.ep-title{display:block;font-size:14px;font-weight:600}.ep-type{display:block;margin-top:4px;font-size:11px;color:#8397b0}.rail-bottom{margin-top:auto;font-size:12px;color:var(--muted);line-height:2}.rail-bottom>span:last-of-type{font-size:11px;color:#6d829e}.live-dot{display:inline-block;width:6px;height:6px;background:var(--green);border-radius:50%;margin-right:6px}.rail-bottom>a{display:flex;justify-content:space-between;border-top:1px solid var(--line);padding-top:17px;margin-top:24px;font-size:11px;color:var(--ink)}main{margin-left:238px;padding:0 48px;max-width:1730px}.topbar{display:flex;justify-content:space-between;gap:20px;padding:29px 0;border-bottom:1px solid var(--line);font-size:10px;color:#9aadc5}.edition{color:#627995;letter-spacing:.2px;font-weight:400}.intro{padding:45px 0 28px;max-width:1010px}.eyebrow{display:flex;align-items:center;gap:13px;color:var(--accent)}.tiny-line{display:inline-block;width:24px;height:1px;background:var(--accent)}h1{font-family:Georgia,"Times New Roman",serif;font-weight:400;font-size:clamp(34px,3.7vw,61px);letter-spacing:-1.8px;line-height:1.13;margin:18px 0;max-width:940px}h2{font-size:24px;font-weight:550;letter-spacing:-.65px;line-height:1.25;margin:9px 0 13px}.dek{color:var(--muted);font-size:17px;margin:0;max-width:800px;line-height:1.7}.intro-links{display:flex;align-items:center;gap:24px;font-size:11px;margin-top:19px;color:#879ab1}.intro-links>a{font-weight:650}.intro-links>span:before{content:"·";margin-right:14px;color:#4b617a}.tabs{display:flex;gap:30px;border-bottom:1px solid var(--line);margin-bottom:26px}.tabs button{padding:13px 0 15px;color:#62788f;background:none;border:none;border-bottom:2px solid transparent;font-size:11px}.tabs button span{margin-left:7px;font-size:13px;color:var(--muted)}.tabs button[aria-selected=true]{color:var(--accent);border-color:var(--accent)}.tabs button[aria-selected=true] span{color:var(--ink)}[hidden]{display:none!important}.watch-layout{display:grid;grid-template-columns:minmax(0,1fr) 263px;gap:26px}.video-shell{overflow:hidden;border-radius:10px;background:#101722;border:1px solid var(--line);aspect-ratio:16/9}.video-shell video{width:100%;height:100%;display:block;background:#101722}.video-meta{display:flex;justify-content:space-between;gap:15px;margin-top:11px;color:#7e93af;font-size:10px}.video-meta a{white-space:nowrap}.current-idea{border-left:2px solid var(--accent);padding:0 17px;margin:28px 0 0}.current-idea>span{font-size:9px;color:#7189a5}.current-idea p{color:var(--accent);font-family:Georgia,serif;font-size:21px;margin:4px 0}.section-label{display:flex;justify-content:space-between;gap:8px;font-size:9px;color:#b4c1d3;border-bottom:1px solid var(--line);padding:0 0 13px}.section-label>span{color:#657c99;letter-spacing:.8px}#chapter-list{list-style:none;margin:8px 0 0;padding:0}#chapter-list button{width:100%;text-align:left;display:flex;gap:10px;background:none;border:0;border-radius:6px;padding:10px 7px;align-items:baseline;color:var(--muted);line-height:1.4}#chapter-list button:hover{background:var(--panel2)}#chapter-list button.active{color:var(--ink);background:#19283a}#chapter-list time{font-size:10px;color:var(--accent);font-variant-numeric:tabular-nums;flex:none}#chapter-list span{font-size:12px}.next-action{display:flex;align-items:center;justify-content:space-between;gap:30px;margin:40px 0 28px;border:1px solid var(--line);border-radius:9px;padding:25px 28px;background:linear-gradient(130deg,#172334,#101a27)}.small-label{color:var(--accent);font-size:9px}.next-action h2{font-size:23px;margin:8px 0}.next-action p{font-size:12px;color:var(--muted);margin:0;max-width:570px}.primary{background:var(--accent);color:#0d1a23;border:1px solid var(--accent);padding:12px 18px;border-radius:6px;font-weight:650;font-size:12px;white-space:nowrap}.primary span{margin-left:16px}.primary:hover{filter:brightness(1.09)}.secondary{background:var(--panel2);color:var(--ink);border:1px solid #354a63;border-radius:6px;padding:10px 14px;font-size:12px}.secondary:hover{background:#24374c}.experiment-heading{display:flex;justify-content:space-between;gap:20px;align-items:center}.experiment-heading h2{font-size:29px}.scope-tag{border:1px solid #4a4433;background:#24241e;color:#d6b877;padding:5px 9px;border-radius:5px;white-space:nowrap;letter-spacing:.3px;font-size:10px}.lab-intro{color:var(--muted);font-size:14px;max-width:920px;margin:0 0 20px}.lab-layout{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:0;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--panel)}.lab-stage{background:#0e1826;min-width:0;display:flex;flex-direction:column;justify-content:center}#lab{display:block;width:100%;height:auto;touch-action:none}.canvas-key{padding:10px 17px;border-top:1px solid #202d40;font-size:10px;color:var(--muted);display:flex;gap:20px;flex-wrap:wrap}.canvas-key i{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--key-color);margin-right:6px}.controls{padding:20px;border-left:1px solid var(--line);display:flex;flex-direction:column;gap:15px;justify-content:center}.control label{display:flex;justify-content:space-between;gap:10px;font-size:11px;color:#b1bfd2;margin-bottom:6px}.control output{color:var(--accent);font-variant-numeric:tabular-nums}.control input[type=range]{width:100%;accent-color:var(--accent);height:15px;margin:8px 0 0}.control select{width:100%;background:#0d1724;border:1px solid #34465d;color:var(--ink);padding:9px;border-radius:5px;font-size:12px}.checkbox{display:flex;gap:9px;align-items:flex-start;color:#b1bfd2;font-size:12px}.checkbox input{accent-color:var(--accent);margin-top:4px}.control-row{display:flex;gap:8px}.control-row button{flex:1}.controls .primary{width:100%}.code-block{font-family:ui-monospace,Menlo,monospace;white-space:pre-wrap;font-size:10px;line-height:1.7;color:var(--green);padding:10px;background:#0a121e;border:1px solid var(--line);border-radius:5px;margin:0;overflow-wrap:anywhere}.metric-row{display:flex;gap:12px}.metric-row>div{flex:1;background:#0b1522;border-radius:5px;padding:9px}.metric-row b{font-size:22px;color:var(--accent);display:block;line-height:1.3}.metric-row span{font-size:9px;color:var(--muted)}.control-note{font-size:10px;color:#7f93ad;margin:0;line-height:1.65}.readout{border-left:2px solid var(--accent);padding:0 18px;margin:24px 0}.readout p{margin:3px 0;color:#c7d5e5;font-size:14px}.explanation-grid{display:grid;grid-template-columns:1fr 1fr;gap:30px;border-top:1px solid var(--line);padding-top:22px}.explanation-grid p{font-size:12px;color:var(--muted)}.notes-grid{display:grid;grid-template-columns:1.5fr 1fr;gap:44px}.notes-grid h2{font-size:28px}.authors{font-size:12px;color:var(--muted)}.sources{display:flex;flex-direction:column;gap:8px;margin:22px 0;font-size:13px}.sources a:before{content:"↗ ";color:#7997b7}.note{font-size:12px;color:var(--muted);line-height:1.8}.text-link{font-size:12px;margin-right:16px}.takeaways{background:var(--panel);border:1px solid var(--line);border-radius:9px;padding:25px}.takeaways ol{padding-left:20px;margin:16px 0 0;color:#bfccde;font-size:13px}.takeaways li{padding:0 0 14px 5px}.transcript-heading{border-top:1px solid var(--line);padding-top:29px;margin-top:35px}.transcript-part{display:grid;grid-template-columns:65px 1fr;gap:20px;margin:25px 0}.transcript-part button{align-self:start;background:none;border:0;color:var(--accent);font-size:12px;padding:5px 0}.transcript-part h3{margin:0 0 8px;font-size:17px;font-weight:550}.transcript-part p{font-size:14px;color:#afbdd0;line-height:1.9;margin:0}.transcript-part small{display:block;color:#748aa5;font-size:11px;margin-top:9px}.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:9px}table{width:100%;border-collapse:collapse;font-size:12px;min-width:770px}th,td{padding:18px;text-align:left;border-bottom:1px solid var(--line);vertical-align:top}thead{background:var(--panel2);color:var(--accent)}tbody th{font-size:13px;color:var(--ink);min-width:130px}td{color:var(--muted)}.comparison-note{max-width:890px;font-size:15px;color:#b2c2d7;margin:25px 0}footer{display:flex;justify-content:space-between;gap:20px;padding:26px 0 28px;margin-top:34px;border-top:1px solid var(--line);color:#647d9b;font-size:10px}.footer-dot{margin:0 8px;color:var(--accent)}@media(min-width:1600px){main{padding:0 60px}.watch-layout{grid-template-columns:minmax(0,1fr) 300px}#chapter-list button{padding:13px 8px}#chapter-list span{font-size:13px}}@media(max-width:1200px){.sidebar{width:200px;padding:26px 17px}.rail-label{font-size:9px}.brand{font-size:19px;gap:9px}.episode-button{padding:13px 8px}.episode-button.selected:before{left:-18px}main{margin-left:200px;padding:0 28px}.watch-layout{grid-template-columns:minmax(0,1fr)}.chapters ol{display:grid;grid-template-columns:1fr 1fr;gap:3px 20px}.section-label{margin-top:4px}.lab-layout{grid-template-columns:minmax(0,1fr) 246px}.controls{padding:15px}.video-meta{font-size:10px}}@media(max-width:820px){.sidebar{position:static;width:100%;padding:18px 21px;border-right:0;border-bottom:1px solid var(--line)}.brand>span{width:auto}.brand{font-size:19px}.brand svg{width:32px;height:33px}.amp{margin:0 2px}.rail-label,.rail-bottom{display:none}#episodes{display:flex;gap:7px;overflow-x:auto;margin-top:19px;padding-bottom:2px}.episode-button{flex:0 0 auto;width:auto;margin:0;padding:9px 11px;gap:7px;white-space:nowrap;border:1px solid var(--line)}.episode-button.selected:before,.ep-type{display:none}.ep-title{font-size:11px}.ep-num{font-size:9px}main{margin-left:0;padding:0 22px}.topbar{padding:18px 0}.edition{display:none}.intro{padding-top:28px}.intro h1{font-size:42px;letter-spacing:-1.2px}.dek{font-size:14px}.intro-links{gap:14px;font-size:10px}.intro-links>span:before{margin-right:8px}.lab-layout{grid-template-columns:1fr}.controls{border-left:0;border-top:1px solid var(--line);padding:20px;display:grid;grid-template-columns:1fr 1fr;gap:16px}.controls>.code-block,.controls>.control-note,.controls>.metric-row{grid-column:1/-1}.next-action{padding:21px;align-items:flex-start}.next-action .primary{margin-top:7px}.notes-grid{grid-template-columns:1fr;gap:25px}.experiment-heading h2{font-size:25px}.scope-tag{font-size:9px;max-width:112px;white-space:normal;text-align:center}footer{font-size:9px;gap:15px}.takeaways{padding:22px}}@media(max-width:500px){main{padding:0 16px}.intro h1{font-size:36px}.intro-links{flex-wrap:wrap;gap:8px 16px}.tabs{gap:25px}.next-action{display:block}.next-action .primary{margin-top:20px}.video-meta{flex-wrap:wrap}.chapters ol{grid-template-columns:1fr!important}.explanation-grid{grid-template-columns:1fr;gap:10px}.controls{grid-template-columns:1fr 1fr;padding:15px}.control label{font-size:10px}.controls .primary,.controls .secondary{font-size:11px;padding:10px}.eyebrow{font-size:9px;letter-spacing:1px}.transcript-part{grid-template-columns:43px 1fr;gap:13px}.transcript-part p{font-size:13px}footer{display:block}footer>span{display:block;margin:5px 0}}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important}}
@media(max-width:820px){.brand br{display:none}.brand .amp{margin-left:4px}}
</style>
</head>
<body data-initial="gap">
<a class="skip" href="#main">Skip to lesson</a>
<aside class="sidebar">
<a href="#integrated-tamp" class="brand" aria-label="Motion and Meaning home"><svg viewBox="0 0 48 48" aria-hidden="true"><path d="M8 37 23 12 40 34M8 37 40 34"/><circle cx="8" cy="37" r="4"/><circle cx="23" cy="12" r="4"/><circle cx="40" cy="34" r="4"/></svg><span>Motion<br><span class="amp">&</span> Meaning</span></a>
<div class="rail-label">A VISUAL READING SERIES</div>
<nav id="episodes" aria-label="Choose a paper"></nav>
<div class="rail-bottom"><span class="live-dot"></span> 5 papers · 30 minutes<br><span>Watch an idea. Then change it.</span><a href="#comparison" id="compare-link">Compare the five papers <span>↗</span></a></div>
</aside>
<main id="main">
<header class="topbar"><span>ROBOTICS, MADE VISIBLE</span><span class="edition">A collection of original visual explainers</span></header>
<section class="intro" aria-labelledby="lesson-title">
<div class="eyebrow"><span id="episode-number"></span><span class="tiny-line"></span><span id="episode-meta"></span></div>
<h1 id="lesson-title"></h1>
<p class="dek" id="lesson-summary"></p>
<div class="intro-links"><a id="paper-link" target="_blank" rel="noopener">Read the paper ↗</a><span>6 min video</span><span>Interactive companion</span></div>
</section>
<div class="tabs" role="tablist" aria-label="Lesson view"><button role="tab" id="tab-watch" data-tab="watch" aria-selected="true" aria-controls="watch">01 <span>Watch</span></button><button role="tab" id="tab-explore" data-tab="explore" aria-selected="false" aria-controls="explore">02 <span>Explore</span></button><button role="tab" id="tab-notes" data-tab="notes" aria-selected="false" aria-controls="notes">03 <span>Notes & sources</span></button></div>
<section id="watch" class="tab-panel" role="tabpanel" aria-labelledby="tab-watch">
<div class="watch-layout"><div><div class="video-shell"><video id="film" controls playsinline preload="metadata" aria-label="Narrated paper explainer"></video></div><div class="video-meta"><span>Geometric animation · synthetic narration · English captions</span><a id="download-video" download>Download MP4 ↓</a></div><div class="current-idea"><span>THE IDEA ON SCREEN</span><p id="current-formula"></p></div></div><div class="chapters"><div class="section-label">IN THIS FILM <span>08 CHAPTERS</span></div><ol id="chapter-list"></ol></div></div>
<div class="next-action"><div><span class="small-label">MAKE THE IDEA YOURS</span><h2 id="try-title"></h2><p id="try-summary"></p></div><button class="primary" id="start-exploring">Open experiment <span>↗</span></button></div>
</section>
<section id="explore" class="tab-panel" role="tabpanel" aria-labelledby="tab-explore" hidden>
<div class="experiment-heading"><div><span class="small-label">INTERACTIVE EXPERIMENT</span><h2 id="lab-title"></h2></div><span class="scope-tag">Educational toy model</span></div>
<p class="lab-intro" id="lab-intro"></p>
<div class="lab-layout"><div class="lab-stage"><canvas id="lab" width="940" height="570" tabindex="0" aria-label="Interactive planning visualization"></canvas><div class="canvas-key" id="canvas-key"></div></div><div class="controls" id="controls"></div></div>
<div class="readout" aria-live="polite"><span class="small-label">WHAT CHANGED</span><p id="lab-status"></p></div>
<div class="explanation-grid"><div><span class="small-label">TRY THIS</span><p id="lab-challenge"></p></div><div><span class="small-label">HOW TO READ IT</span><p id="lab-scope"></p></div></div>
</section>
<section id="notes" class="tab-panel" role="tabpanel" aria-labelledby="tab-notes" hidden>
<div class="notes-grid"><div><span class="small-label">THE SOURCE PAPER</span><h2 id="full-paper-title"></h2><p class="authors" id="authors"></p><div class="sources" id="source-links"></div><p class="note">The animations, toy geometries, and numerical exercises are original explanations. They are not reproductions of the papers’ software or benchmarks. Paper-specific results are explicitly identified.</p><a id="transcript-download" class="text-link" download>Download transcript ↓</a> <a id="caption-download" class="text-link" download>Download captions ↓</a></div><div class="takeaways"><span class="small-label">THREE QUESTIONS TO CARRY FORWARD</span><ol><li>What is being searched: actions, continuous values, constraints, or programs?</li><li>What evidence makes a proposed behavior feasible?</li><li>Which assumptions connect the model to the physical world?</li></ol></div></div>
<h2 class="transcript-heading">Read along</h2><div id="transcript"></div>
</section>
<section id="comparison" hidden><div class="experiment-heading"><div><span class="small-label">THE WHOLE SERIES</span><h2>Same robot. Different questions.</h2></div><button id="close-comparison" class="secondary">Back to lesson</button></div><p class="lab-intro">An interpretive comparison of the five contributions. This is a reading guide, not a performance ranking.</p><div class="table-wrap"><table><thead><tr><th>Paper</th><th>Main contribution</th><th>What gets reasoned about</th><th>Key boundary</th></tr></thead><tbody><tr><th>Integrated TAMP</th><td>A survey of the coupled planning problem</td><td>Discrete actions and continuous feasibility</td><td>A family of methods, not one solver</td></tr><tr><th>PDDLStream</th><td>A declarative sampler interface and planning algorithms</td><td>Plans, stream dependencies, parameter bindings</td><td>Sampler contracts and model correctness</td></tr><tr><th>OWL-TAMP</th><td>Language-generated task constraints</td><td>Ordering sketches and continuous predicates</td><td>A checked constraint may still misstate intent</td></tr><tr><th>TiPToP</th><td>A modular perception-to-action system</td><td>Scene grounding, cuTAMP plans, execution</td><td>Reported execution has no visual replanning</td></tr><tr><th>GaP</th><td>Agent-generated and rehearsed skill graphs</td><td>Program structure and parameters across instances</td><td>Known workcell, bounded variation, available skills</td></tr></tbody></table></div><p class="comparison-note">“GaP reinvented TAMP” captures the family resemblance. More precisely, its outer search generates executable programs, while TAMP addresses coupled action and geometric planning. Those programs can themselves call motion planners or learned skills.</p></section>
<footer><span>Motion & Meaning <span class="footer-dot">·</span> Original visual essays</span><span><a href="https://gatech-rl2.github.io/reset-free-rl-explainers/">Reset-free RL collection ↗</a> · Sources attached to every lesson.</span></footer>
</main>
<script>window.EPISODES = [{"id": "integrated-tamp", "short": "Integrated TAMP", "number": "01", "color": "#69d5ec", "title": "When a plan meets the physical world", "paper": "Integrated Task and Motion Planning", "authors": "Caelan Reed Garrett, Rohan Chitnis, Rachel Holladay, Beomjoon Kim, Tom Silver, Leslie Pack Kaelbling, Tomás Lozano-Pérez", "year": "2021 · survey", "url": "https://arxiv.org/abs/2010.01083", "summary": "Why choosing actions and choosing motions are one coupled problem.", "sources": [{"label": "Garrett et al. · full survey", "url": "https://arxiv.org/abs/2010.01083"}, {"label": "Publisher · Annual Review 2021", "url": "https://doi.org/10.1146/annurev-control-091420-084139"}], "chapters": [{"title": "The deceptively simple request", "visual": "table", "equation": "Goal: On(cup, tray)", "points": ["A goal names a result", "A plan must physically reach it", "Geometry can change the action order"], "narration": "Put the blue cup on the tray. Three words seem to solve it: pick, move, place. But look at the red carton. The cup fits in the open space beside it; the gripper does not. A list of sensible actions has hidden a physical impossibility. This is our running miniature example, designed for this explainer. The first paper, Integrated Task and Motion Planning, is a survey by Caelan Garrett and colleagues, rather than a single new planner. Its organizing question is exactly this: how do we choose a sequence of actions while also finding the geometry that makes those actions possible? Watch the carton turn a motion problem into a task problem.", "source": "Survey §§1–2; original cup example", "start": 0, "duration": 43.232940072395756, "end": 43.232940072395756}, {"title": "Two spaces, one robot", "visual": "spaces", "equation": "state = (logical facts, continuous values)", "points": ["Discrete: which object, which action", "Continuous: poses, grasps, joint angles", "The same choice lives in both spaces"], "narration": "On the left is a small graph. Each arrow names an action: pick the cup, put down the carton, place the cup. On the right is a continuous space of possible robot configurations. A point represents a complete joint setting, not the location of the robot's hand. The graph asks which action comes next. The continuous space asks which precise configuration, grasp, and path realize it. These descriptions overlap. Choosing to hold the cup changes which configurations collide. Choosing a grasp can make the final placement unreachable. We cannot glue an arbitrary graph path to an arbitrary geometric path and expect them to describe the same physical behavior.", "source": "Survey §2; schematic configuration space", "start": 43.232940072395756, "duration": 44.95917683335568, "end": 88.19211690575143}, {"title": "Why geometry pushes back", "visual": "cspace", "equation": "C_free = C \\ C_collision", "points": ["Inflate obstacles by the moving body", "A point path can still collide", "A larger payload can close a passage"], "narration": "Shrink our robot to a disk moving across a table. We can test collisions by expanding every obstacle by the disk's radius and then planning for its center as a point. The expanded red region is forbidden configuration space. Now enlarge the disk to represent a carried object. A passage that was open becomes closed. Nothing about the high-level words pick and place tells us this. The relevant collision geometry depends on what is held and how it is held. Our two-dimensional drawing is deliberately simplified; a real arm's configuration space has many more dimensions. But the central lesson survives: a path belongs to a particular geometric situation.", "source": "Survey §2.2; original disk-robot construction", "start": 88.19211690575143, "duration": 43.46621531036332, "end": 131.65833221611476}, {"title": "A grasp changes the rules", "visual": "modes", "equation": "free → holding(cup, grasp) → free", "points": ["Objects attach and detach", "Motion stays within a mode", "Grasps connect different modes"], "narration": "Before grasping, the cup stays fixed on the table while the hand moves. After grasping, the cup must follow the hand. That contact changes the constraints governing motion. Think of each contact arrangement as a different sheet of feasible states. A grasp connects one sheet to another; a release connects back. We must travel within each sheet and find valid places to switch between them. This gives a geometric meaning to the symbolic actions. Pick is not merely a label on an arrow. It is an event where the robot and object satisfy the contact conditions needed to enter a new mode of motion.", "source": "Survey §§2.2.2–2.2.3", "start": 131.65833221611476, "duration": 39.827121598069446, "end": 171.4854538141842}, {"title": "A skeleton needs a witness", "visual": "tree", "equation": "find skeleton a₁…aₙ and parameters θ", "points": ["Skeleton: an action sequence", "Refinement: fill in continuous values", "Feasibility needs one consistent assignment"], "narration": "Erase the exact grasps, poses, and trajectories from a plan. What remains is its skeleton. To refine that skeleton, fill in all the missing continuous values so every constraint agrees. Here the first branch tries to pick the cup immediately. Its grasp candidates collide with the carton. Another branch first relocates the carton and then picks the cup. Notice the dependency: where we put the carton matters to a later motion, so individually valid choices can be jointly inconsistent. The plan succeeds only when the entire sequence has a compatible assignment. The green path is a witness to feasibility, not just a convincing description of what ought to happen.", "source": "Survey §§3–4; original search tree", "start": 171.4854538141842, "duration": 45.44905483308754, "end": 216.93450864727174}, {"title": "Integration is a design choice", "visual": "integration", "equation": "discrete search ↔ continuous reasoning", "points": ["Sample candidate values", "Optimize constraint violations", "Feed geometric information into search"], "narration": "There are several ways to coordinate this search. We might sample geometric candidates early, then search a finite abstraction. We might first propose an action sequence and refine it afterward. Or we might interleave decisions, checking geometry as the sequence grows. Continuous subproblems can themselves use sampling, numerical optimization, or combinations. The survey organizes this landscape rather than declaring one universal winner. Imagine having a limited computation budget. Testing everything up front wastes work on irrelevant actions. Deferring everything risks spending ages on an impossible skeleton. Integration means deciding when geometric information is valuable enough to obtain and how that information should change the next discrete decision.", "source": "Survey §§4–5; original budget analogy", "start": 216.93450864727174, "duration": 51.164298163292656, "end": 268.0988068105644}, {"title": "A failed attempt is information", "visual": "backtrack", "equation": "sample failure ≠ proof of impossibility", "points": ["Retry continuous choices", "Change the action sequence", "Keep the scope of evidence precise"], "narration": "Suppose our sampler tries three grasps and none works. Have we proved the cup cannot be picked? No. Perhaps the fourth grasp succeeds. Now suppose a geometric test conclusively rejects a particular grasp because it intersects the carton. That rejection is valid for that configuration, but it does not rule out every grasp or every world state. Good search must preserve this distinction. It can try another continuous assignment, change the skeleton, or move the obstacle. Claims of completeness also depend on assumptions about the problem and solver. A timeout is not an impossibility theorem. In the companion, change the clearance and see which kind of failure you actually create.", "source": "Survey §4; original evidence example", "start": 268.0988068105644, "duration": 45.77564016624212, "end": 313.8744469768065}, {"title": "The idea that connects the series", "visual": "lineage", "equation": "choose actions + find feasible geometry", "points": ["TAMP: the coupled problem", "PDDLStream: a solver interface", "Later systems add language and perception"], "narration": "Return to the cup. The successful animation has two intertwined stories: the robot chooses to move the carton, and it discovers poses and motions that make doing so useful. That is the foundation for the rest of this series. PDDLStream gives symbolic planning a disciplined interface to geometric samplers. OWL-TAMP asks language models to supply new constraints. TiPToP builds a complete perception-to-action system around a planner. GaP generates and rehearses modular execution graphs. These are different contributions at different layers. When you read any of them, ask what is being searched, what checks feasibility, and what assumptions connect the internal model to the real world.", "source": "Survey synthesis; cross-paper interpretation", "start": 313.8744469768065, "duration": 46.12555302319345, "end": 359.99999999999994}], "duration": 360, "subtitles": [{"start": 0.645270210483979, "end": 5.2806834361174415, "text": "Put the blue cup on the tray Three words seem to solve it pick move"}, {"start": 5.491968594985923, "end": 10.233003988470303, "text": "place But look at the red carton The cup fits in the open space beside"}, {"start": 10.246206394959108, "end": 15.211769204987261, "text": "it the gripper does not A list of sensible actions has hidden a physical"}, {"start": 15.224972583456225, "end": 19.516993967019705, "text": "impossibility This is our running miniature example designed for this"}, {"start": 19.53019637350851, "end": 24.773098169995976, "text": "explainer The first paper Integrated Task and Motion Planning is a survey"}, {"start": 24.786300576484777, "end": 29.144335936452602, "text": "by Caelan Garrett and colleagues rather than a single new planner Its"}, {"start": 29.157579166108054, "end": 34.14954776109398, "text": "organizing question is exactly this how do we choose a sequence of actions"}, {"start": 34.3608319479823, "end": 38.81136677168521, "text": "while also finding the geometry that makes those actions possible Watch"}, {"start": 38.82452932698752, "end": 41.83556153639898, "text": "the carton turn a motion problem into a task problem"}, {"start": 43.83860209143316, "end": 48.487177872368946, "text": "On the left is a small graph Each arrow names an action pick the cup"}, {"start": 48.77771926531706, "end": 53.18860604638691, "text": "put down the carton place the cup On the right is a continuous space"}, {"start": 53.20180845287571, "end": 57.86362746346694, "text": "of possible robot configurations A point represents a complete joint"}, {"start": 57.876830841935906, "end": 62.578297895160205, "text": "setting not the location of the robot's hand The graph asks which action"}, {"start": 62.59146045046252, "end": 67.94002426598739, "text": "comes next The continuous space asks which precise configuration grasp"}, {"start": 68.17771423783347, "end": 72.48293802788577, "text": "and path realize it These descriptions overlap Choosing to hold the"}, {"start": 72.49614140635472, "end": 76.98628344952405, "text": "cup changes which configurations collide Choosing a grasp can make the"}, {"start": 76.99948682799302, "end": 81.76692800643517, "text": "final placement unreachable We cannot glue an arbitrary graph path to"}, {"start": 81.78017123609061, "end": 86.21746380211823, "text": "an arbitrary geometric path and expect them to describe the same physical"}, {"start": 86.23066620860703, "end": 86.81174802252312, "text": "behavior"}, {"start": 88.79777892478884, "end": 93.31428690172945, "text": "Shrink our robot to a disk moving across a table We can test collisions"}, {"start": 93.32753013138489, "end": 97.52709190239977, "text": "by expanding every obstacle by the disk's radius and then planning for"}, {"start": 97.54029528086873, "end": 102.03043732403806, "text": "its center as a point The expanded red region is forbidden configuration"}, {"start": 102.04364070250703, "end": 107.32615069044107, "text": "space Now enlarge the disk to represent a carried object A passage that"}, {"start": 107.33935309692987, "end": 111.35407631720068, "text": "was open becomes closed Nothing about the high-level words pick and"}, {"start": 111.36723887250301, "end": 115.39516547124279, "text": "place tells us this The relevant collision geometry depends on what"}, {"start": 115.40836787773159, "end": 119.8589027014345, "text": "is held and how it is held Our two-dimensional drawing is deliberately"}, {"start": 119.87206525673682, "end": 124.61314147338784, "text": "simplified a real arm's configuration space has many more dimensions"}, {"start": 125.06211563212226, "end": 129.56546105376054, "text": "But the central lesson survives a path belongs to a particular geometric"}, {"start": 129.57866443222952, "end": 130.27861164365194, "text": "situation"}, {"start": 132.26399423515215, "end": 136.4107444362515, "text": "Before grasping the cup stays fixed on the table while the hand moves"}, {"start": 136.84655701166375, "end": 141.32349762032445, "text": "After grasping the cup must follow the hand That contact changes the"}, {"start": 141.3366592036466, "end": 145.64192381686553, "text": "constraints governing motion Think of each contact arrangement as a"}, {"start": 145.6551271953345, "end": 150.31694620592572, "text": "different sheet of feasible states A grasp connects one sheet to another"}, {"start": 150.73951457970236, "end": 155.52019898779997, "text": "a release connects back We must travel within each sheet and find valid"}, {"start": 155.53340139428877, "end": 159.42926018903339, "text": "places to switch between them This gives a geometric meaning to the"}, {"start": 159.4424625955222, "end": 164.19670136747553, "text": "symbolic actions Pick is not merely a label on an arrow It is an event"}, {"start": 164.20990377396433, "end": 168.34345156857486, "text": "where the robot and object satisfy the contact conditions needed to"}, {"start": 168.35665494704384, "end": 170.0866989542834, "text": "enter a new mode of motion"}, {"start": 172.0911158332216, "end": 177.571706629575, "text": "Erase the exact grasps poses and trajectories from a plan What remains"}, {"start": 177.66412639093713, "end": 182.62968822898512, "text": "is its skeleton To refine that skeleton fill in all the missing continuous"}, {"start": 182.6428916074541, "end": 187.58204960450462, "text": "values so every constraint agrees Here the first branch tries to pick"}, {"start": 187.59525201099342, "end": 192.4287470170264, "text": "the cup immediately Its grasp candidates collide with the carton Another"}, {"start": 192.44195039549538, "end": 196.53588999865934, "text": "branch first relocates the carton and then picks the cup Notice the"}, {"start": 196.54909337712832, "end": 201.42219657460785, "text": "dependency where we put the carton matters to a later motion so individually"}, {"start": 201.43539898109665, "end": 206.25569158064084, "text": "valid choices can be jointly inconsistent The plan succeeds only when"}, {"start": 206.2688949591098, "end": 210.7326321893015, "text": "the entire sequence has a compatible assignment The green path is a"}, {"start": 210.74579474460384, "end": 215.02461274969835, "text": "witness to feasibility not just a convincing description of what ought"}, {"start": 215.03781612816732, "end": 215.53968155919023, "text": "to happen"}, {"start": 217.55337307279794, "end": 221.68692183938865, "text": "There are several ways to coordinate this search We might sample geometric"}, {"start": 221.70012424587745, "end": 226.63924141976136, "text": "candidates early then search a finite abstraction We might first propose"}, {"start": 226.6524846494168, "end": 231.2482498324172, "text": "an action sequence and refine it afterward Or we might interleave decisions"}, {"start": 231.49918303391874, "end": 236.66282665236625, "text": "checking geometry as the sequence grows Continuous subproblems can themselves"}, {"start": 236.67603003083522, "end": 242.275486224695, "text": "use sampling numerical optimization or combinations The survey organizes"}, {"start": 242.2886886311838, "end": 246.91089945032846, "text": "this landscape rather than declaring one universal winner Imagine having"}, {"start": 246.92406200563076, "end": 251.3349886378871, "text": "a limited computation budget Testing everything up front wastes work"}, {"start": 251.46701659069578, "end": 256.04957839522723, "text": "on irrelevant actions Deferring everything risks spending ages on an"}, {"start": 256.0627817736962, "end": 261.2132229856549, "text": "impossible skeleton Integration means deciding when geometric information"}, {"start": 261.2264263641239, "end": 265.30716356079904, "text": "is valuable enough to obtain and how that information should change"}, {"start": 265.32036596728784, "end": 266.7202195669661, "text": "the next discrete decision"}, {"start": 268.7176712360906, "end": 273.18136861509583, "text": "Suppose our sampler tries three grasps and none works Have we proved"}, {"start": 273.1945719935648, "end": 275.2019530433034, "text": "the cup cannot be picked No."}, {"start": 275.6509272020378, "end": 280.6560982035125, "text": "Perhaps the fourth grasp succeeds Now suppose a geometric test conclusively"}, {"start": 280.6693015819815, "end": 285.38397201367474, "text": "rejects a particular grasp because it intersects the carton That rejection"}, {"start": 285.3971753921437, "end": 289.58357460785624, "text": "is valid for that configuration but it does not rule out every grasp"}, {"start": 289.86087277114893, "end": 294.3114066228717, "text": "or every world state Good search must preserve this distinction It can"}, {"start": 294.32457015015416, "end": 299.03924058184737, "text": "try another continuous assignment change the skeleton or move the obstacle"}, {"start": 299.47501136211287, "end": 303.1859499597801, "text": "Claims of completeness also depend on assumptions about the problem"}, {"start": 303.3444643718997, "end": 308.2703781673146, "text": "and solver A timeout is not an impossibility theorem In the companion"}, {"start": 308.6797849577691, "end": 312.4831841399651, "text": "change the clearance and see which kind of failure you actually create"}, {"start": 314.4801089958439, "end": 319.0494683938865, "text": "Return to the cup The successful animation has two intertwined stories"}, {"start": 319.35321219332343, "end": 323.8433143853063, "text": "the robot chooses to move the carton and it discovers poses and motions"}, {"start": 323.8565177637753, "end": 327.6863625821155, "text": "that make doing so useful That is the foundation for the rest of this"}, {"start": 327.6995659605845, "end": 332.7443441815256, "text": "series P D D L Stream gives symbolic planning a disciplined interface"}, {"start": 332.9424269339053, "end": 338.25134173481695, "text": "to geometric samplers Owl Tamp asks language models to supply new constraints"}, {"start": 338.68715333824906, "end": 342.7942953479018, "text": "Tip Top builds a complete perception-to-action system around a planner"}, {"start": 343.23010792331405, "end": 347.8258721343343, "text": "Gap generates and rehearses modular execution graphs These are different"}, {"start": 347.8390755128033, "end": 352.42167814050134, "text": "contributions at different layers When you read any of them ask what"}, {"start": 352.4348815189703, "end": 356.56842931358085, "text": "is being searched what checks feasibility and what assumptions connect"}, {"start": 356.58163172006965, "end": 358.615418554766, "text": "the internal model to the real world"}], "voice": "en-US-AndrewNeural · synthetic narration"}, {"id": "pddlstream", "short": "PDDLStream", "number": "02", "color": "#b4a1ff", "title": "Planning with promises you must keep", "paper": "PDDLStream: Integrating Symbolic Planners and Blackbox Samplers via Optimistic Adaptive Planning", "authors": "Caelan Reed Garrett, Tomás Lozano-Pérez, Leslie Pack Kaelbling", "year": "2020 · ICAPS", "url": "https://arxiv.org/abs/1802.08705", "summary": "How optimistic placeholders become certified geometric objects.", "sources": [{"label": "Garrett et al. · paper", "url": "https://arxiv.org/abs/1802.08705"}, {"label": "Official implementation", "url": "https://github.com/caelan/pddlstream"}], "chapters": [{"title": "The infinity hiding inside pick", "visual": "table", "equation": "Pick(cup, grasp, configuration)", "points": ["One action, infinitely many values", "Specialist solvers know the geometry", "The symbolic planner needs an interface"], "narration": "A symbolic planner is comfortable choosing between pick cup and pick carton. It is less comfortable choosing among infinitely many wrist poses. Yet robotics already has tools for these continuous questions: grasp generators, inverse kinematics, collision tests, and motion planners. PDDLStream asks how a general-purpose symbolic planner can use these tools without understanding their internals. Think of our cup problem as a conversation. The planner asks for a useful geometric object. A specialist returns a candidate and facts about it. The planner then reasons with those facts. The remarkable move is to make this conversation declarative, so the same planning machinery can work with very different sampling procedures.", "source": "Paper §§1–3; original cup example", "start": 0, "duration": 46.237666405638215, "end": 46.237666405638215}, {"title": "A stream is a typed promise", "visual": "stream", "equation": "inputs → generator → outputs + facts", "points": ["Domain: when the call is meaningful", "Outputs: newly generated objects", "Certified facts: the declared contract"], "narration": "Imagine a stream that receives a cup and returns possible grasps. Its declaration says which input facts must already hold and which facts every returned output certifies. A second stream takes a pose and grasp, returning a robot configuration that satisfies inverse kinematics. The implementation can be a black box. What matters to the planner is its contract. Certification here means the procedure is trusted to obey its declared semantics; it does not make an inaccurate collision model infallible. Also, sampling a grasp is a computation, not a robot action. The cup stays on the table while the planning system creates new objects it can reason about.", "source": "Paper §3.1; original stream contracts", "start": 46.237666405638215, "duration": 44.67071260767424, "end": 90.90837901331246}, {"title": "Geometry has a dependency graph", "visual": "dag", "equation": "grasp → IK configuration → trajectory", "points": ["Later calls depend on earlier outputs", "Facts connect specialized procedures", "Every link must be grounded"], "narration": "Follow the chain. To plan a trajectory, we need a destination configuration. To obtain that configuration, we need a pose and grasp. Each output becomes an input to another stream. This dependency graph is why simply generating random numbers everywhere is wasteful. Some expensive calls are useless until earlier choices are promising. In the drawing, a hollow node represents a value we have not yet obtained. A solid node represents an actual result. As the chain fills in, it becomes possible to justify the planned action with concrete geometric evidence. If the last link fails, we may need to reconsider an earlier choice, not only repeat the final call.", "source": "Paper §§3–5; original dependency diagram", "start": 90.90837901331246, "duration": 42.9902114330462, "end": 133.89859044635864}, {"title": "Plan optimistically, then check", "visual": "optimism", "equation": "optimistic object ≠ executable value", "points": ["Assume a useful output could exist", "Find a candidate plan", "Evaluate the streams that support it"], "narration": "Suppose, temporarily, that a useful grasp exists. Suppose a compatible inverse-kinematics solution exists too. The symbolic planner can use placeholders for these hypothetical outputs and ask whether a plan would work if the promises came true. This is optimism, and it is a search device. It does not authorize executing imaginary coordinates. Once a candidate plan is found, the relevant stream calls are evaluated to replace placeholders with actual values. Watch the dotted purple chain turn solid. A motion failure breaks the chain, forcing more sampling or a different candidate plan. The distinction between a promising hypothesis and a verified binding is the heart of the visual metaphor.", "source": "Paper §6; original promise metaphor", "start": 133.89859044635864, "duration": 45.82889584964761, "end": 179.72748629600625}, {"title": "Why focus computation?", "visual": "sampling", "equation": "only some samples support the goal", "points": ["Broad sampling explores alternatives", "Focused calls follow dependencies", "Cost depends on the particular problem"], "narration": "Picture a warehouse of possible objects, placements, and grasps. One strategy samples broadly and repeatedly asks the symbolic planner whether the accumulated facts suffice. That can discover useful alternatives, but it can also produce many values unrelated to the goal. An optimistic approach first identifies a plausible dependency chain and directs computation toward it. In our toy animation, the useful region occupies only a narrow band, so most scattered dots never contribute to the selected plan. This is an illustration, not a runtime result from the paper. Focus can save work, but an unlucky commitment can also waste work. The real question is how to balance those two risks.", "source": "Paper §§5–7; synthetic illustration", "start": 179.72748629600625, "duration": 46.71456538762725, "end": 226.4420516836335}, {"title": "Explore another plan or bind this one?", "visual": "balance", "equation": "search time ↔ sampling time", "points": ["Explore candidate plans", "Exploit promising parameter bindings", "Adapt where computation goes"], "narration": "Now give the planner one more second of computation. Should it search for a different skeleton, or try another binding for the skeleton already on the screen? Optimistic adaptive planning addresses this allocation problem. The adaptive algorithm combines search for candidate plans with focused effort to bind the continuous parameters of promising ones. Imagine two doors. One opens onto a large geometric region but requires a longer action sequence. The other promises a short plan but has a very narrow feasible grasp region. Committing forever to either extreme is a poor strategy. The algorithm's contribution is in how it coordinates these kinds of discrete and continuous work.", "source": "Paper §7; original two-door analogy", "start": 226.4420516836335, "duration": 43.87588097102584, "end": 270.31793265465933}, {"title": "Facts do not move the robot", "visual": "certificates", "equation": "model validity → conditional guarantees", "points": ["Streams add facts during planning", "Actions change the world state", "Bad models can certify bad predictions"], "narration": "Our notebook now contains a valid grasp, a configuration, and a collision-free trajectory. The symbolic state still says the cup is on the table. Only the planned pick action changes that state to holding the cup. Keeping computational facts separate from changing world facts makes the interface precise. It also clarifies the limits. If a mesh omits the cup handle, a collision checker may certify a trajectory that fails on hardware. If the generator never proposes a needed grasp, search may never find the plan. The paper's theoretical results have explicit assumptions; they are not a promise that every physical task is solved within a fixed deadline.", "source": "Paper §3 and Appendix A; original model-error example", "start": 270.31793265465933, "duration": 42.80853563038371, "end": 313.126468285043}, {"title": "The executable chain", "visual": "lineage", "equation": "placeholder → sample → certified fact → plan", "points": ["Inspect which calls actually ran", "Compare broad and focused sampling", "Carry the contract into later systems"], "narration": "The cup finally reaches the tray because every relevant promise acquired a concrete witness. PDDLStream is useful far beyond this one drawing: it separates the language of planning from the implementation of specialized procedures. The planner sees objects and facts; the samplers handle the difficult continuous relationships. In the interactive companion, advance one stream call at a time. Watch how an inverse-kinematics result enables a motion query, and how a failed query leaves a plan ungrounded. Then compare broad sampling with a focused dependency chain. The lesson to carry forward is that a modular interface can support rigorous search, provided each module's contract actually means what it says.", "source": "Paper synthesis; original interactive exercise", "start": 313.126468285043, "duration": 46.873531714956925, "end": 359.99999999999994}], "duration": 360, "subtitles": [{"start": 0.6028625685199687, "end": 4.125511909423127, "text": "A symbolic planner is comfortable choosing between pick cup and pick"}, {"start": 4.138365472461498, "end": 8.663780083529105, "text": "carton It is less comfortable choosing among infinitely many wrist poses"}, {"start": 9.088045125293657, "end": 13.382106956408249, "text": "Yet robotics already has tools for these continuous questions grasp"}, {"start": 13.394920777864787, "end": 18.51176771730619, "text": "generators inverse kinematics collision tests and motion planners P"}, {"start": 18.524620334116417, "end": 22.87009357870008, "text": "D D L Stream asks how a general-purpose symbolic planner can use these"}, {"start": 22.882908346384756, "end": 26.80411654920386, "text": "tools without understanding their internals Think of our cup problem"}, {"start": 26.97124409423127, "end": 32.049492495432006, "text": "as a conversation The planner asks for a useful geometric object A specialist"}, {"start": 32.062346058470375, "end": 35.944995464630644, "text": "returns a candidate and facts about it The planner then reasons with"}, {"start": 35.95784902766902, "end": 40.560420027407986, "text": "those facts The remarkable move is to make this conversation declarative"}, {"start": 40.843264650221876, "end": 44.14737503262855, "text": "so the same planning machinery can work with very different sampling"}, {"start": 44.16018790785696, "end": 44.867295679979115, "text": "procedures"}, {"start": 46.84052897415818, "end": 51.18596247716001, "text": "Imagine a stream that receives a cup and returns possible grasps Its"}, {"start": 51.19881604019838, "end": 55.942809351344295, "text": "declaration says which input facts must already hold and which facts"}, {"start": 56.08423166275124, "end": 61.13677388410337, "text": "every returned output certifies A second stream takes a pose and grasp"}, {"start": 61.40676494387888, "end": 65.98363070999739, "text": "returning a robot configuration that satisfies inverse kinematics The"}, {"start": 65.99648427303576, "end": 70.18768258940224, "text": "implementation can be a black box What matters to the planner is its"}, {"start": 70.20053615244062, "end": 75.03450061994258, "text": "contract Certification here means the procedure is trusted to obey its"}, {"start": 75.04735323675281, "end": 79.5985128230227, "text": "declared semantics it does not make an inaccurate collision model infallible"}, {"start": 80.0227788110154, "end": 85.30675234925607, "text": "Also sampling a grasp is a computation not a robot action The cup stays"}, {"start": 85.31960591229443, "end": 89.11224536674497, "text": "on the table while the planning system creates new objects it can reason"}, {"start": 89.12509892978335, "end": 89.53651040850953, "text": "about"}, {"start": 91.54980037849126, "end": 95.93383241973376, "text": "Follow the chain To plan a trajectory we need a destination configuration"}, {"start": 96.35805866614461, "end": 101.1149443356826, "text": "To obtain that configuration we need a pose and grasp Each output becomes"}, {"start": 101.12779789872097, "end": 105.82033910858785, "text": "an input to another stream This dependency graph is why simply generating"}, {"start": 105.83323241320804, "end": 110.25578445575569, "text": "random numbers everywhere is wasteful Some expensive calls are useless"}, {"start": 110.37150058731402, "end": 114.97411132863482, "text": "until earlier choices are promising In the drawing a hollow node represents"}, {"start": 114.98692515009137, "end": 119.55093735317149, "text": "a value we have not yet obtained A solid node represents an actual result"}, {"start": 119.97520334116419, "end": 124.3592353824067, "text": "As the chain fills in it becomes possible to justify the planned action"}, {"start": 124.41064774210389, "end": 128.7432286282955, "text": "with concrete geometric evidence If the last link fails we may need"}, {"start": 128.7561219329157, "end": 132.52301641216394, "text": "to reconsider an earlier choice not only repeat the final call"}, {"start": 134.51430563168884, "end": 139.57970141607933, "text": "Suppose temporarily that a useful grasp exists Suppose a compatible"}, {"start": 139.59255497911772, "end": 143.80941973375096, "text": "inverse-kinematics solution exists too The symbolic planner can use"}, {"start": 143.82231303837116, "end": 147.67921746932913, "text": "placeholders for these hypothetical outputs and ask whether a plan would"}, {"start": 147.69207008613938, "end": 152.39746580527276, "text": "work if the promises came true This is optimism and it is a search device"}, {"start": 152.82177058861913, "end": 157.1800567084312, "text": "It does not authorize executing imaginary coordinates Once a candidate"}, {"start": 157.19291027146957, "end": 162.06547233098405, "text": "plan is found the relevant stream calls are evaluated to replace placeholders"}, {"start": 162.2583060558601, "end": 167.25943780997127, "text": "with actual values Watch the dotted purple chain turn solid A motion"}, {"start": 167.2722904267815, "end": 171.360626174628, "text": "failure breaks the chain forcing more sampling or a different candidate"}, {"start": 171.3734797376664, "end": 176.2846005938397, "text": "plan The distinction between a promising hypothesis and a verified binding"}, {"start": 176.40031672539806, "end": 178.34162203080135, "text": "is the heart of the visual metaphor"}, {"start": 180.34320148133645, "end": 186.03858839075957, "text": "Picture a warehouse of possible objects placements and grasps One strategy"}, {"start": 186.05140221221612, "end": 190.38402283998954, "text": "samples broadly and repeatedly asks the symbolic planner whether the"}, {"start": 190.39687545679976, "end": 194.94803504306967, "text": "accumulated facts suffice That can discover useful alternatives but"}, {"start": 194.96088860610806, "end": 199.29347043852778, "text": "it can also produce many values unrelated to the goal An optimistic"}, {"start": 199.30632305533803, "end": 204.05031636648394, "text": "approach first identifies a plausible dependency chain and directs computation"}, {"start": 204.0631699295223, "end": 208.89717319237795, "text": "toward it In our toy animation the useful region occupies only a narrow"}, {"start": 208.9100267554163, "end": 213.9754215935787, "text": "band so most scattered dots never contribute to the selected plan This"}, {"start": 214.1039912881754, "end": 218.6036997193944, "text": "is an illustration not a runtime result from the paper Focus can save"}, {"start": 218.61659207778646, "end": 223.14200763508222, "text": "work but an unlucky commitment can also waste work The real question"}, {"start": 223.21916402375356, "end": 225.0576067606369, "text": "is how to balance those two risks"}, {"start": 227.0449142521535, "end": 230.67042616157661, "text": "Now give the planner one more second of computation Should it search"}, {"start": 230.68323998303313, "end": 234.7330169342208, "text": "for a different skeleton or try another binding for the skeleton already"}, {"start": 234.7458704972592, "end": 238.84702006656224, "text": "on the screen Optimistic adaptive planning addresses this allocation"}, {"start": 238.85991337118244, "end": 243.46248531714957, "text": "problem The adaptive algorithm combines search for candidate plans with"}, {"start": 243.4753379339598, "end": 248.30934119681544, "text": "focused effort to bind the continuous parameters of promising ones Imagine"}, {"start": 248.3221947598538, "end": 253.29757964630645, "text": "two doors One opens onto a large geometric region but requires a longer"}, {"start": 253.3104332093448, "end": 258.0287203406421, "text": "action sequence The other promises a short plan but has a very narrow"}, {"start": 258.0415739036805, "end": 262.25847934612375, "text": "feasible grasp region Committing forever to either extreme is a poor"}, {"start": 262.27133196293397, "end": 266.50105028060557, "text": "strategy The algorithm's contribution is in how it coordinates these"}, {"start": 266.51394263899766, "end": 268.93092439963453, "text": "kinds of discrete and continuous work"}, {"start": 270.9207952231793, "end": 275.7419061276429, "text": "Our notebook now contains a valid grasp a configuration and a collision-free"}, {"start": 275.7547596906813, "end": 280.3187718937614, "text": "trajectory The symbolic state still says the cup is on the table Only"}, {"start": 280.33162545679977, "end": 284.0342549595406, "text": "the planned pick action changes that state to holding the cup Keeping"}, {"start": 284.0471085225789, "end": 288.4439941268598, "text": "computational facts separate from changing world facts makes the interface"}, {"start": 288.45684674367004, "end": 293.6508112764291, "text": "precise It also clarifies the limits If a mesh omits the cup handle"}, {"start": 294.0750763181937, "end": 298.1377068324197, "text": "a collision checker may certify a trajectory that fails on hardware"}, {"start": 298.5619718741843, "end": 302.9074063234142, "text": "If the generator never proposes a needed grasp search may never find"}, {"start": 302.9202598864526, "end": 307.25288051422604, "text": "the plan The paper's theoretical results have explicit assumptions they"}, {"start": 307.26573313103626, "end": 311.2126087183503, "text": "are not a promise that every physical task is solved within a fixed"}, {"start": 311.2254613351605, "end": 311.73969658705295, "text": "deadline"}, {"start": 313.7421834703732, "end": 317.9719017880448, "text": "The cup finally reaches the tray because every relevant promise acquired"}, {"start": 317.9847553510832, "end": 323.4101512007308, "text": "a concrete witness P D D L Stream is useful far beyond this one drawing"}, {"start": 323.9244261942051, "end": 327.7555856499608, "text": "it separates the language of planning from the implementation of specialized"}, {"start": 327.7684780083529, "end": 332.563883679196, "text": "procedures The planner sees objects and facts the samplers handle the"}, {"start": 332.57673629600623, "end": 337.29502437353165, "text": "difficult continuous relationships In the interactive companion advance"}, {"start": 337.3078769903419, "end": 341.70476259462276, "text": "one stream call at a time Watch how an inverse-kinematics result enables"}, {"start": 341.71761615766115, "end": 346.30733454058986, "text": "a motion query and how a failed query leaves a plan ungrounded Then"}, {"start": 346.32018810362825, "end": 350.3956712346645, "text": "compare broad sampling with a focused dependency chain The lesson to"}, {"start": 350.40852385147474, "end": 354.6510957321848, "text": "carry forward is that a modular interface can support rigorous search"}, {"start": 354.93393940877047, "end": 358.6237550900548, "text": "provided each module's contract actually means what it says"}], "voice": "en-US-AndrewNeural · synthetic narration"}, {"id": "owl-tamp", "short": "OWL-TAMP", "number": "03", "color": "#f2c86d", "title": "Turning language into feasible regions", "paper": "Open-World Task and Motion Planning via Vision-Language Model Generated Constraints", "authors": "Nishanth Kumar, William Shen, Fabio Ramos, Dieter Fox, Tomás Lozano-Pérez, Leslie Pack Kaelbling, Caelan Reed Garrett", "year": "2026 · RA-L / arXiv v4", "url": "https://arxiv.org/abs/2411.08253", "summary": "Language proposes constraints; geometric search finds values that satisfy them.", "sources": [{"label": "Kumar et al. · paper v4", "url": "https://arxiv.org/html/2411.08253v4"}, {"label": "Authors’ project and demonstrations", "url": "https://nishanthjkumar.com/owl-tamp/"}], "chapters": [{"title": "What does “near” mean to a planner?", "visual": "region", "equation": "language → a set of acceptable outcomes", "points": ["Words specify intent", "A fixed vocabulary can miss the goal", "Continuous constraints make intent testable"], "narration": "Place the cup near the plate. To you, that sounds ordinary. To a planner whose only spatial predicate is on, the word near may have no meaning at all. A vision-language model can interpret the phrase, but that does not mean it can produce a collision-free arm trajectory. OWL-TAMP connects these capabilities through constraints. We will use an original tabletop example: the cup must end near a plate while staying away from a red obstacle. Instead of asking language to output the final motion, ask it to describe which outcomes count as acceptable. The animation turns a phrase into a region of possible placements.", "source": "Paper §§1,4; original cup example", "start": 0, "duration": 40.58746473196292, "end": 40.58746473196292}, {"title": "A predicate draws a region", "visual": "predicate", "equation": "Near(p) := ||p − c|| ≤ r", "points": ["Candidate pose goes in", "True or false comes out", "The threshold is an interpretation"], "narration": "Here is one possible interpretation of near: the cup's center must lie within a chosen distance of the plate's center. Every candidate placement is fed to a function that returns true or false. As the distance threshold grows, the accepted region expands. This particular circle and threshold are teaching choices, not a universal definition of near or a literal classifier copied from the paper. The important transformation is from open-ended language to executable tests. OWL-TAMP uses a vision-language model to generate such classifier code, conditioned on the task and scene. A planner can then search over continuous candidates and reject those that fail the generated test.", "source": "Paper §§4,5.2; original predicate", "start": 40.58746473196292, "duration": 45.80068520757759, "end": 86.38814993954051}, {"title": "Intersect intent with physics", "visual": "intersection", "equation": "feasible = language ∩ reach ∩ collision-free", "points": ["Language is one constraint", "Reachability is another", "Collision checking removes more candidates"], "narration": "The yellow disk shows placements that satisfy our interpretation of near. But some lie beyond the robot's reach. Others overlap the obstacle. The admissible set is the intersection of all these requirements. Watch yellow points disappear when geometric tests are applied, leaving only a smaller green region. A language model can be quite good at choosing the semantic region while still being poor at finding exact joint angles. This arrangement lets each tool contribute the kind of reasoning it can support. Yet an empty intersection is meaningful: the chosen interpretation and physical constraints may be incompatible. No amount of confidently restating the goal creates a feasible point inside an empty set.", "source": "Paper §§4–5; original set construction", "start": 86.38814993954051, "duration": 47.250100765820235, "end": 133.63825070536075}, {"title": "A sketch leaves room for extra actions", "visual": "ordering", "equation": "required actions ⊆ ordered plan subsequence", "points": ["Preserve task-relevant order", "Insert missing setup actions", "Allow geometric backtracking"], "narration": "Now add an instruction: place the cup on the scale, then move it near the plate. A language-generated sketch can specify these two required events in order without listing every necessary movement. OWL-TAMP constrains the full plan to contain the sketch as a subsequence. The planner can insert actions before, between, or after those events. Here it first moves the obstructing carton, then picks the cup, weighs it, and eventually places it near the plate. This distinction is powerful. The semantic sketch says what must happen and in what order, while the underlying search still has room to discover the physical preparation needed to make it happen.", "source": "Paper §5.1; original weigh-cup example", "start": 133.63825070536075, "duration": 43.11225312374042, "end": 176.75050382910118}, {"title": "The blocked-object test", "visual": "table", "equation": "task sketch + geometric repair", "points": ["A sensible sketch can be incomplete", "An obstacle can require an extra action", "Search fills the missing details"], "narration": "Try an experiment in your head. Give a language model a picture of a cup crowded by a carton. It may reasonably suggest picking the cup and placing it near the plate. But if every usable grasp collides, the direct plan fails. A TAMP system can instead search for a plan that relocates the carton. The authors demonstrate this kind of obstacle-removal reasoning with their own object arrangements. Our cup scene isolates the mechanism. The language constraint remains attached to the intended cup placement while the search adds a preparatory action. The system is doing more than translating a sentence into a fixed list of robot commands.", "source": "Authors’ project overview; original cup geometry", "start": 176.75050382910118, "duration": 41.896614268440146, "end": 218.64711809754132}, {"title": "Correct code can express the wrong goal", "visual": "ambiguity", "equation": "verified constraint ≠ verified human intent", "points": ["“Near” needs a scale", "“Initially” needs a remembered reference", "A valid plan can satisfy the wrong test"], "narration": "Change the phrase to near where the plate was initially. If the generated function reads the plate's current pose after it moves, the code can run perfectly and still express the wrong intention. Or suppose the threshold is so large that almost the whole table counts as near. The planner may return a mathematically valid solution to a poorly specified task. This is the key boundary: geometric checking validates the supplied constraints, not the truth of the language model's interpretation. The visual comparison shows two feasible regions for two interpretations of the same phrase. In the companion, adjust the threshold and watch how much behavior that single semantic choice permits.", "source": "Paper §8; original initial-reference counterexample", "start": 218.64711809754132, "duration": 44.42140266021765, "end": 263.06852075775896}, {"title": "Open-world goals, bounded capabilities", "visual": "capabilities", "equation": "new constraints + existing robot skills", "points": ["New language relations can be grounded", "Available actions still define capability", "Perception and generated code can fail"], "narration": "There is a second boundary. Generating a new constraint does not magically add a new physical skill. If the available robot actions only move rigid objects, a request to fold cloth is not solved merely by inventing a folded predicate. The action library, perception, geometric models, and code generation all matter. OWL-TAMP expands the goals and constraints that a planning system can express while using available manipulation capabilities. The paper reports simulation comparisons and real-robot demonstrations; those support the tested settings, not every interpretation of open world. A useful way to read the method is to ask exactly which part of the task model becomes flexible and which parts remain supplied.", "source": "Paper §§3,6,8; original cloth counterexample", "start": 263.06852075775896, "duration": 49.1670697299476, "end": 312.23559048770653}, {"title": "Language writes the test", "visual": "lineage", "equation": "interpret → constrain → search → execute", "points": ["A semantic contract", "A geometric feasibility check", "A plan that joins the two"], "narration": "We began with a word, near, and ended with a set intersection and an executable plan. That is the central picture for OWL-TAMP. Language supplies task-dependent meaning through discrete ordering constraints and continuous classifier functions. TAMP supplies search over actions and precise geometric values. Their connection is inspectable: look at the sketch, read the predicate, and examine the accepted region. In the interactive scene, move the candidate cup around and find a point that passes the language test but fails collision checking. Then find one that passes both. Understanding that difference is more informative than asking whether the language model, by itself, understands all of robot manipulation.", "source": "Paper synthesis; original interactive exercise", "start": 312.23559048770653, "duration": 47.76440951229343, "end": 359.99999999999994}], "duration": 360, "subtitles": [{"start": 0.6191199449146849, "end": 4.986563583232567, "text": "Place the cup near the plate To you that sounds ordinary To a planner"}, {"start": 4.9997953446191055, "end": 9.274580612656186, "text": "whose only spatial predicate is on the word near may have no meaning"}, {"start": 9.287812374042725, "end": 13.311125016794302, "text": "at all A vision-language model can interpret the phrase but that does"}, {"start": 13.324356778180839, "end": 17.837382910116887, "text": "not mean it can produce a collision-free arm trajectory Owl Tamp connects"}, {"start": 17.850614671503426, "end": 22.45625826279726, "text": "these capabilities through constraints We will use an original tabletop"}, {"start": 22.469490024183795, "end": 26.638386134623136, "text": "example the cup must end near a plate while staying away from a red"}, {"start": 26.651657832863094, "end": 31.62789496842671, "text": "obstacle Instead of asking language to output the final motion ask it"}, {"start": 31.641126729813244, "end": 36.180574499529754, "text": "to describe which outcomes count as acceptable The animation turns a"}, {"start": 36.193846197769716, "end": 39.18484864973801, "text": "phrase into a region of possible placements"}, {"start": 41.21981643826414, "end": 45.52106328093511, "text": "Here is one possible interpretation of near the cup's center must lie"}, {"start": 45.534295042321645, "end": 49.650266055354024, "text": "within a chosen distance of the plate's center Every candidate placement"}, {"start": 49.80908031035872, "end": 54.71912162434502, "text": "is fed to a function that returns true or false As the distance threshold"}, {"start": 54.732393322584976, "end": 60.065951330108824, "text": "grows the accepted region expands This particular circle and threshold"}, {"start": 60.145338976219264, "end": 64.68482765685879, "text": "are teaching choices not a universal definition of near or a literal"}, {"start": 64.69805941824534, "end": 68.90664886470509, "text": "classifier copied from the paper The important transformation is from"}, {"start": 69.07873384388014, "end": 74.01523770656993, "text": "open-ended language to executable tests Owl Tamp uses a vision-language"}, {"start": 74.02846849388686, "end": 78.83266058712884, "text": "model to generate such classifier code conditioned on the task and scene"}, {"start": 79.26941001612252, "end": 83.26626108424023, "text": "A planner can then search over continuous candidates and reject those"}, {"start": 83.27949187155716, "end": 84.99998320569662, "text": "that fail the generated test"}, {"start": 87.0072698844552, "end": 90.84530767163778, "text": "The yellow disk shows placements that satisfy our interpretation of"}, {"start": 90.85853845895473, "end": 95.86123814322183, "text": "near But some lie beyond the robot's reach Others overlap the obstacle"}, {"start": 96.31121738546285, "end": 100.99628953379015, "text": "The admissible set is the intersection of all these requirements Watch"}, {"start": 101.00952032110709, "end": 105.36369226118501, "text": "yellow points disappear when geometric tests are applied leaving only"}, {"start": 105.37692402257154, "end": 109.53262928254736, "text": "a smaller green region A language model can be quite good at choosing"}, {"start": 109.5458610439339, "end": 113.71479709122666, "text": "the semantic region while still being poor at finding exact joint angles"}, {"start": 114.16473639661427, "end": 117.72487992073088, "text": "This arrangement lets each tool contribute the kind of reasoning it"}, {"start": 117.73811070804783, "end": 123.33633219132071, "text": "can support Yet an empty intersection is meaningful the chosen interpretation"}, {"start": 123.40252801289802, "end": 128.06113761252183, "text": "and physical constraints may be incompatible No amount of confidently"}, {"start": 128.07436937390838, "end": 132.24326451027812, "text": "restating the goal creates a feasible point inside an empty set"}, {"start": 134.2441398629585, "end": 138.36011087599087, "text": "Now add an instruction place the cup on the scale then move it near"}, {"start": 138.37334263737742, "end": 142.91279040709392, "text": "the plate A language-generated sketch can specify these two required"}, {"start": 142.92606307940346, "end": 148.3125452102647, "text": "events in order without listing every necessary movement Owl Tamp constrains"}, {"start": 148.3257769716512, "end": 152.66675903533522, "text": "the full plan to contain the sketch as a subsequence The planner can"}, {"start": 152.67998982265215, "end": 158.00031704285908, "text": "insert actions before between or after those events Here it first moves"}, {"start": 158.0135488042456, "end": 162.63242318285637, "text": "the obstructing carton then picks the cup weighs it and eventually places"}, {"start": 162.64565494424292, "end": 167.15868205024856, "text": "it near the plate This distinction is powerful The semantic sketch says"}, {"start": 167.17191283756551, "end": 171.43346731828564, "text": "what must happen and in what order while the underlying search still"}, {"start": 171.4466990796722, "end": 175.3509317143625, "text": "has room to discover the physical preparation needed to make it happen"}, {"start": 177.35639298669892, "end": 180.92972638720946, "text": "Try an experiment in your head Give a language model a picture of a"}, {"start": 180.942958148596, "end": 185.5618734381298, "text": "cup crowded by a carton It may reasonably suggest picking the cup and"}, {"start": 185.57510519951634, "end": 190.2469455864571, "text": "placing it near the plate But if every usable grasp collides the direct"}, {"start": 190.26013643692062, "end": 195.104062777106, "text": "plan fails A TAMP system can instead search for a plan that relocates"}, {"start": 195.11725362756954, "end": 199.7361289802499, "text": "the carton The authors demonstrate this kind of obstacle-removal reasoning"}, {"start": 199.74940067848985, "end": 204.40801027811366, "text": "with their own object arrangements Our cup scene isolates the mechanism"}, {"start": 204.8579495835013, "end": 208.78864476689506, "text": "The language constraint remains attached to the intended cup placement"}, {"start": 209.0136548434771, "end": 213.0105059115948, "text": "while the search adds a preparatory action The system is doing more"}, {"start": 213.02373669891173, "end": 217.24559784361145, "text": "than translating a sentence into a fixed list of robot commands"}, {"start": 219.25300725513907, "end": 223.2365866250168, "text": "Change the phrase to near where the plate was initially If the generated"}, {"start": 223.24985832325677, "end": 227.36583031035875, "text": "function reads the plate's current pose after it moves the code can"}, {"start": 227.37906109767567, "end": 232.06413227193337, "text": "run perfectly and still express the wrong intention Or suppose the threshold"}, {"start": 232.0773640333199, "end": 236.40507342469436, "text": "is so large that almost the whole table counts as near The planner may"}, {"start": 236.4183051860809, "end": 241.5401248152627, "text": "return a mathematically valid solution to a poorly specified task This"}, {"start": 241.6724774956335, "end": 246.15904205293566, "text": "is the key boundary geometric checking validates the supplied constraints"}, {"start": 246.46339789063552, "end": 250.77791643154643, "text": "not the truth of the language model's interpretation The visual comparison"}, {"start": 250.79114819293295, "end": 255.29094353755207, "text": "shows two feasible regions for two interpretations of the same phrase"}, {"start": 255.72765205562274, "end": 259.8436230686551, "text": "In the companion adjust the threshold and watch how much behavior that"}, {"start": 259.85685483004164, "end": 261.6832752586323, "text": "single semantic choice permits"}, {"start": 263.68764070267366, "end": 268.2800535066505, "text": "There is a second boundary Generating a new constraint does not magically"}, {"start": 268.34621036544405, "end": 273.19009579470645, "text": "add a new physical skill If the available robot actions only move rigid"}, {"start": 273.20332658202335, "end": 277.9942878879484, "text": "objects a request to fold cloth is not solved merely by inventing a"}, {"start": 278.00751964933494, "end": 283.26169098481796, "text": "folded predicate The action library perception geometric models and"}, {"start": 283.27488183528146, "end": 288.2908522437189, "text": "code generation all matter Owl Tamp expands the goals and constraints"}, {"start": 288.30408400510544, "end": 292.4597493282279, "text": "that a planning system can express while using available manipulation"}, {"start": 292.4729801155448, "end": 297.3697906422141, "text": "capabilities The paper reports simulation comparisons and real-robot"}, {"start": 297.3830214295311, "end": 302.3063344417574, "text": "demonstrations those support the tested settings not every interpretation"}, {"start": 302.3195662031439, "end": 306.81932063683996, "text": "of open world A useful way to read the method is to ask exactly which"}, {"start": 306.83255239822654, "end": 310.8558650409781, "text": "part of the task model becomes flexible and which parts remain supplied"}, {"start": 312.8414796453043, "end": 317.98976182318955, "text": "We began with a word near and ended with a set intersection and an executable"}, {"start": 318.0029935845761, "end": 323.23066243450216, "text": "plan That is the central picture for Owl Tamp Language supplies task-dependent"}, {"start": 323.2438932218191, "end": 327.39955757087193, "text": "meaning through discrete ordering constraints and continuous classifier"}, {"start": 327.41278933225846, "end": 332.5478407228268, "text": "functions TAMP supplies search over actions and precise geometric values"}, {"start": 332.9978209391374, "end": 337.3652636033857, "text": "Their connection is inspectable look at the sketch read the predicate"}, {"start": 337.6828921133951, "end": 342.40765662367323, "text": "and examine the accepted region In the interactive scene move the candidate"}, {"start": 342.42088838505975, "end": 346.47070448743784, "text": "cup around and find a point that passes the language test but fails"}, {"start": 346.48393624882436, "end": 350.7454488445519, "text": "collision checking Then find one that passes both Understanding that"}, {"start": 350.75872151686144, "end": 354.557064993954, "text": "difference is more informative than asking whether the language model"}, {"start": 354.79526592099955, "end": 358.60684018540906, "text": "by itself understands all of robot manipulation"}], "voice": "en-US-AndrewNeural · synthetic narration"}, {"id": "tiptop", "short": "TiPToP", "number": "04", "color": "#82e1b0", "title": "From pixels to a physical plan", "paper": "TiPToP: A Modular Open-Vocabulary Planning System for Robotic Manipulation", "authors": "William Shen, Nishanth Kumar, Sahit Chintalapudi, Jie Wang, Christopher Watson, Edward Hu, Jing Cao, Dinesh Jayaraman, Leslie Pack Kaelbling, Tomás Lozano-Pérez", "year": "2026 · arXiv v1", "url": "https://arxiv.org/abs/2603.09971", "summary": "A modular system connects pretrained perception, cuTAMP, and trajectory execution.", "sources": [{"label": "Shen et al. · paper v1", "url": "https://arxiv.org/html/2603.09971v1"}, {"label": "Official implementation walkthrough", "url": "https://tiptop-robot.github.io/implementation"}, {"label": "Project results", "url": "https://tiptop-robot.github.io/"}], "chapters": [{"title": "The model has to come from somewhere", "visual": "perception", "equation": "RGB + instruction → scene + goal", "points": ["A planner needs objects and geometry", "A camera provides pixels", "Perception constructs the planning input"], "narration": "So far our planner has enjoyed a luxury: someone handed it objects, poses, and a goal. A real robot starts with camera images. TiPToP addresses the full path from images and a natural-language instruction to manipulation. Its three major modules are perception, planning, and execution. Our teaching example asks the robot to put a snack on a tray while a carton obstructs access. Watch the initial image acquire object identities, geometry, and grasp candidates. The system is modular, so its internal decisions can be inspected. That matters both when it succeeds and when a perfectly reasonable-looking plan turns out to depend on a mistaken reconstruction of the scene.", "source": "Paper §§III–IV; original snack example", "start": 0, "duration": 43.88852705410822, "end": 43.88852705410822}, {"title": "Separate meaning from geometry", "visual": "architecture", "equation": "semantic branch + 3D branch → object model", "points": ["Identify objects and ground the goal", "Estimate depth and propose grasps", "Merge masks, points, and identities"], "narration": "TiPToP builds its scene through two branches. One estimates depth and proposes grasps. The other identifies objects, segments them, and grounds the language goal. In the reported system, FoundationStereo supplies depth, M2T2 proposes grasps, Gemini provides semantic grounding, and SAM two supplies masks. The outputs are merged into object-centered geometry and candidate grasps. Our animation separates these streams so you can see their different jobs. A label such as snack does not determine the surface shape. A precise point cloud does not, by itself, decide which item the user meant. The planning input needs both, joined through a consistent correspondence between perceived pixels and physical objects.", "source": "Implementation walkthrough · Perception Module", "start": 43.88852705410822, "duration": 47.22294589178357, "end": 91.11147294589179}, {"title": "A mesh is an estimate", "visual": "mesh", "equation": "observed surface → completed geometry", "points": ["One viewpoint leaves hidden surfaces", "Completion fills the missing shape", "Model errors alter collision predictions"], "narration": "Look at this U-shaped object from above. A convex hull fills its empty center. If we use that filled shape for collision checking, a real opening disappears from the model. The opposite mistake is also possible: an unseen surface is missing, so the model allows a motion that will collide. TiPToP constructs meshes from partial observations, and its paper identifies shape completion as a source of failures. Our U shape is an illustrative counterexample rather than a reported experiment. The point is that motion feasibility is evaluated against reconstructed geometry. Improving the planner cannot repair every error in the world model it was given. Sometimes the right fix belongs in perception.", "source": "Paper §VIII; original U-shape example", "start": 91.11147294589179, "duration": 43.19113226452906, "end": 134.30260521042084}, {"title": "Many continuous guesses at once", "visual": "particles", "equation": "skeleton → particles → feasible parameters", "points": ["cuTAMP enumerates plan skeletons", "Particles represent parameter candidates", "GPU optimization reduces violations"], "narration": "The planning module uses cuTAMP. For a candidate action skeleton, it initializes many continuous parameter assignments and optimizes them in parallel on a GPU. The moving dots in our drawing stand for complete candidate assignments, compressed into two dimensions so we can see them. They move toward lower constraint violation; only candidates satisfying the necessary conditions are useful. Motion planning then connects configurations into executable trajectories, using cuRobo. The dots are a conceptual animation, not real cuTAMP optimization traces. Their purpose is to reveal the division of labor: discrete search proposes a structure, batched optimization seeks compatible geometric values, and motion planning builds paths between the required configurations.", "source": "Implementation walkthrough · Planning Module", "start": 134.30260521042084, "duration": 49.358717434869746, "end": 183.66132264529057}, {"title": "Open vocabulary does not mean every skill", "visual": "goal", "equation": "language → On(object, support)", "points": ["Interpret diverse object descriptions", "Ground goals in supported predicates", "New skills need a model and controller"], "narration": "Ask for the snack rather than a particular object identifier. The semantic module can use visual and linguistic knowledge to choose the intended item. That is one source of open-vocabulary behavior. But the released paper's main system grounds these requests into a limited action and predicate model, primarily pick and place with an on relation. It also demonstrates extending the system with a wiping skill. Our visualization lets the words vary while keeping the supported relation explicit. There is an engineering step between recognizing a new request and possessing the motor skill to fulfill it. TiPToP's contribution includes making those module boundaries practical to implement, inspect, and improve.", "source": "Paper §§IV-B,VII-D; original vocabulary exercise", "start": 183.66132264529057, "duration": 43.08216432865732, "end": 226.74348697394788}, {"title": "A planned future can go stale", "visual": "openloop", "equation": "planned scene ≠ scene after disturbance", "points": ["Execution follows the computed trajectory", "Visual feedback does not update the plan", "Object motion can invalidate a grasp"], "narration": "The planner finds a valid grasp at the snack's estimated location. Now, after perception, slide the snack a little to the right. The gripper continues toward the old target. TiPToP's reported execution does not monitor visual observations and replan during the trajectory. Its low-level impedance controller still uses robot feedback, so open loop here means open loop with respect to scene perception and task replanning, not the absence of all control feedback. This distinction prevents a common misunderstanding. The companion's disturbance slider makes the failure concrete: the plan can remain valid in the saved model while missing the object in the changed physical scene.", "source": "Paper §§VI,VIII; original disturbance example", "start": 226.74348697394788, "duration": 41.38226452905812, "end": 268.125751503006}, {"title": "Debug the interface that failed", "visual": "failurebars", "equation": "55 failures / 173 diagnostic trials", "points": ["31 grasping failures", "13 scene completion errors", "6 VLM errors · 5 planning failures"], "narration": "The authors conducted a separate diagnostic study with one hundred seventy-three trials. Fifty-five failed. Of those failures, thirty-one involved grasping, thirteen scene completion, six vision-language detection errors, and five planning failures. Those are counts from that specific study, not a universal ranking of robot bottlenecks. The broader evaluation covered twenty-eight scenes and a different trial set. Keeping those denominators separate matters. In the bar chart, notice how improving search alone leaves most observed failures untouched. Modularity pays off because a failure can be traced to an interface or component. It also helps identify where closed-loop recovery, better geometry, or improved grasp proposals could have the greatest effect.", "source": "Paper §VII-E and Fig.4; diagnostic study", "start": 268.125751503006, "duration": 47.33191382765531, "end": 315.45766533066126}, {"title": "Strong modules still need a strong loop", "visual": "lineage", "equation": "perceive → plan → execute → ? observe", "points": ["No task-specific robot training data", "Pretrained models and engineered modules", "Feedback remains a key extension"], "narration": "TiPToP demonstrates how much a system can do by composing pretrained perception models with an existing planner and a controller. Its no-robot-training-data claim should not be read as no prior knowledge: the system uses pretrained models, calibrated hardware, engineered skills, and geometric assumptions. What makes the result interesting is the level of behavior obtained from that composition. In the interactive scene, first optimize with an accurate observation, then add perception error, and finally disturb the object after planning. These are different failure causes. The final picture is a chain of useful modules whose reliability depends on their interfaces and on whether the world still matches the state they planned from.", "source": "Paper §§I,VIII–IX; original interactive exercise", "start": 315.45766533066126, "duration": 44.54233466933868, "end": 359.99999999999994}], "duration": 360, "subtitles": [{"start": 0.6110483153807615, "end": 5.287096724699399, "text": "So far our planner has enjoyed a luxury someone handed it objects poses"}, {"start": 5.459819075651303, "end": 10.34559262274549, "text": "and a goal A real robot starts with camera images Tip Top addresses"}, {"start": 10.357927793086173, "end": 14.663863884018037, "text": "the full path from images and a natural-language instruction to manipulation"}, {"start": 15.071018036072145, "end": 19.796404402555112, "text": "Its three major modules are perception planning and execution Our teaching"}, {"start": 19.808739572895792, "end": 23.855536291332665, "text": "example asks the robot to put a snack on a tray while a carton obstructs"}, {"start": 23.867908692384773, "end": 29.037452905811627, "text": "access Watch the initial image acquire object identities geometry and"}, {"start": 29.049788076152307, "end": 33.73817074774549, "text": "grasp candidates The system is modular so its internal decisions can"}, {"start": 33.750505918086176, "end": 38.007065913076154, "text": "be inspected That matters both when it succeeds and when a perfectly"}, {"start": 38.019400175350704, "end": 41.95518580911824, "text": "reasonable-looking plan turns out to depend on a mistaken reconstruction"}, {"start": 41.967520979458925, "end": 42.51039287950902, "text": "of the scene"}, {"start": 44.49957536948899, "end": 48.57107965931864, "text": "Tip Top builds its scene through two branches One estimates depth and"}, {"start": 48.58341392159319, "end": 53.51852633391785, "text": "proposes grasps The other identifies objects segments them and grounds"}, {"start": 53.5308605961924, "end": 58.083563658567144, "text": "the language goal In the reported system FoundationStereo supplies depth"}, {"start": 58.36733432489981, "end": 63.610886836172355, "text": "M two T two proposes grasps Gemini provides semantic grounding and SAM"}, {"start": 63.62325923722446, "end": 68.31164190881765, "text": "two supplies masks The outputs are merged into object-centered geometry"}, {"start": 68.37331503632265, "end": 72.67925112725452, "text": "and candidate grasps Our animation separates these streams so you can"}, {"start": 72.69154815881765, "end": 76.49165327530062, "text": "see their different jobs A label such as snack does not determine the"}, {"start": 76.50395030686374, "end": 81.26634036823648, "text": "surface shape A precise point cloud does not by itself decide which"}, {"start": 81.38976199273549, "end": 86.0904416958918, "text": "item the user meant The planning input needs both joined through a consistent"}, {"start": 86.10281500501003, "end": 89.74249480210423, "text": "correspondence between perceived pixels and physical objects"}, {"start": 91.710186998998, "end": 95.69531058992986, "text": "Look at this U-shaped object from above A convex hull fills its empty"}, {"start": 95.70764576027055, "end": 100.00124668086173, "text": "center If we use that filled shape for collision checking a real opening"}, {"start": 100.01354371242486, "end": 104.80064134519039, "text": "disappears from the model The opposite mistake is also possible an unseen"}, {"start": 104.81297560746494, "end": 109.1312078218938, "text": "surface is missing so the model allows a motion that will collide Tip"}, {"start": 109.14358113101203, "end": 113.70854217810623, "text": "Top constructs meshes from partial observations and its paper identifies"}, {"start": 113.72091548722446, "end": 118.18720061999, "text": "shape completion as a source of failures Our U shape is an illustrative"}, {"start": 118.19953579033067, "end": 122.35741896292586, "text": "counterexample rather than a reported experiment The point is that motion"}, {"start": 122.36975322520041, "end": 126.76203096818638, "text": "feasibility is evaluated against reconstructed geometry Improving the"}, {"start": 126.77436613852706, "end": 131.09259835295592, "text": "planner cannot repair every error in the world model it was given Sometimes"}, {"start": 131.1049335232966, "end": 132.9432752692886, "text": "the right fix belongs in perception"}, {"start": 134.9136535258016, "end": 139.23188664829658, "text": "The planning module uses cue Tamp For a candidate action skeleton it"}, {"start": 139.24422091057113, "end": 143.46377721067134, "text": "initializes many continuous parameter assignments and optimizes them"}, {"start": 143.47611238101203, "end": 147.99177360971944, "text": "in parallel on a GPU The moving dots in our drawing stand for complete"}, {"start": 148.004107871994, "end": 151.85351371492985, "text": "candidate assignments compressed into two dimensions so we can see them"}, {"start": 152.27300303732466, "end": 156.56660395791582, "text": "They move toward lower constraint violation only candidates satisfying"}, {"start": 156.57890098947897, "end": 161.23027996618237, "text": "the necessary conditions are useful Motion planning then connects configurations"}, {"start": 161.31666066508015, "end": 166.23947513777554, "text": "into executable trajectories using cue Robo The dots are a conceptual"}, {"start": 166.25181030811623, "end": 170.90319019288577, "text": "animation not real cue Tamp optimization traces Their purpose is to"}, {"start": 170.91552445516032, "end": 175.55453193887774, "text": "reveal the division of labor discrete search proposes a structure batched"}, {"start": 175.56686620115232, "end": 179.89747172469941, "text": "optimization seeks compatible geometric values and motion planning builds"}, {"start": 179.90980598697394, "end": 182.29102054108216, "text": "paths between the required configurations"}, {"start": 184.2600366983968, "end": 188.26982881387775, "text": "Ask for the snack rather than a particular object identifier The semantic"}, {"start": 188.2821639842184, "end": 192.0575252066633, "text": "module can use visual and linguistic knowledge to choose the intended"}, {"start": 192.06989760771543, "end": 196.30178817009016, "text": "item That is one source of open-vocabulary behavior But the released"}, {"start": 196.3141224323647, "end": 200.18819770791583, "text": "paper's main system grounds these requests into a limited action and"}, {"start": 200.20053197019035, "end": 204.54343361723446, "text": "predicate model primarily pick and place with an on relation It also"}, {"start": 204.5558069263527, "end": 208.9233770979459, "text": "demonstrates extending the system with a wiping skill Our visualization"}, {"start": 208.93575040706412, "end": 213.11826487349697, "text": "lets the words vary while keeping the supported relation explicit There"}, {"start": 213.13059913577155, "end": 217.26377564504008, "text": "is an engineering step between recognizing a new request and possessing"}, {"start": 217.27611081538075, "end": 221.19959850951903, "text": "the motor skill to fulfill it Tip Top's contribution includes making"}, {"start": 221.2118964491483, "end": 225.36977871367736, "text": "those module boundaries practical to implement inspect and improve"}, {"start": 227.35453528932865, "end": 231.5123812312124, "text": "The planner finds a valid grasp at the snack's estimated location Now"}, {"start": 231.73447877004006, "end": 236.2007639028056, "text": "after perception slide the snack a little to the right The gripper continues"}, {"start": 236.21309907314628, "end": 240.33394041207413, "text": "toward the old target Tip Top's reported execution does not monitor"}, {"start": 240.34627558241482, "end": 244.92360903056112, "text": "visual observations and replan during the trajectory Its low-level impedance"}, {"start": 244.93598233967936, "end": 249.37759803982965, "text": "controller still uses robot feedback so open loop here means open loop"}, {"start": 249.38993321017034, "end": 253.1652935245491, "text": "with respect to scene perception and task replanning not the absence"}, {"start": 253.1776659256012, "end": 257.6439510583667, "text": "of all control feedback This distinction prevents a common misunderstanding"}, {"start": 258.0634403807615, "end": 262.1226095002505, "text": "The companion's disturbance slider makes the failure concrete the plan"}, {"start": 262.13494376252504, "end": 265.5772326841182, "text": "can remain valid in the saved model while missing the object in the"}, {"start": 265.58953062374746, "end": 266.76161607590177, "text": "changed physical scene"}, {"start": 268.7244655561122, "end": 272.89464485220435, "text": "The authors conducted a separate diagnostic study with one hundred seventy-three"}, {"start": 272.90698002254504, "end": 278.2986226828657, "text": "trials Fifty-five failed Of those failures thirty-one involved grasping"}, {"start": 278.58239334919836, "end": 282.6538967309619, "text": "thirteen scene completion six vision-language detection errors and five"}, {"start": 282.6662319013026, "end": 287.18189313001, "text": "planning failures Those are counts from that specific study not a universal"}, {"start": 287.1942283003507, "end": 291.4384149862224, "text": "ranking of robot bottlenecks The broader evaluation covered twenty-eight"}, {"start": 291.45078829534066, "end": 295.3619035884268, "text": "scenes and a different trial set Keeping those denominators separate"}, {"start": 295.3742387587675, "end": 299.84052389153305, "text": "matters In the bar chart notice how improving search alone leaves most"}, {"start": 299.8528590618737, "end": 304.26980532940877, "text": "observed failures untouched Modularity pays off because a failure can"}, {"start": 304.28214049974946, "end": 308.3042677855711, "text": "be traced to an interface or component It also helps identify where"}, {"start": 308.3166410946893, "end": 312.9679819326152, "text": "closed-loop recovery better geometry or improved grasp proposals could"}, {"start": 312.98035524173343, "end": 314.103065506012, "text": "have the greatest effect"}, {"start": 316.0563793837675, "end": 319.9551604145791, "text": "Tip Top demonstrates how much a system can do by composing pretrained"}, {"start": 319.96745835420836, "end": 324.86560430235465, "text": "perception models with an existing planner and a controller Its no-robot-training-data"}, {"start": 324.87793947269535, "end": 329.6033258391783, "text": "claim should not be read as no prior knowledge the system uses pretrained"}, {"start": 329.615661009519, "end": 334.31641608216427, "text": "models calibrated hardware engineered skills and geometric assumptions"}, {"start": 334.72353300350693, "end": 338.21515988226446, "text": "What makes the result interesting is the level of behavior obtained"}, {"start": 338.22749505260515, "end": 342.4470504446392, "text": "from that composition In the interactive scene first optimize with an"}, {"start": 342.5210587424849, "end": 346.8023254008015, "text": "accurate observation then add perception error and finally disturb the"}, {"start": 346.8763327905811, "end": 351.0835539203406, "text": "object after planning These are different failure causes The final picture"}, {"start": 351.0958890906813, "end": 355.2290655999498, "text": "is a chain of useful modules whose reliability depends on their interfaces"}, {"start": 355.45112590806605, "end": 358.6466478582164, "text": "and on whether the world still matches the state they planned from"}], "voice": "en-US-AndrewNeural · synthetic narration"}, {"id": "gap", "short": "GaP", "number": "05", "color": "#f79c84", "title": "Did we reinvent TAMP?", "paper": "GaP: A Graph-as-Policy Multi-Agent Self-Learning Harness For Variational Automation Tasks", "authors": "Kaiyuan Chen et al.", "year": "2026 · arXiv v1", "url": "https://arxiv.org/abs/2607.05369", "summary": "What graph generation and simulation rehearsal add to modular robot planning.", "sources": [{"label": "Chen et al. · paper v1", "url": "https://arxiv.org/html/2607.05369v1"}, {"label": "Authors’ project", "url": "https://graph-robots.github.io/gap/"}, {"label": "Official graph runtime and documentation", "url": "https://github.com/graph-robots/graph-as-policy"}], "chapters": [{"title": "A familiar-looking robot pipeline", "visual": "graph", "equation": "perceive → plan motion → act → inspect", "points": ["Explicit structure", "Reusable robot components", "Geometric planning inside the system"], "narration": "A robot identifies an object, plans a collision-free motion, picks it up, and checks what happened. Draw those operations as connected boxes and the resemblance to classical robotics is immediate. So, did GaP reinvent task and motion planning? There is a useful joke here, but also a technical distinction worth keeping. GaP explicitly acknowledges inspiration from TAMP and the Robot Operating System. Its proposal is to use coding agents to generate modular execution graphs and improve them through rehearsal. Our final episode follows one graph through a toy packing task, then compares the object being optimized with the action-and-geometry search we studied in the first episode.", "source": "Paper §§1–2; original comparison", "start": 0, "duration": 42.08465136316081, "end": 42.08465136316081}, {"title": "A bounded world with varying instances", "visual": "distribution", "equation": "task instances x ~ D", "points": ["Known robot and workcell", "Objects and poses vary within bounds", "Repeated success and throughput matter"], "narration": "First specify the setting. A factory station may see different package sizes and different initial poses while keeping the robot, sensors, and workcell fixed. GaP calls its target setting variational automation. It sits between tightly repeated fixed automation and broadly open-ended generalist robotics. In our drawing, each dot is one possible initial object position. A graph that succeeds only at the center of that distribution is not enough. We want reliable repeated execution across the allowed variation. The paper assumes a known workcell and bounded object and pose ranges. Those assumptions are part of the problem definition, and they shape what simulation rehearsal can usefully teach the system.", "source": "Paper §3; original position distribution", "start": 42.08465136316081, "duration": 44.33340513262355, "end": 86.41805649578436}, {"title": "The generated object is a program graph", "visual": "typedgraph", "equation": "node: typed inputs → operation → outputs", "points": ["Nodes perform atomic operations", "Edges route data and control", "The graph is an executable policy"], "narration": "A graph node can capture an image, call perception, compute a target, plan motion, or issue a robot command. Edges carry outputs into the next operation and can express conditional execution. Think of the graph as a visible program with typed interfaces. In our toy example, a detect node produces a pose, a motion-planning node consumes that pose, and a verification node decides whether to continue or retry. This is richer than a single fixed sequence of action names, but a graph is not automatically a correct policy. Every node still needs meaningful semantics, compatible inputs, and sensible behavior when the world violates an expectation.", "source": "Paper §3; original retry graph", "start": 86.41805649578436, "duration": 41.97756785032925, "end": 128.3956243461136}, {"title": "Who writes the graph?", "visual": "agents", "equation": "task description → subgraphs → execution graph", "points": ["An orchestrator divides the task", "Skill agents construct local pieces", "Evaluation feeds back into revision"], "narration": "GaP uses an orchestration agent to divide the task into functional segments and skill agents to produce subgraphs. These are combined using a modular robot skill library. The important object for us is the resulting graph, not the conversational transcript of the agents. Different generated graphs can be tested, diagnosed, and revised. Our animation assembles perception, manipulation, and verification subgraphs into one program. This diagram is a conceptual simplification of the paper's harness. It shows how a familiar robotics architecture can acquire a new construction process: instead of an engineer manually wiring every detail, coding agents synthesize the wiring and use execution evidence to improve it.", "source": "Authors’ project · architecture; original subgraph illustration", "start": 128.3956243461136, "duration": 46.00390793279586, "end": 174.39953227890948}, {"title": "Rehearsal changes the policy", "visual": "rehearsal", "equation": "graph + parameters → trials → revision", "points": ["Sample task instances in simulation", "Inspect failure and cycle time", "Revise structure or parameters"], "narration": "Run the first toy graph on many starting positions. Its cached target works near the center and fails toward the edges. Now add a fresh observation before grasping. The successful region expands, although an extra perception call costs time. A retry branch can recover some transient failures while making unsuccessful episodes longer. These are educational examples of graph edits, not reproductions of GaP's measured experiments. The paper's self-learning harness rehearses task instances in simulation and revises graph structure and parameters to improve performance. This creates an outer search over programs. Inside each program, a motion planner may still solve ordinary geometric planning problems. The two searches operate at different levels.", "source": "Paper §§3–4; original rehearsal experiment", "start": 174.39953227890948, "duration": 47.1604098713767, "end": 221.5599421502862}, {"title": "Success per hour is a different objective", "visual": "throughput", "equation": "throughput = 3600 × success rate / mean seconds", "points": ["Recovery can raise success", "Extra checks can increase cycle time", "Measure across the full trial distribution"], "narration": "Suppose graph A succeeds ninety percent of the time and takes ten seconds per attempt. That is about three hundred twenty-four successes per hour in this simplified model. Graph B succeeds ninety-eight percent of the time but takes twenty seconds per attempt, giving about one hundred seventy-six successes per hour. These invented numbers show why accuracy alone does not settle an automation design. Real cycle-time accounting must include retries, failures, and resets. The paper considers reliability and throughput together. In the companion, toggle the retry edge and run the same seeded toy trials. You can see an improvement in success come with a measurable increase in average time.", "source": "Paper §3 objective; original numeric example", "start": 221.5599421502862, "duration": 42.68431903501754, "end": 264.24426118530374}, {"title": "The TAMP resemblance, made precise", "visual": "comparison", "equation": "TAMP: plan & geometry | GaP: graph & parameters", "points": ["Shared: modular physical reasoning", "Different: the main object being searched", "A graph can call a planner as a component"], "narration": "Here is the comparison I would defend. TAMP concerns the coupled choice of discrete actions and continuous parameters that make a task feasible. GaP's outer harness generates and revises executable graphs that compose perception, planning, control, and other skills across task instances. Both benefit from explicit structure and specialized geometric computation. But graph synthesis is not, by itself, equivalent to searching a formal TAMP problem, and calling a motion planner does not automatically confer TAMP-style guarantees. Conversely, classical TAMP systems can also operate inside feedback policies; feedback is not unique to GaP. The most useful question is which decisions are searched at which layer, rather than who owns the idea of boxes and arrows.", "source": "Cross-paper interpretation; not an author claim", "start": 264.24426118530374, "duration": 48.01707797402917, "end": 312.2613391593329}, {"title": "What the new layer buys—and what it needs", "visual": "lineage", "equation": "generate structure • test behavior • retain evidence", "points": ["Less manual graph construction", "Evidence from a bounded task distribution", "Limits from skills, simulation, and evaluation"], "narration": "GaP's distinctive emphasis is the construction and rehearsal of modular robot programs for repeated tasks with bounded variation. Its experiments cover eight benchmarks across simulation and hardware, while the authors acknowledge remaining reliability, throughput, and task-coverage limitations. Simulation success also depends on how well the rehearsal distribution represents deployment. A polished graph can still overfit its tests or call a weak skill. That brings the series full circle. Explicit structure is valuable when it exposes assumptions and lets failures change the search. Whether we are refining a skeleton, certifying a stream output, intersecting constraints, or revising a graph, the essential discipline is to connect a proposed behavior to evidence that it can work.", "source": "Paper §6; cross-series interpretation", "start": 312.2613391593329, "duration": 47.738660840667116, "end": 360.00000000000006}], "duration": 360, "subtitles": [{"start": 0.5970069542741092, "end": 4.670827866330236, "text": "A robot identifies an object plans a collision-free motion picks it"}, {"start": 4.682949719982768, "end": 8.938626100067697, "text": "up and checks what happened Draw those operations as connected boxes"}, {"start": 9.132640900978522, "end": 14.152180564957844, "text": "and the resemblance to classical robotics is immediate So did Gap reinvent"}, {"start": 14.164302418610376, "end": 18.286608068188812, "text": "task and motion planning There is a useful joke here but also a technical"}, {"start": 18.298766508708226, "end": 22.251338543910393, "text": "distinction worth keeping Gap explicitly acknowledges inspiration from"}, {"start": 22.26345950520032, "end": 26.688908763616222, "text": "TAMP and the Robot Operating System Its proposal is to use coding agents"}, {"start": 26.701029724906146, "end": 30.677881161917654, "text": "to generate modular execution graphs and improve them through rehearsal"}, {"start": 31.077956766570253, "end": 35.2124208566681, "text": "Our final episode follows one graph through a toy packing task then"}, {"start": 35.224542710320634, "end": 39.16499289187027, "text": "compares the object being optimized with the action-and-geometry search"}, {"start": 39.1771147455228, "end": 40.7169230106468, "text": "we studied in the first episode"}, {"start": 42.730143054957225, "end": 46.7312373069112, "text": "First specify the setting A factory station may see different package"}, {"start": 46.74335826820112, "end": 51.12028441750262, "text": "sizes and different initial poses while keeping the robot sensors and"}, {"start": 51.13240627115515, "end": 55.448764200873896, "text": "workcell fixed Gap calls its target setting variational automation It"}, {"start": 55.460848575296936, "end": 59.55894888916241, "text": "sits between tightly repeated fixed automation and broadly open-ended"}, {"start": 59.57107074281494, "end": 64.11773229121792, "text": "generalist robotics In our drawing each dot is one possible initial"}, {"start": 64.12989073173733, "end": 68.628067542618, "text": "object position A graph that succeeds only at the center of that distribution"}, {"start": 68.83416671795187, "end": 73.24745664348575, "text": "is not enough We want reliable repeated execution across the allowed"}, {"start": 73.25961597636777, "end": 77.62445775124623, "text": "variation The paper assumes a known workcell and bounded object and"}, {"start": 77.63654301803187, "end": 81.64975733891316, "text": "pose ranges Those assumptions are part of the problem definition and"}, {"start": 81.66187919256569, "end": 85.06888214659364, "text": "they shape what simulation rehearsal can usefully teach the system"}, {"start": 87.01506345005846, "end": 91.5981253615607, "text": "A graph node can capture an image call perception compute a target plan"}, {"start": 91.61024721521325, "end": 96.60550747738323, "text": "motion or issue a robot command Edges carry outputs into the next operation"}, {"start": 96.72675724659979, "end": 100.72785060619115, "text": "and can express conditional execution Think of the graph as a visible"}, {"start": 100.73997245984368, "end": 105.60189768601144, "text": "program with typed interfaces In our toy example a detect node produces"}, {"start": 105.61401953966399, "end": 109.89397621392085, "text": "a pose a motion-planning node consumes that pose and a verification"}, {"start": 109.9060980675734, "end": 114.12541156378855, "text": "node decides whether to continue or retry This is richer than a single"}, {"start": 114.13753252507846, "end": 118.46597393685765, "text": "fixed sequence of action names but a graph is not automatically a correct"}, {"start": 118.47809579051018, "end": 123.36426472398301, "text": "policy Every node still needs meaningful semantics compatible inputs"}, {"start": 123.60676426241615, "end": 127.03800913902394, "text": "and sensible behavior when the world violates an expectation"}, {"start": 128.99263130038773, "end": 133.2240657578928, "text": "Gap uses an orchestration agent to divide the task into functional segments"}, {"start": 133.28467234906765, "end": 137.73436353006338, "text": "and skill agents to produce subgraphs These are combined using a modular"}, {"start": 137.7464853837159, "end": 142.12341242538002, "text": "robot skill library The important object for us is the resulting graph"}, {"start": 142.48716173302972, "end": 146.1366642254908, "text": "not the conversational transcript of the agents Different generated"}, {"start": 146.14878607914332, "end": 151.58055978829466, "text": "graphs can be tested diagnosed and revised Our animation assembles perception"}, {"start": 151.83518028801774, "end": 156.52733442057973, "text": "manipulation and verification subgraphs into one program This diagram"}, {"start": 156.64858418979628, "end": 160.47994304264878, "text": "is a conceptual simplification of the paper's harness It shows how a"}, {"start": 160.49206489630132, "end": 164.4567570004308, "text": "familiar robotics architecture can acquire a new construction process"}, {"start": 164.85687008431287, "end": 169.8642887870023, "text": "instead of an engineer manually wiring every detail coding agents synthesize"}, {"start": 169.8764097482922, "end": 173.05299753831005, "text": "the wiring and use execution evidence to improve it"}, {"start": 174.9965392331836, "end": 179.0703601452397, "text": "Run the first toy graph on many starting positions Its cached target"}, {"start": 179.08248199889223, "end": 183.41092341067144, "text": "works near the center and fails toward the edges Now add a fresh observation"}, {"start": 183.42304526432397, "end": 188.04247095205858, "text": "before grasping The successful region expands although an extra perception"}, {"start": 188.05459280571114, "end": 192.66189753215582, "text": "call costs time A retry branch can recover some transient failures while"}, {"start": 192.67401938580835, "end": 196.90549132254293, "text": "making unsuccessful episodes longer These are educational examples of"}, {"start": 196.91761228383285, "end": 201.64616767185674, "text": "graph edits not reproductions of Gap's measured experiments The paper's"}, {"start": 201.65828863314667, "end": 206.02309471352083, "text": "self-learning harness rehearses task instances in simulation and revises"}, {"start": 206.03521567481076, "end": 210.14543784232876, "text": "graph structure and parameters to improve performance This creates an"}, {"start": 210.27880946519787, "end": 214.8497504154102, "text": "outer search over programs Inside each program a motion planner may"}, {"start": 214.8618722690627, "end": 219.3236478244815, "text": "still solve ordinary geometric planning problems The two searches operate"}, {"start": 219.33580626500094, "end": 220.19663813157734, "text": "at different levels"}, {"start": 222.16907006585024, "end": 226.27929223336824, "text": "Suppose graph A succeeds ninety percent of the time and takes ten seconds"}, {"start": 226.29137660779128, "end": 229.94084162102286, "text": "per attempt That is about three hundred twenty-four successes per hour"}, {"start": 230.0136066527171, "end": 233.96617779555666, "text": "in this simplified model Graph B succeeds ninety-eight percent of the"}, {"start": 233.9782996492092, "end": 238.46439208566682, "text": "time but takes twenty seconds per attempt giving about one hundred seventy-six"}, {"start": 238.47651393931937, "end": 242.9262051203151, "text": "successes per hour These invented numbers show why accuracy alone does"}, {"start": 242.93832697396766, "end": 247.14551861653027, "text": "not settle an automation design Real cycle-time accounting must include"}, {"start": 247.1576404701828, "end": 252.69854298726077, "text": "retries failures and resets The paper considers reliability and throughput"}, {"start": 252.7106639485507, "end": 257.33009052864793, "text": "together In the companion toggle the retry edge and run the same seeded"}, {"start": 257.3422114899379, "end": 261.4281533632839, "text": "toy trials You can see an improvement in success come with a measurable"}, {"start": 261.44027521693647, "end": 262.8952358606684, "text": "increase in average time"}, {"start": 264.8533891008678, "end": 268.6725895132008, "text": "Here is the comparison I would defend TAMP concerns the coupled choice"}, {"start": 268.6847113668534, "end": 272.78277420148936, "text": "of discrete actions and continuous parameters that make a task feasible"}, {"start": 273.18292476460095, "end": 277.37799544587364, "text": "Gap's outer harness generates and revises executable graphs that compose"}, {"start": 277.39011729952614, "end": 282.57939147024433, "text": "perception planning control and other skills across task instances Both"}, {"start": 282.5915133238969, "end": 286.6410914210106, "text": "benefit from explicit structure and specialized geometric computation"}, {"start": 287.0896901347776, "end": 291.73335863745467, "text": "But graph synthesis is not by itself equivalent to searching a formal"}, {"start": 291.74551707797406, "end": 295.57683934395965, "text": "TAMP problem and calling a motion planner does not automatically confer"}, {"start": 295.5889603052496, "end": 300.1962650316943, "text": "TAMP-style guarantees Conversely classical TAMP systems can also operate"}, {"start": 300.20838688534684, "end": 305.0824339651671, "text": "inside feedback policies feedback is not unique to Gap The most useful"}, {"start": 305.09455581881963, "end": 308.34394522739865, "text": "question is which decisions are searched at which layer rather than"}, {"start": 308.35606618868854, "end": 310.9143216505631, "text": "who owns the idea of boxes and arrows"}, {"start": 312.87046707489696, "end": 316.83516007138905, "text": "Gap's distinctive emphasis is the construction and rehearsal of modular"}, {"start": 316.84728103267895, "end": 321.2848512523848, "text": "robot programs for repeated tasks with bounded variation Its experiments"}, {"start": 321.29697310603734, "end": 325.47992193365747, "text": "cover eight benchmarks across simulation and hardware while the authors"}, {"start": 325.49204378731, "end": 329.7841223152194, "text": "acknowledge remaining reliability throughput and task-coverage limitations"}, {"start": 330.19635636039146, "end": 334.30654104867995, "text": "Simulation success also depends on how well the rehearsal distribution"}, {"start": 334.42779171025916, "end": 338.3682784786756, "text": "represents deployment A polished graph can still overfit its tests or"}, {"start": 338.3804003323282, "end": 342.8664552895563, "text": "call a weak skill That brings the series full circle Explicit structure"}, {"start": 342.8785771432089, "end": 346.7826626561635, "text": "is valuable when it exposes assumptions and lets failures change the"}, {"start": 346.79478450981605, "end": 350.94137045356644, "text": "search Whether we are refining a skeleton certifying a stream output"}, {"start": 351.317240722506, "end": 355.42742541079457, "text": "intersecting constraints or revising a graph the essential discipline"}, {"start": 355.52443325743127, "end": 358.6525363099268, "text": "is to connect a proposed behavior to evidence that it can work"}], "voice": "en-US-AndrewNeural · synthetic narration"}];</script>
<script>/* All experiments run locally. No network, framework, or API is required. */
'use strict';
const $=s=>document.querySelector(s), $$=s=>[...document.querySelectorAll(s)];
const colors={ink:'#edf2fa',muted:'#98a9bf',line:'#30425b',cyan:'#69d5ec',green:'#82e1b0',yellow:'#f2c86d',red:'#f79c84',purple:'#b4a1ff',bg:'#0e1826'};
const metadata={
'integrated-tamp':{type:'The foundations',lab:'When does the robot need another action?',intro:'Change the gripper clearance. A grid search tests geometric paths; if the direct skeleton fails, the toy planner can try relocating the blocker.',challenge:'Set clearance above 0.55 and turn off “Allow moving the blocker.” Then turn it on. The same final goal now needs a different action sequence.',scope:'A disk-shaped end effector in 2D, with A* on a 0.10-unit grid. Relocating the blocker is an assumed available primitive. This is not an articulated-arm simulator or the survey’s implementation.',key:[['cyan','robot / cup'],['red','blocker'],['green','computed path']]},
pddlstream:{type:'The planning interface',lab:'Turn an optimistic plan into a witness.',intro:'Advance real toy sampling calls. Each successful grasp, reachability test, and grid path fills one dependency in an optimistic plan.',challenge:'Run the focused schedule, note its call count, then reset to the broad schedule using the same seed. Inspect which extra calls do not support the cup plan.',scope:'A small dependency scheduler, not the paper’s full algorithms. The broad schedule deliberately performs two unrelated placement calls per chain; call counts illustrate this choice and are not benchmarks.',key:[['purple','optimistic placeholder'],['green','grounded output'],['red','failed test']]},
'owl-tamp':{type:'Language as constraints',lab:'Draw the meaning of a goal.',intro:'Choose a spatial relation and move the candidate cup. The visualizer evaluates a language predicate, reachability, and collision avoidance independently.',challenge:'Find a point accepted by the yellow language region but rejected by geometry. Tighten the “near” threshold until little or no feasible area remains.',scope:'The predicates here are hand-written teaching examples, not live VLM outputs. Distances, reach, and object size are simplified 2D choices. The inserted-action sketch is illustrative.',key:[['yellow','language region'],['green','all tests pass'],['red','obstacle / rejected candidate']]},
tiptop:{type:'A complete robot system',lab:'A valid plan can belong to a stale world.',intro:'Optimize candidate grasp targets in the perceived scene, then execute against the actual object. Add perception bias or move the object after the snapshot.',challenge:'Optimize and execute with both offsets at zero. Next, change only the post-snapshot shift and execute again. The stored plan stays put while the object moves.',scope:'A 2D quadratic optimization and grasp-tolerance model illustrates module boundaries. No foundation model, cuTAMP, or cuRobo is running here. Visual replanning is intentionally absent, matching the reported system’s limitation.',key:[['cyan','candidate grasp targets'],['green','selected target'],['yellow','actual object']]},
gap:{type:'Generating robot programs',lab:'Change the graph. Measure the behavior.',intro:'Run a graph across 120 seeded toy instances. Fresh observations and one retry alter both success and cycle time. Rehearsal searches four graph variants.',challenge:'Run the cached-target graph under wide pose variation. Add fresh observations and compare success. Add a retry and inspect the change in successes per hour.',scope:'All displayed results come from this toy stochastic model, not the GaP paper. The workcell is fixed; object position, observation noise, and transient grasp failures vary. Rehearsal evaluates four predeclared graphs, not LLM agents.',key:[['green','successful toy trial'],['red','failed toy trial'],['yellow','optional recovery edge']]}
};
let current=0,view='watch',state={},animTime=0;
const canvas=$('#lab'),ctx=canvas.getContext('2d');
const film=$('#film');
const fmt=t=>`${Math.floor(t/60)}:${String(Math.floor(t%60)).padStart(2,'0')}`;
const clamp=(x,a,b)=>Math.max(a,Math.min(b,x));
const lerp=(a,b,t)=>a+(b-a)*t;
const distance=(a,b)=>Math.hypot(a[0]-b[0],a[1]-b[1]);
const escapeHTML=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
function rng(seed){let x=seed>>>0;return()=>{x+=0x6D2B79F5;let t=x;t=Math.imul(t^t>>>15,t|1);t^=t+Math.imul(t^t>>>7,t|61);return((t^t>>>14)>>>0)/4294967296;};}
function gaussian(r){return Math.sqrt(-2*Math.log(Math.max(1e-9,r())))*Math.cos(Math.PI*2*r());}
function setStatus(text){if($('#lab-status').textContent!==text)$('#lab-status').textContent=text;}
function text(x,y,s,size=18,color=colors.ink,align='left',weight=400){ctx.font=`${weight} ${size}px -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif`;ctx.fillStyle=color;ctx.textAlign=align;ctx.textBaseline='middle';ctx.fillText(s,x,y);}
function line(points,color=colors.line,width=2,dash=[]){if(!points.length)return;ctx.strokeStyle=color;ctx.lineWidth=width;ctx.setLineDash(dash);ctx.beginPath();points.forEach((p,i)=>i?ctx.lineTo(...p):ctx.moveTo(...p));ctx.stroke();ctx.setLineDash([]);}
function circle(x,y,r,color=colors.cyan,fill=null,width=2){ctx.beginPath();ctx.arc(x,y,r,0,Math.PI*2);if(fill){ctx.fillStyle=fill;ctx.fill();}ctx.strokeStyle=color;ctx.lineWidth=width;ctx.stroke();}
function box(x,y,w,h,label='',color=colors.line,fill='#162436',size=17){ctx.beginPath();ctx.roundRect(x,y,w,h,10);ctx.fillStyle=fill;ctx.fill();ctx.strokeStyle=color;ctx.lineWidth=1.5;ctx.stroke();if(label)text(x+w/2,y+h/2,label,size,colors.ink,'center');}
function arrow(a,b,color=colors.cyan,width=2,dash=[]){line([a,b],color,width,dash);const angle=Math.atan2(b[1]-a[1],b[0]-a[0]);ctx.fillStyle=color;ctx.beginPath();ctx.moveTo(...b);ctx.lineTo(b[0]-11*Math.cos(angle-.4),b[1]-11*Math.sin(angle-.4));ctx.lineTo(b[0]-11*Math.cos(angle+.4),b[1]-11*Math.sin(angle+.4));ctx.fill();}
function grid(){for(let x=60;x<=880;x+=41)line([[x,70],[x,480]],'#1c2b40',1);for(let y=70;y<=480;y+=41)line([[60,y],[880,y]],'#1c2b40',1);}
function heading(kicker,subtitle){text(48,34,kicker,13,colors.muted,'left',650);if(subtitle)text(892,34,subtitle,12,colors.muted,'right');}
function world(p){return[60+p[0]*82,70+p[1]*68.3];}
function unworld(p){return[clamp((p[0]-60)/82,0,10),clamp((p[1]-70)/68.3,0,6)];}
function wp(points,color=colors.green,width=3,dash=[]){line(points.map(world),color,width,dash);}
function disk(p,r,col,fill){const q=world(p);ctx.beginPath();ctx.ellipse(...q,r*82,r*68.3,0,0,Math.PI*2);if(fill){ctx.fillStyle=fill;ctx.fill();}ctx.strokeStyle=col;ctx.lineWidth=2;ctx.stroke();}
function obstacle(o,inflation=0){const [x,y]=world([o.x,o.y]);box(x,y,o.w*82,o.h*68.3,'B',colors.red,'#50372f',22);if(inflation){ctx.beginPath();ctx.roundRect(x-inflation*82,y-inflation*68.3,(o.w+2*inflation)*82,(o.h+2*inflation)*68.3,inflation*70);ctx.strokeStyle='#a46256';ctx.lineWidth=1.5;ctx.setLineDash([5,5]);ctx.stroke();ctx.setLineDash([]);}}
function collision(p,r,obs){if(p[0]<r||p[0]>10-r||p[1]<r||p[1]>6-r)return true;return obs.some(o=>Math.hypot(p[0]-clamp(p[0],o.x,o.x+o.w),p[1]-clamp(p[1],o.y,o.y+o.h))<r+.001);}
function segmentOK(a,b,r,obs){const n=Math.ceil(distance(a,b)/.025);for(let j=0;j<=n;j++){let f=j/Math.max(n,1);if(collision([lerp(a[0],b[0],f),lerp(a[1],b[1],f)],r,obs))return false;}return true;}
function astar(start,goal,r,obs){
if(collision(start,r,obs)||collision(goal,r,obs))return null;
if(segmentOK(start,goal,r,obs))return[start,goal];
const step=.1,nx=101,ny=61,idx=(x,y)=>y*nx+x,pt=i=>[(i%nx)*step,Math.floor(i/nx)*step];
const sx=Math.round(start[0]/step),sy=Math.round(start[1]/step),gx=Math.round(goal[0]/step),gy=Math.round(goal[1]/step),src=idx(sx,sy),dst=idx(gx,gy);
const g=new Float64Array(nx*ny).fill(Infinity),parent=new Int32Array(nx*ny).fill(-1),closed=new Uint8Array(nx*ny),open=[src];g[src]=0;
const dirs=[[1,0],[-1,0],[0,1],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];
while(open.length){let k=0,best=Infinity;for(let j=0;j<open.length;j++){const p=pt(open[j]),f=g[open[j]]+distance(p,goal);if(f<best){best=f;k=j;}}
const u=open.splice(k,1)[0];if(closed[u])continue;closed[u]=1;
if(u===dst){let path=[];for(let at=u;at!==-1;at=parent[at])path.push(pt(at));path.reverse();path[0]=start;path[path.length-1]=goal;
let out=[path[0]],at=0;while(at<path.length-1){let to=path.length-1;while(to>at+1&&!segmentOK(path[at],path[to],r,obs))to--;out.push(path[to]);at=to;}return out;}
const ux=u%nx,uy=Math.floor(u/nx);for(const [dx,dy] of dirs){const x=ux+dx,y=uy+dy;if(x<0||y<0||x>=nx||y>=ny)continue;const v=idx(x,y);if(closed[v])continue;const pv=pt(v),pu=pt(u);if(!segmentOK(pu,pv,r,obs))continue;const ng=g[u]+distance(pu,pv);if(ng+1e-8<g[v]){g[v]=ng;parent[v]=u;open.push(v);}}
}return null;
}
function pathLength(path){return path?path.slice(1).reduce((s,p,i)=>s+distance(p,path[i]),0):Infinity;}
function along(path,f){if(!path?.length)return[1,3];let budget=pathLength(path)*clamp(f,0,1);for(let i=1;i<path.length;i++){let len=distance(path[i-1],path[i]);if(budget<=len){let q=budget/(len||1);return[lerp(path[i-1][0],path[i][0],q),lerp(path[i-1][1],path[i][1],q)];}budget-=len;}return path.at(-1);}
function range(id,label,min,max,step,value,suffix=''){return`<div class="control"><label for="${id}">${label}<output id="${id}-value">${value}${suffix}</output></label><input id="${id}" type="range" min="${min}" max="${max}" step="${step}" value="${value}"></div>`;}
function select(id,label,items,value){return`<div class="control"><label for="${id}">${label}</label><select id="${id}">${items.map(([v,l])=>`<option value="${v}" ${v===value?'selected':''}>${l}</option>`).join('')}</select></div>`;}
function check(id,label,on){return`<label class="checkbox"><input id="${id}" type="checkbox" ${on?'checked':''}><span>${label}</span></label>`;}
function bindRange(id,callback,format=v=>Number(v).toFixed(2)){$('#'+id).addEventListener('input',e=>{$('#'+id+'-value').textContent=format(e.target.value);callback(Number(e.target.value));});}
function resetTamp(){state={radius:.6,allow:true,showInflation:true,blockY:2.4,runStart:0,finished:false};computeTamp();}
function computeTamp(){const s=state;const b={x:5.75,y:s.blockY,w:.7,h:1.2};const start=[1.0,3],cup=[7,3],tray=[8.7,3];let obs=[b],a=astar(start,cup,s.radius,obs),carry=s.radius+.08,z=astar(cup,tray,carry,obs);s.moved=false;
if((!a||!z)&&s.allow){obs=[{...b,y:.35}];a=astar(start,cup,s.radius,obs);z=astar(cup,tray,carry,obs);s.moved=!!(a&&z);}
s.original=b;s.obs=obs;s.a=a;s.z=z;s.ok=!!(a&&z);s.path=s.ok?[...a,...z.slice(1)]:[];s.runStart=0;s.finished=false;
setStatus(s.ok?`${s.moved?'The direct skeleton failed. Relocating B enables':'The direct skeleton works:'} pick cup → place on tray. The computed approach and carrying paths total ${(pathLength(a)+pathLength(z)).toFixed(2)} toy units.`:'No witness for the enabled skeletons at this grid resolution. Try a smaller clearance, moving B, or enabling the relocation primitive.');
}
function renderTamp(t){const s=state;heading('TASK SEARCH + GEOMETRIC SEARCH','2D disk model · computed A* paths');grid();const f=s.runStart?clamp((t-s.runStart)/7000,0,1):(s.finished?1:0);
const o=s.moved&&f>.05?{...s.original,y:lerp(s.original.y,.35,clamp((f-.05)/.25,0,1))}:s.original;obstacle(o,s.showInflation?s.radius:0);
if(s.moved&&f<.28){const a=world([s.original.x+.35,s.original.y]),b=world([s.original.x+.35,1.6]);arrow(a,b,colors.yellow,2,[5,5]);text(b[0],b[1]-16,'relocate B first',14,colors.yellow,'center');}
const tp=world([8.7,3]);box(tp[0]-34,tp[1]-47,68,94,'tray',colors.green,'#193c35',15);
if(s.ok){wp(s.a,colors.cyan,3,s.moved&&f<.3?[7,6]:[]);wp(s.z,colors.green,4);}
const start=s.moved?.3:0;let moveF=clamp((f-start)/(1-start),0,1),rpos=s.ok?along(s.path,moveF):[1,3];
const toCup=s.ok?pathLength(s.a)/pathLength(s.path):1;const cup=moveF>toCup&&s.ok?rpos:[7,3];
disk(cup,.17,colors.cyan,'#2a697b');disk(rpos,s.radius,colors.cyan,'#183b50');disk(rpos,.045,colors.ink,colors.ink);
text(80,516,s.ok?(s.moved?'RELOCATE B → PICK CUP → PLACE':'PICK CUP → PLACE'):'NO FEASIBLE BINDING FOUND',21,s.ok?colors.green:colors.red,'left',600);
text(80,546,s.moved?'Moving B is an assumed primitive; the cup paths are computed.':'A grasp that clears the cup can still fail against the blocker.',14,colors.muted);
if(s.runStart&&f>=1){s.runStart=0;s.finished=true;}
}
function resetStream(mode='focused',seed=7){state={mode,seed,random:rng(seed),stage:0,calls:0,chain:0,certs:[],unrelatedFacts:[],log:[],solved:false,path:null,grasp:null,extra:0};setStatus('The proposed grasp-approach plan is optimistic. No grasp, configuration, or motion has been grounded yet.');}
function streamStep(){const s=state;if(s.solved)return;s.calls++;
if(s.mode==='broad'&&s.extra<2){s.extra++;const r=rng(s.seed+s.calls*101),p=[.5+9*r(),.5+5*r()];s.unrelatedFacts.push({object:'other',pose:p});s.log.push(`Call ${s.calls}: unrelated pose (${p[0].toFixed(1)}, ${p[1].toFixed(1)}) → cached`);}
else if(s.stage===0){const angle=s.random()*Math.PI*2;s.grasp={angle,pose:[7+Math.cos(angle)*.75,3+Math.sin(angle)*.75]};s.certs=['Grasp(cup, g'+s.chain+')'];s.stage=1;s.log.push(`Call ${s.calls}: grasp g${s.chain} = ${(angle*180/Math.PI).toFixed(0)}° → certified`);}
else if(s.stage===1){const reach=distance([1,4],s.grasp.pose);if(reach<6.7){s.certs.push('IK(p, g, q)');s.stage=2;s.log.push(`Call ${s.calls}: IK reach ${reach.toFixed(2)} < 6.70 → q`);}else{s.log.push(`Call ${s.calls}: IK failed (reach ${reach.toFixed(2)})`);s.stage=0;s.chain++;s.extra=0;s.certs=[];}}
else{const path=astar([1,4],s.grasp.pose,.29,[{x:5.85,y:2.5,w:.65,h:1.0}]);if(path){s.certs.push('Motion(q0, q, τ)');s.path=path;s.solved=true;s.log.push(`Call ${s.calls}: motion path found → τ; plan grounded`);}else{s.log.push(`Call ${s.calls}: motion rejected; try another grasp`);s.stage=0;s.chain++;s.extra=0;s.certs=[];}}
$('#stream-calls').textContent=s.calls;$('#stream-facts').textContent=s.certs.length;
$('#stream-code').textContent=s.certs.length?s.certs.join('\n'):'No certified supporting facts yet.';
$('#step-stream').disabled=s.solved;$('#run-stream').disabled=s.solved;
setStatus(s.solved?`A concrete witness was found after ${s.calls} toy calls. Grasp, configuration, and path now support this simplified plan. No robot action was executed.`:s.log.at(-1)+'. The plan remains optimistic.');
}
function renderStream(){const s=state;heading('A CHAIN OF PROMISES','One click = one toy procedure call');const xs=[140,360,580,800],labs=['grasp g','configuration q','trajectory τ','plan π'];
for(let i=0;i<3;i++)arrow([xs[i]+61,132],[xs[i+1]-65,132],i<s.certs.length-1?colors.green:colors.purple,3,i<s.certs.length-1?[]:[5,6]);
for(let i=0;i<4;i++){let done=i<3?i<s.certs.length:s.solved;box(xs[i]-75,101,150,64,labs[i],done?colors.green:colors.purple,done?'#183c36':'#211f3b',17);text(xs[i],186,done?'grounded':'optimistic',13,done?colors.green:colors.muted,'center');}
box(54,232,376,286);text(77,257,'GEOMETRIC WITNESS',12,colors.muted);
const map=p=>[78+p[0]*32,286+p[1]*32];const b=[5.85,2.5];let bo=map(b);box(...bo,.65*32,32,'',colors.red,'#51342f');
circle(...map([7,3]),13,colors.cyan,'#255767');if(s.grasp){const q=map(s.grasp.pose);circle(...q,7,colors.yellow,colors.yellow);line([map([7,3]),q],colors.yellow,2);}
if(s.path)line(s.path.map(map),colors.green,3);circle(...map([1,4]),10,colors.cyan,'#255767');
text(77,497,s.solved?'Concrete trajectory is available.':'Motion cannot run on a placeholder.',14,s.solved?colors.green:colors.muted);
text(469,247,'COMPUTATION LOG',12,colors.muted);s.log.slice(-7).forEach((l,i)=>text(469,285+i*32,l,12,l.includes('failed')||l.includes('rejected')?colors.red:colors.muted));
text(57,548,'Certified facts are added to the planning model; sampling is not execution.',16,colors.muted);
}
function owlTests(p){const s=state,c=[6.4,2.8],a=[4.5,2.0],b=[7.4,4.0];let lang;
if(s.relation==='near')lang=distance(p,c)<=s.radius;
else if(s.relation==='left')lang=p[0]<c[0]-.45&&Math.abs(p[1]-c[1])<1.6;
else{const ab=[b[0]-a[0],b[1]-a[1]],ap=[p[0]-a[0],p[1]-a[1]],u=(ap[0]*ab[0]+ap[1]*ab[1])/(ab[0]**2+ab[1]**2);const proj=[a[0]+clamp(u,0,1)*ab[0],a[1]+clamp(u,0,1)*ab[1]];lang=u>.15&&u<.85&&distance(p,proj)<s.radius*.34;}
const reach=distance(p,[1,4.8])<6.5,free=!collision(p,.23,[{x:s.blockX,y:2.0,w:.9,h:1.4}]);return{lang,reach,free,all:lang&&reach&&free};}
function updateOwl(){const s=state,result=owlTests(s.candidate);$('#owl-code').textContent=s.relation==='near'?`def near(p):\n return norm(p - plate) <= ${s.radius.toFixed(2)}`:s.relation==='left'?'def left(p):\n return (p.x < plate.x - 0.45\n and abs(p.y-plate.y) < 1.6)':'def between(p):\n return (0.15 < projection(p) < 0.85\n and distance_to_segment(p) < r*0.34)';
setStatus(`Candidate (${s.candidate.map(x=>x.toFixed(2)).join(', ')}): language ${result.lang?'PASS':'FAIL'} · reach ${result.reach?'PASS':'FAIL'} · collision ${result.free?'PASS':'FAIL'}. ${result.all?'This placement passes all three toy tests.':'Passing one test does not imply passing the others.'}`);
}
function renderOwl(){const s=state;heading('LANGUAGE ∩ GEOMETRY','Drag the cup, use arrow keys, or move the coordinate sliders');grid();
for(let x=.2;x<9.9;x+=.16)for(let y=.2;y<5.9;y+=.16){const test=owlTests([x,y]);if(test.lang){const p=world([x,y]);ctx.fillStyle=test.all?'#287554':'#514934';ctx.fillRect(p[0]-4,p[1]-4,8,8);}}
if(s.relation==='near'){const p=world([6.4,2.8]);ctx.beginPath();ctx.ellipse(...p,s.radius*82,s.radius*68.3,0,0,Math.PI*2);ctx.strokeStyle=colors.yellow;ctx.lineWidth=2;ctx.stroke();}
if(s.relation==='between'){for(const p of [[4.5,2],[7.4,4]])disk(p,.2,colors.purple,'#514976');wp([[4.5,2],[7.4,4]],colors.purple,1,[4,6]);}
obstacle({x:s.blockX,y:2,w:.9,h:1.4});disk([6.4,2.8],.24,colors.yellow,'#675532');text(...world([6.6,2.25]),'plate',15,colors.yellow);
disk([1,4.8],.18,colors.cyan,'#204b65');const p=world(s.candidate),test=owlTests(s.candidate);circle(...p,15,test.all?colors.green:colors.red,'#294e66',3);circle(p[0]+17,p[1],6,colors.cyan);text(p[0]+23,p[1]-24,'candidate',14,colors.ink);
const endLabel=s.relation==='near'?'place near':s.relation==='left'?'place left':'place between';const list=s.ordering?['move blocker','pick cup','weigh cup','pick cup',endLabel]:['weigh cup',endLabel];
const width=s.ordering?153:240,start=s.ordering?56:192;list.forEach((l,i)=>{box(start+i*(width+16),510,width,39,l,l.includes('weigh')||l.includes('place')?colors.yellow:colors.green,'#182637',13);if(i<list.length-1)arrow([start+i*(width+16)+width,530],[start+(i+1)*(width+16)-2,530],colors.line,1);});
}
function makeParticles(){const r=rng(111);return Array.from({length:52},()=>[1+r()*5.8,1+r()*4]);}
function resetTip(){state={bias:0,shift:0,particles:makeParticles(),history:[],optimized:false,executed:false,selected:null,optStart:0,execStart:0};setStatus('A snapshot is ready. Optimize the candidate targets, then execute.');}
function optimizeTip(){const s=state;let p=makeParticles(),history=[p.map(q=>q.slice())],target=[4+s.bias,3];for(let i=0;i<35;i++){p=p.map(q=>[q[0]+.2*(target[0]-q[0]),q[1]+.2*(target[1]-q[1])]);history.push(p.map(q=>q.slice()));}s.particles=p;s.history=history;s.selected=p.reduce((a,b)=>distance(a,target)<distance(b,target)?a:b);s.optimized=true;s.executed=false;s.optStart=performance.now();$('#execute-tip').disabled=false;
setStatus(`52 toy candidates optimized toward the perceived target x=${target[0].toFixed(2)}. The planner has not observed the post-snapshot object shift.`);}
function executeTip(){const s=state;if(!s.optimized)return;s.executed=true;s.execStart=performance.now();tipResult();}
function tipResult(){const s=state;if(!s.selected)return;const actual=[4+s.shift,3],error=distance(s.selected,actual);$('#tip-error').textContent=error.toFixed(2);$('#tip-outcome').textContent=error<.18?'PASS':'MISS';
setStatus(`Executed target x=${s.selected[0].toFixed(2)}; actual object x=${actual[0].toFixed(2)}. Error ${error.toFixed(2)} versus a 0.18-unit toy grasp tolerance: ${error<.18?'success':'miss'}. Low-level robot feedback is separate from visual scene replanning.`);}
function renderTip(t){const s=state;heading('PERCEIVE → PLAN → EXECUTE','Two views of the same toy object');
const panels=[{x:52,label:'PERCEIVED SNAPSHOT',co:colors.cyan},{x:495,label:'EXECUTION WORLD',co:colors.yellow}];
panels.forEach(p=>{box(p.x,97,390,365);text(p.x+195,125,p.label,14,p.co,'center',600);for(let x=p.x+30;x<p.x+375;x+=35)line([[x,160],[x,430]],'#243348',1);for(let y=160;y<440;y+=35)line([[p.x+20,y],[p.x+370,y]],'#243348',1);});
const map=(p,offset)=>[offset+28+p[0]*45,177+p[1]*39];const target=[4+s.bias,3],actual=[4+s.shift,3];circle(...map(target,52),14,colors.cyan,'#295267');circle(...map(actual,495),14,colors.yellow,'#645234');circle(...map(target,495),18,colors.muted,null,1);
let particles=s.particles;if(s.optStart&&s.history.length){const f=clamp((t-s.optStart)/2400,0,1);particles=s.history[Math.min(35,Math.floor(f*35))];}
particles.forEach(p=>circle(...map(p,52),3,colors.cyan,colors.cyan,1));
if(s.selected){circle(...map(s.selected,52),9,colors.green,null,3);const start=[1,4.9],f=s.executed?clamp((t-s.execStart)/2000,0,1):0,q=[lerp(start[0],s.selected[0],f),lerp(start[1],s.selected[1],f)];line([map(start,495),map(s.selected,495)],colors.green,2,[5,5]);const a=map(q,495);line([[a[0]-11,a[1]-15],[a[0]-11,a[1]+8],[a[0]+11,a[1]+8],[a[0]+11,a[1]-15]],colors.green,4);}
text(76,438,`perception bias: ${s.bias.toFixed(2)}`,14,colors.cyan);text(519,438,`post-snapshot shift: ${s.shift.toFixed(2)}`,14,colors.yellow);
arrow([449,282],[488,282],colors.green,3);text(470,505,'The plan uses the snapshot. A later scene change is not fed back.',18,colors.muted,'center');text(470,539,'Toy optimization minimizes squared distance to the perceived target.',13,colors.muted,'center');
}
function gapTrials(fresh,retry,variation,seed=1234){const r=rng(seed),trials=[];let successes=0,totalTime=0;for(let i=0;i<120;i++){const x=gaussian(r)*variation,noise=gaussian(r)*.07,miss=r()<.17,noise2=gaussian(r)*.07,miss2=r()<.17;let target=fresh?x+noise:0;let good=Math.abs(target-x)<.25&&!miss&&Math.abs(x)<3;let seconds=6+(fresh?3:0);let retried=false;if(!good&&retry){seconds+=5+(fresh?3:0);target=fresh?x+noise2:0;good=Math.abs(target-x)<.25&&!miss2&&Math.abs(x)<3;retried=true;}if(good)successes++;totalTime+=seconds;trials.push({x,good,retried,seconds});}return{trials,successes,rate:successes/120,seconds:totalTime/120,throughput:3600*successes/totalTime,fresh,retry};}
function runGap(message=''){const s=state;s.result=gapTrials(s.fresh,s.retry,s.variation);s.runStart=performance.now();$('#gap-success').textContent=Math.round(s.result.rate*100)+'%';$('#gap-speed').textContent=Math.round(s.result.throughput);$('#gap-cycle').textContent=s.result.seconds.toFixed(1)+' s';setStatus(`${message}${s.result.successes}/120 seeded toy trials succeeded; mean attempt time ${s.result.seconds.toFixed(2)} s, including failed attempts and recovery. ${s.result.throughput.toFixed(1)} successes/hour in this toy model.`);}
function rehearseGap(){const s=state,old=gapTrials(s.fresh,s.retry,s.variation),choices=[];for(const f of [false,true])for(const r of [false,true]){let result=gapTrials(f,r,s.variation);result.score=.7*result.rate+.3*result.throughput/600;choices.push(result);}choices.sort((a,b)=>b.score-a.score);s.fresh=choices[0].fresh;s.retry=choices[0].retry;$('#fresh').checked=s.fresh;$('#retry').checked=s.retry;runGap(`Rehearsal compared four graphs using 0.7 × success + 0.3 × throughput/600. Selected ${s.fresh?'fresh perception':'cached target'}, ${s.retry?'one retry':'no retry'}; previous success ${Math.round(old.rate*100)}%. `);}
function renderGap(t){const s=state;heading('A POLICY GRAPH + A DISTRIBUTION OF INSTANCES','All statistics below are generated by this toy model');
const nodes=[[118,162,s.fresh?'observe':'cached pose'],[345,162,'plan motion'],[576,162,'grasp'],[808,162,'verify']];for(let i=0;i<3;i++)arrow([nodes[i][0]+78,162],[nodes[i+1][0]-79,162],colors.cyan,2);nodes.forEach(([x,y,l],i)=>box(x-79,y-31,158,62,l,s.fresh&&i===0?colors.green:colors.cyan));
if(s.retry){line([[808,193],[808,238],[118,238],[118,193]],colors.yellow,2,[5,5]);arrow([118,222],[118,193],colors.yellow,2);text(461,219,'failed grasp → one retry',13,colors.yellow,'center');}
box(51,287,835,210);text(72,308,'TRIALS ACROSS POSITION VARIATION',12,colors.muted);line([[98,439],[838,439]],colors.line,1);text(97,464,'−3',12,colors.muted);text(466,464,'nominal pose',12,colors.muted,'center');text(837,464,'+3',12,colors.muted,'right');
if(s.result){const n=Math.floor(120*clamp((t-s.runStart)/1600,0,1));s.result.trials.slice(0,n).forEach((r,i)=>{const x=clamp(468+r.x*115,85,855),y=340+(i%5)*19;circle(x,y,5,r.good?colors.green:colors.red,r.good?colors.green:colors.red,1);});}
else text(469,387,'Run the graph to generate measured toy outcomes.',18,colors.muted,'center');
text(470,533,'Rehearsal changes graph structure; motion planning remains a skill inside it.',17,colors.muted,'center');
}
function initLab(){const ep=EPISODES[current],m=metadata[ep.id];$('#lab-title').textContent=m.lab;$('#lab-intro').textContent=m.intro;$('#lab-challenge').textContent=m.challenge;$('#lab-scope').textContent=m.scope;$('#canvas-key').innerHTML=m.key.map(([co,l])=>`<span><i style="--key-color:${colors[co]}"></i>${escapeHTML(l)}</span>`).join('');canvas.setAttribute('aria-label',m.lab+' '+m.intro);const el=$('#controls');
if(ep.id==='integrated-tamp'){
el.innerHTML=range('clearance','Gripper clearance',.18,.9,.01,.6)+range('block-y','Blocker position',.5,4.5,.05,2.4)+check('allow-move','Allow moving the blocker',true)+check('inflate','Show configuration-space expansion',true)+'<button class="primary" id="run-tamp">Animate computed plan</button><button class="secondary" id="reset-lab">Reset experiment</button><p class="control-note">Carrying adds 0.08 units to the effective radius. Red dashed geometry shows clearance around B.</p>';
resetTamp();bindRange('clearance',v=>{state.radius=v;computeTamp();});bindRange('block-y',v=>{state.blockY=v;computeTamp();});$('#allow-move').onchange=e=>{state.allow=e.target.checked;computeTamp();};$('#inflate').onchange=e=>state.showInflation=e.target.checked;$('#run-tamp').onclick=()=>{if(state.ok)state.runStart=performance.now();};
}else if(ep.id==='pddlstream'){
el.innerHTML=select('schedule','Sampling schedule',[['focused','Focused dependency chain'],['broad','Broad illustrative schedule']],'focused')+select('seed','Reproducible seed',[['7','Seed 7'],['19','Seed 19'],['43','Seed 43']],'7')+'<div class="metric-row"><div><b id="stream-calls">0</b><span>procedure calls</span></div><div><b id="stream-facts">0</b><span>supporting facts</span></div></div><button class="primary" id="step-stream">Advance one call</button><button class="secondary" id="run-stream">Run to a witness</button><pre class="code-block" id="stream-code">No certified supporting facts yet.</pre><button class="secondary" id="reset-lab">Reset experiment</button>';
resetStream();const reset=()=>{resetStream($('#schedule').value,+$('#seed').value);$('#stream-calls').textContent='0';$('#stream-facts').textContent='0';$('#stream-code').textContent='No certified supporting facts yet.';$('#step-stream').disabled=false;$('#run-stream').disabled=false;};$('#schedule').onchange=reset;$('#seed').onchange=reset;$('#step-stream').onclick=streamStep;$('#run-stream').onclick=()=>{for(let i=0;i<90&&!state.solved;i++)streamStep();};
}else if(ep.id==='owl-tamp'){
el.innerHTML=select('relation','Language relation',[['near','Near the plate'],['left','Left of the plate'],['between','Between two reference objects']],'near')+range('near-radius','Relation scale',.35,3,.05,1.6)+range('obstacle-x','Blocker x',3.5,7.4,.05,5.2)+range('candidate-x','Candidate x',.3,9.7,.05,5.6)+range('candidate-y','Candidate y',.3,5.7,.05,3.8)+check('ordering','Show inserted setup actions',false)+'<button class="primary" id="find-feasible">Find an admissible placement</button><pre class="code-block" id="owl-code"></pre><button class="secondary" id="reset-lab">Reset experiment</button>';
state={relation:'near',radius:1.6,blockX:5.2,candidate:[5.6,3.8],ordering:false};$('#relation').onchange=e=>{state.relation=e.target.value;updateOwl();};bindRange('near-radius',v=>{state.radius=v;updateOwl();});bindRange('obstacle-x',v=>{state.blockX=v;updateOwl();});bindRange('candidate-x',v=>{state.candidate[0]=v;updateOwl();});bindRange('candidate-y',v=>{state.candidate[1]=v;updateOwl();});$('#ordering').onchange=e=>state.ordering=e.target.checked;$('#find-feasible').onclick=()=>{const candidates=[];for(let x=.3;x<9.8;x+=.08)for(let y=.3;y<5.8;y+=.08)if(owlTests([x,y]).all)candidates.push([x,y]);candidates.sort((a,b)=>distance(a,[1,4.8])-distance(b,[1,4.8]));if(candidates.length){state.candidate=candidates[0];syncCandidate();updateOwl();}else setStatus('No admissible sample on this 0.08-unit grid. This is a finite search result, not a proof that the continuous feasible set is empty.');};updateOwl();
}else if(ep.id==='tiptop'){
el.innerHTML=range('bias','Perception bias',-1,1,.05,0)+range('shift','Shift after snapshot',-1.5,1.5,.05,0)+'<button class="primary" id="optimize-tip">Optimize 52 candidates</button><button class="secondary" id="execute-tip" disabled>Execute stored plan</button><div class="metric-row"><div><b id="tip-error">—</b><span>target error</span></div><div><b id="tip-outcome">—</b><span>grasp outcome</span></div></div><button class="secondary" id="reset-lab">Reset experiment</button><p class="control-note">Changing perception bias creates a new planning input. Changing the post-snapshot shift preserves the stored plan.</p>';
resetTip();bindRange('bias',v=>{state.bias=v;state.optimized=false;state.executed=false;state.selected=null;state.optStart=0;state.particles=makeParticles();$('#execute-tip').disabled=true;$('#tip-error').textContent='—';$('#tip-outcome').textContent='—';setStatus('The perceived scene changed. Optimize again to create a plan from this new snapshot.');});bindRange('shift',v=>{state.shift=v;if(state.executed)tipResult();else setStatus('The actual object moved after the snapshot. The stored planning target has not changed.');});$('#optimize-tip').onclick=optimizeTip;$('#execute-tip').onclick=executeTip;
}else{
el.innerHTML=range('variation','Pose variation (standard deviation)',.1,1.8,.05,.9)+check('fresh','Observe the object before each grasp',false)+check('retry','Add one recovery attempt',false)+'<button class="primary" id="run-gap">Run 120 toy trials</button><button class="secondary" id="rehearse-gap">Rehearse four graph variants</button><div class="metric-row"><div><b id="gap-success">—</b><span>trial success</span></div><div><b id="gap-speed">—</b><span>successes / hour</span></div></div><p class="control-note">Mean attempt time: <strong id="gap-cycle">—</strong>. Includes failures and retries. Seed 1234 is shared across all graph variants.</p><button class="secondary" id="reset-lab">Reset experiment</button>';
state={variation:.9,fresh:false,retry:false,result:null,runStart:0};bindRange('variation',v=>{state.variation=v;state.result=null;clearGap();});$('#fresh').onchange=e=>{state.fresh=e.target.checked;state.result=null;clearGap();};$('#retry').onchange=e=>{state.retry=e.target.checked;state.result=null;clearGap();};$('#run-gap').onclick=()=>runGap();$('#rehearse-gap').onclick=rehearseGap;setStatus('Run the initial graph, or rehearse four variants. Counts and timing will come from the simulated trials.');
}
$('#reset-lab').onclick=initLab;
}
function clearGap(){for(const id of ['gap-success','gap-speed','gap-cycle'])$('#'+id).textContent='—';setStatus('Graph or distribution changed. Run the trials again to measure the new behavior.');}
function syncCandidate(){for(const [i,name] of ['candidate-x','candidate-y'].entries()){$('#'+name).value=state.candidate[i];$('#'+name+'-value').textContent=state.candidate[i].toFixed(2);}}
let dragging=false;
canvas.addEventListener('pointerdown',e=>{if(EPISODES[current].id!=='owl-tamp')return;dragging=true;canvas.setPointerCapture(e.pointerId);moveCandidate(e);});
canvas.addEventListener('pointermove',e=>{if(dragging)moveCandidate(e);});canvas.addEventListener('pointerup',()=>dragging=false);canvas.addEventListener('pointercancel',()=>dragging=false);
function moveCandidate(e){const b=canvas.getBoundingClientRect(),p=[(e.clientX-b.left)*940/b.width,(e.clientY-b.top)*570/b.height];state.candidate=unworld(p);syncCandidate();updateOwl();}
canvas.addEventListener('keydown',e=>{if(EPISODES[current].id!=='owl-tamp'||!['ArrowLeft','ArrowRight','ArrowUp','ArrowDown'].includes(e.key))return;e.preventDefault();const d={ArrowLeft:[-.1,0],ArrowRight:[.1,0],ArrowUp:[0,-.1],ArrowDown:[0,.1]}[e.key];state.candidate=[clamp(state.candidate[0]+d[0],.3,9.7),clamp(state.candidate[1]+d[1],.3,5.7)];syncCandidate();updateOwl();});
function setView(next){view=next;$('#comparison').hidden=true;$('.intro').hidden=false;$('.tabs').hidden=false;for(const t of ['watch','explore','notes']){$('#'+t).hidden=t!==next;$('#tab-'+t).setAttribute('aria-selected',String(t===next));$('#tab-'+t).tabIndex=t===next?0:-1;}if(next!=='watch')film.pause();if(next==='explore'&&!Object.keys(state).length)initLab();}
function chooseEpisode(i){current=i;const ep=EPISODES[i],m=metadata[ep.id];document.documentElement.style.setProperty('--accent',ep.color);document.title=ep.short+' — Motion & Meaning';$('#episode-number').textContent=`PAPER ${ep.number} / 05`;$('#episode-meta').textContent=ep.year;$('#lesson-title').textContent=ep.title;$('#lesson-summary').textContent=ep.summary;$('#paper-link').href=ep.url;$('#download-video').href=`media/${ep.id}.mp4`;$('#try-title').textContent=m.lab;$('#try-summary').textContent=m.intro;film.pause();film.src=`media/${ep.id}.mp4`;film.poster=`previews/${ep.id}.jpg`;film.setAttribute('aria-label',ep.short+' — six-minute narrated visual explainer');
$('#episodes').innerHTML=EPISODES.map((e,j)=>`<button class="episode-button ${i===j?'selected':''}" data-episode="${j}" style="--ep-color:${e.color}" ${i===j?'aria-current="page"':''}><span class="ep-num">${e.number}</span><span><span class="ep-title">${e.short}</span><span class="ep-type">${metadata[e.id].type}</span></span></button>`).join('');$$('[data-episode]').forEach(b=>b.onclick=()=>{location.hash=EPISODES[+b.dataset.episode].id;});
$('#chapter-list').innerHTML=ep.chapters.map((ch,j)=>`<li><button data-chapter="${j}" class="${j===0?'active':''}"><time>${fmt(ch.start)}</time><span>${ch.title}</span></button></li>`).join('');$$('[data-chapter]').forEach(b=>b.onclick=()=>{film.currentTime=ep.chapters[+b.dataset.chapter].start;film.play().catch(()=>{});});$('#current-formula').textContent=ep.chapters[0].equation;
$('#full-paper-title').textContent=ep.paper;$('#authors').textContent=ep.authors;$('#source-links').innerHTML=ep.sources.map(s=>`<a href="${s.url}" target="_blank" rel="noopener">${escapeHTML(s.label)}</a>`).join('');$('#transcript-download').href=`transcripts/${ep.id}.txt`;$('#caption-download').href=`captions/${ep.id}.vtt`;
$('#transcript').innerHTML=ep.chapters.map((ch,j)=>`<article class="transcript-part"><button data-read-chapter="${j}" aria-label="Play chapter ${j+1}">${fmt(ch.start)} ↗</button><div><h3>${ch.title}</h3><p>${escapeHTML(ch.narration)}</p><small>Source / scope: ${escapeHTML(ch.source)}</small></div></article>`).join('');$$('[data-read-chapter]').forEach(b=>b.onclick=()=>{setView('watch');film.currentTime=ep.chapters[+b.dataset.readChapter].start;film.play().catch(()=>{});$('#watch').scrollIntoView({block:'start'});});state={};initLab();setView(view);
}
film.addEventListener('timeupdate',()=>{const ep=EPISODES[current];let index=0;ep.chapters.forEach((c,i)=>{if(film.currentTime>=c.start)index=i;});$$('[data-chapter]').forEach(b=>b.classList.toggle('active',+b.dataset.chapter===index));$('#current-formula').textContent=ep.chapters[index].equation;});
$$('[data-tab]').forEach(b=>{b.onclick=()=>setView(b.dataset.tab);b.addEventListener('keydown',e=>{if(['ArrowLeft','ArrowRight','Home','End'].includes(e.key)){e.preventDefault();const tabs=$$('[data-tab]');let i=tabs.indexOf(b);i=e.key==='Home'?0:e.key==='End'?2:(i+(e.key==='ArrowRight'?1:2))%3;setView(tabs[i].dataset.tab);tabs[i].focus();}});});
$('#start-exploring').onclick=()=>{setView('explore');$('#explore').scrollIntoView({block:'start'});};
function comparison(){film.pause();$('.intro').hidden=true;$('.tabs').hidden=true;for(const id of ['watch','explore','notes'])$('#'+id).hidden=true;$('#comparison').hidden=false;}
$('#compare-link').onclick=()=>comparison();$('#close-comparison').onclick=()=>{location.hash=EPISODES[current].id;setView(view);};
function route(){const hash=location.hash.slice(1);if(hash==='comparison'){comparison();return;}const i=EPISODES.findIndex(e=>e.id===hash);chooseEpisode(i>=0?i:EPISODES.findIndex(e=>e.id===(document.body.dataset.initial||'integrated-tamp')));}
window.addEventListener('hashchange',route);
function frame(t){animTime=t;if(view==='explore'&&!$('#explore').hidden){ctx.fillStyle=colors.bg;ctx.fillRect(0,0,940,570);switch(EPISODES[current].id){case'integrated-tamp':renderTamp(t);break;case'pddlstream':renderStream(t);break;case'owl-tamp':renderOwl(t);break;case'tiptop':renderTip(t);break;case'gap':renderGap(t);break;}}requestAnimationFrame(frame);}
route();requestAnimationFrame(frame);
// Expose pure toy computations for reproducible verification, not remote control.
window.TampLab={astar,collision,segmentOK,gapTrials,owlTests,getState:()=>state,getEpisode:()=>EPISODES[current].id};
</script>
</body>
</html>