amp-robotics's picture
Demo 2026-10-20 18:30
fbc5cb3
Raw History Blame Contribute Delete
15.2 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content">
<title>AMP Embodied AI Workbench — Demo</title>
<meta name="description" content="Drive a robot arm with words: AMP Tadpole, a small vision-language-action model, running in your browser.">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="driver.css">
</head>
<body>
<header class="top">
<div class="brand">
<img class="logo" src="amp-logo.svg" alt="Adaptive Machine Patterns">
<span class="name">Embodied AI Workbench</span>
<span class="badge demo">Demo</span>
</div>
<nav class="tabs" role="tablist">
<button role="tab" id="tab-robot" aria-selected="true" data-tab="robot">Robot</button>
<button role="tab" id="tab-inside" aria-selected="false" data-tab="inside">Model Viewer</button>
</nav>
<div class="top-actions">
<button id="tour-btn" class="ghost">Tour</button>
<a class="ghost about-link" id="pro-link" data-place="header" target="_blank" rel="noopener">Get Pro</a>
</div>
</header>
<main>
<section id="view-robot" class="view" role="tabpanel" aria-labelledby="tab-robot">
<div class="robot-grid">
<div class="stage panel">
<div class="cam-bar">
<div class="modes" role="group" aria-label="View">
<button data-mode="Free 3D" class="on">Free 3D</button><button data-mode="Top">Top</button><button data-mode="Side">Side</button><button data-mode="Iso">Iso</button>
</div>
<label>az <input id="az" type="range" min="-180" max="180" value="-110"></label>
<label>el <input id="el" type="range" min="0" max="89" value="28"></label>
</div>
<canvas id="main" width="512" height="512" aria-label="The robot arm and the objects"></canvas>
<div class="stage-hint">Drag to turn the view</div>
</div>
<aside class="hints panel" id="hints" aria-label="Command hints">
<h3>Instructions</h3><div id="h-verbs" class="hint-group"></div>
<h3>Objects</h3><div id="h-objects" class="hint-group"></div>
<h3>Connecting words</h3><div id="h-connectors" class="hint-group"></div>
<p id="h-state" class="hint-state"></p>
</aside>
<aside class="strip panel" id="strip" aria-label="What the model sees">
<h3>What the model sees</h3>
<figure><figcaption>TOP</figcaption><canvas id="cam-top" width="150" height="150"></canvas></figure>
<figure><figcaption>SIDE</figcaption><canvas id="cam-side" width="150" height="150"></canvas></figure>
<figure><figcaption>ISO</figcaption><canvas id="cam-iso" width="150" height="150"></canvas></figure>
</aside>
</div>
<div class="command panel">
<div class="row buttons">
<div class="btn-group" role="group" aria-label="Run">
<button id="play" class="play" disabled>&#9654; Play</button>
<button id="stop">&#9632; Stop</button>
</div>
<div class="voice-wrap">
<div class="btn-group" role="group" aria-label="Voice">
<button id="say" title="Read the command aloud"><svg class="speaker" width="15" height="15" viewBox="0 0 16 16" aria-hidden="true"><path d="M2 6h3l4-3.5v11L5 10H2z" fill="currentColor"/><path d="M11 5.5a3.5 3.5 0 0 1 0 5M12.8 3.5a6.2 6.2 0 0 1 0 9" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>Read</button>
<button id="listen" title="Say a command" aria-expanded="false" aria-controls="listen-pop" hidden><span class="mic" aria-hidden="true"></span><span id="listen-label">Listen</span></button>
</div>
<div id="listen-pop" class="listen-pop panel" role="dialog" aria-label="Listen" hidden>
<div id="listen-setup">
<b id="listen-title">Setting up Listen</b>
<p id="listen-msg"></p>
<div class="progress"><div id="listen-bar"></div></div>
<p class="small" id="listen-step"></p>
</div>
<div id="listen-live" hidden>
<canvas id="listen-meter" aria-hidden="true"></canvas>
<div class="listen-side">
<div id="listen-status" class="listen-status" aria-live="polite">READY hold SPACE to talk</div>
<div class="listen-buttons">
<button id="listen-hold" class="listen-hold">Hold to talk</button>
<button id="listen-clear" class="listen-clear" title="Clear the command">Clear</button>
</div>
</div>
</div>
</div>
</div>
<div class="btn-group" role="group" aria-label="Scene">
<button id="reset" title="Back to the start of this scene; the instruction stays, so you can run it again">&#10226; Reset</button>
<button id="new-scene" title="A random scene AMP Tadpole never saw in training: other shapes, colours and places">New scene</button>
</div>
<div class="backend" id="backend">
<button class="backend-btn" aria-haspopup="listbox" aria-expanded="false"><span id="backend-label">Teacher</span> &#9662;</button>
<ul role="listbox" id="backend-list" hidden></ul>
</div>
</div>
<div class="row">
<label for="text" class="lbl">Instruction</label>
<input id="text" type="text" autocomplete="off" spellcheck="false"
placeholder="e.g. pick up the teal star then return home">
</div>
<div class="progress"><div id="progress-bar"></div></div>
<div id="model-progress" class="small" aria-live="polite"></div>
</div>
<div class="status" id="status">Loading…</div>
<ol class="log" id="log" aria-live="polite"></ol>
</section>
<section id="view-inside" class="view" role="tabpanel" aria-labelledby="tab-inside" hidden>
<div class="inside-intro">
<p><b>AMP Tadpole, inside.</b> Every layer drawn as a storey of a <i>“building”</i>, from the camera
pictures on the ground to the arm's next moves at the top, lit by one real run of the model.
Drag to turn it, click a block to read what it is.</p>
<div class="v-pickers">
<div class="glow-pick" id="v-model-wrap">
<span class="lbl" id="v-model-lbl">Model</span>
<button class="glow-btn" id="v-model" aria-haspopup="listbox" aria-expanded="false" aria-labelledby="v-model-lbl v-model">
<span>AMP Tadpole</span> &#9662;</button>
<ul role="listbox" id="v-model-list" aria-labelledby="v-model-lbl" hidden></ul>
</div>
<label class="v-scene-label">Scene <select id="v-scene"></select></label>
<span class="small dim" id="v-phone-note" hidden></span>
</div>
</div>
<div class="inside-grid">
<div class="panel v-stage" id="v-stage">
<div class="cam-bar">
<div class="modes" id="v-modes" role="group" aria-label="Show">
<button data-mode="structure" class="on">Blocks</button><button data-mode="glow">Glow</button>
</div>
<div class="glow-pick" id="v-what-wrap">
<span class="lbl" id="v-what-lbl">Glow shows</span>
<button class="glow-btn" id="v-what" aria-haspopup="listbox" aria-expanded="false" aria-labelledby="v-what-lbl v-what">
<span id="v-what-label">Token delta</span> &#9662;</button>
<ul role="listbox" id="v-what-list" aria-labelledby="v-what-lbl" hidden></ul>
</div>
<button id="v-reset" class="ghost small-btn">Reset view</button>
</div>
<div class="v-canvas-wrap">
<canvas id="v-main" width="900" height="720" tabindex="0" aria-label="AMP Tadpole drawn as a building of its layers; drag to turn, click a block"></canvas>
<div class="v-keys" id="v-keys">
<button id="v-keys-toggle" class="link" aria-label="Show or hide the keys">Keys</button>
<dl><dt>Drag</dt><dd>turn</dd><dt>Right-drag</dt><dd>slide</dd><dt>Wheel</dt><dd>zoom</dd>
<dt>WASD</dt><dd>move</dd><dt>Q E</dt><dd>turn</dd><dt>G</dt><dd>glow</dd><dt>V</dt><dd>glow shows</dd>
<dt>Space</dt><dd>play</dd><dt>R</dt><dd>reset</dd><dt>Esc</dt><dd>clear</dd></dl>
</div>
<div class="v-preview" id="v-preview" hidden>
<img id="v-preview-img" alt="" crossorigin="anonymous">
<span class="v-preview-tag">Demo preview</span>
<div class="v-preview-text">
<b id="v-preview-title"></b>
<p id="v-preview-note"></p>
<div class="v-preview-actions">
<button id="v-preview-pro" class="ghost"><span class="badge pro">Pro</span> Run and trace it in Pro</button>
<button id="v-preview-back" class="link">Back to AMP Tadpole</button>
</div>
</div>
</div>
<div class="v-loading" id="v-loading" hidden>
<p>Loading this scene's trace of AMP Tadpole…</p>
<div class="progress"><div id="v-loading-bar"></div></div>
<p class="small" id="v-loading-step"></p>
</div>
</div>
<div class="v-bar">
<button id="v-play" class="play">&#9654; Play</button>
<label class="v-progress-label">Calculation <input id="v-progress" type="range" min="0" max="100" step="0.5" value="100"></label>
<span id="v-percent" class="small">done</span>
<label>Storey spacing <input id="v-spread" type="range" min="1" max="12" step="0.5" value="1"></label>
</div>
<div class="small v-caption" id="v-caption" aria-live="polite"></div>
</div>
<aside class="panel v-side" id="v-side-wrap" aria-label="About the selected block">
<canvas id="v-side" width="380" height="720"></canvas>
<div class="v-side-note" id="v-side-note">
<h3 id="v-side-title"></h3>
<p class="dim" id="v-side-params"></p>
<h4>Colour = kind of layer</h4>
<ul class="v-legend">
<li><i style="background:rgb(150, 160, 178)"></i>what the model is given</li>
<li><i style="background:rgb(64, 196, 122)"></i>convolution: each cell reads its neighbours</li>
<li><i style="background:rgb(240, 178, 62)"></i>lookup table: one learned row per word piece</li>
<li><i style="background:rgb(70, 150, 255)"></i>one linear layer</li>
<li><i style="background:rgb(178, 120, 255)"></i>learned tokens and tags: the same for every input</li>
<li><i style="background:rgb(120, 132, 150)"></i>normalisation</li>
<li><i style="background:rgb(255, 92, 138)"></i>attention: tokens read each other</li>
<li><i style="background:rgb(54, 200, 220)"></i>MLP: works on each token by itself</li>
<li><i style="background:rgb(250, 240, 150)"></i>what the model returns</li>
</ul>
<p class="v-side-pro">In this demo, block-by-block descriptions are available for AMP Tadpole only.
In <span class="badge pro">Pro</span> every block of <span id="v-side-model"></span> can be clicked and described,
with its glow, its attention heads and what each token reads.</p>
</div>
</aside>
</div>
</section>
<section class="about panel" aria-label="About this project">
<div class="about-cols">
<div>
<h2>Want these features in your project?</h2>
<p>We built these tools to understand our own models while we develop them. If you'd like the same
kind of insight in your AI products, from looking inside models to benchmarks and robot learning, get
in touch with <b>Adaptive Machine Patterns</b> to see how we can help.
<a class="about-link" data-place="consulting" data-home target="_blank" rel="noopener">Find out more &#8599;</a></p>
<h2>Want to use this when teaching?</h2>
<p>This toy robot task and the Model Viewer are good for learning: students can watch an AI model drive
a simulated robot arm, look inside it layer by layer, and see what each part does. Students can use
this demo for free. One Pro copy per teacher is all you need to teach advanced classes or record videos for your presentations.
<a class="about-link" data-place="teaching" target="_blank" rel="noopener">Get Pro &#8599;</a></p>
</div>
<div>
<h2>Why a desktop app?</h2>
<p>Because big models don't fit in a browser. AMP Tadpole was built small enough to run right here,
but SmolVLA, Cosmos3-Edge and your own models aren't, and you might also want to keep your
models private.</p>
<p>So we made a desktop app: it runs them on your own machine and GPU, offline. It imports
<b>any PyTorch model</b>, packaged with its weights or straight from LeRobot, and opens up every
block of transformer-based ones, with automatic descriptions, down to the attention heads. <b>AMP Embodied AI Workbench Pro</b> also pays for
this free demo, the open benchmark and AMP Tadpole, so buying a copy keeps them coming. Every purchase
includes the full source code, for Linux, Windows and macOS.
<a class="about-link" data-place="pro-box" target="_blank" rel="noopener">More about Pro &#8599;</a></p>
</div>
</div>
<h3 class="pro-list-h">In Pro</h3>
<ul id="pro-list" class="pro-list"></ul>
</section>
</main>
<footer>
<span>&copy; 2026 Adaptive Machine Patterns Ltd</span>
<a href="https://huggingface.co/Adaptive-Machine-Patterns/amp-tadpole" target="_blank" rel="noopener">AMP Tadpole</a>
<a id="bench-link" href="https://github.com/Adaptive-Machine-Patterns/amp-toy-robotics" target="_blank" rel="noopener">AMP Toy Robotics Benchmark</a>
<button id="credits-btn" class="link">Credits</button>
</footer>
<div id="loading" class="loading" role="status">
<div class="loading-box">
<img class="logo big" src="amp-logo.svg" alt="Adaptive Machine Patterns">
<div id="gate" hidden>
<p>This demo runs on your device. It downloads <b id="gate-start">about 60 MB</b> to start,
and <span id="gate-inside">about 20 MB</span> more for the <i>Model Viewer</i>.
On a metered connection, Wi-Fi is best.</p>
<p class="small" id="gate-phone">Made for a desktop screen: on a phone you get the robot and one scene in the Model Viewer.</p>
<button id="gate-start-btn" class="play">Start the demo</button>
</div>
<div id="loading-run">
<p id="loading-text">Starting Python in your browser…</p>
<div class="progress"><div id="loading-bar"></div></div>
<p class="small" id="loading-size"></p>
</div>
<p class="small">Everything runs on your computer. Nothing you type leaves this page.</p>
</div>
</div>
<dialog id="pro-dialog">
<form method="dialog">
<span class="badge pro">Pro</span>
<h2 id="pro-title"></h2>
<p id="pro-blurb"></p>
<p id="pro-why" class="pro-why"></p>
<p id="pro-part">This is part of <b>AMP Embodied AI Workbench Pro</b>, the desktop app.</p>
<div class="dialog-actions">
<a id="pro-contact" class="button primary" target="_blank" rel="noopener">Find out more &#8599;</a>
<button value="close">Close</button>
</div>
</form>
</dialog>
<dialog id="credits-dialog">
<form method="dialog">
<h2>Credits</h2>
<div id="credits-body"></div>
<div class="dialog-actions"><button value="close">Close</button></div>
</form>
</dialog>
<script type="module" src="app.js"></script>
</body>
</html>