ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Interactive two-joint robot arm with guided lessons: FK, IK, configuration space, the Jacobian and feedback control. Companion to Unit 2 of the Hugging Face Robotics Course.
翻译准备中
正在加载完整 README。 以下为已保存的摘录。
Learn robot kinematics and control by touching them.
An interactive two-joint arm with 30 guided lessons, the last six on the real five-joint arm in 3D,
plus the Workbench : a playable 3D bench where you drive the SO‑101, record your driving, replay it blind and teach a small policy,
built as a companion to
Unit 2 · Classical Robotics of the Hugging Face Robotics Course ,
plus a second page for Unit 1 : what LeRobotDataset actually fetches when you ask for a temporal window.查看完整 README ↗Unit 2 of the Hugging Face Robotics Course makes one argument: even a two-joint arm needs real math to control, and that math breaks on contact, clutter and cameras, which is why the field is learning from data. The unit gives the equations (forward kinematics, inverse kinematics, the Jacobian, feedback) but no way to push on them. Its source even carries TODO placeholders for the diagrams.
This playground is those diagrams, made interactive. Every equation in the unit is a slider, a drag or a button, and each tab walks you through it with predict-then-check questions: you commit to a number before the answer appears.
It uses the course's own notation (q = [θ₁, θ₂], p(q), J(q)⁺, k_p Δp) and its running example: the SO‑100 arm with four joints locked, so it moves in a plane. Tab 5 then gives the locked joints back, one at a time, on the real arm in 3D, so you can watch the planar math stop being enough.
Two views, always in sync. Task space: where the hand is. Configuration space: every pixel is one pose (θ₁, θ₂). Hover it to preview that pose as a ghost arm; click to go there. Turn on a floor or shelf and watch them carve regions out of the map. Every tab has a "What do the symbols mean?" key: tap a symbol and the matching thing on screen pulses, so J(q) stops being notation and becomes "those two arrows at the hand."
| Tab | You learn | You can | Lesson |
|---|---|---|---|
| 1 · Forward kinematics | FK is two arrows added head to tail; θ₂ is relative; the workspace is a ring | Drive θ₁, θ₂; change link lengths; hover the pose map | 6 steps |
| 2 · Inverse kinematics | IK has 0, 1 or 2 answers; obstacles delete them; iterative solvers find the one whose basin you start in | Drag a target; jump to either solution; run an iterative (damped least-squares) solver and see its path; paint the basins of attraction | 6 steps |
| 3 · Jacobian & diff-IK | J's columns are each joint's "nudge"; det J = l₁l₂ sin θ₂; singularities make joint speeds explode | Wiggle a joint to see its column; drag a desired hand velocity; run diff-IK into a singularity with a plain vs damped inverse; teleop the hand with arrow keys | 5 steps |
| 4 · Feedback control | Open loop trusts the model; feedback fixes model error; k_p·Δt > 1 overshoots, > 2 diverges; latency and saturation change the picture; tracking isn't planning; and, beyond the course, why PD needs mass: P on an arm with inertia is an undamped spring, k_d is the damper | Step, circle, sweep or drag targets; vary gain, control rate, latency, model error, joint speed limit; watch the error trace against the ideal e^(−k_p t) response, step-response metrics and the discrete error sequence; switch on inertia and tune k_d to critical damping | 7 steps |
| 5 · The real arm (3D) | The plane of tabs 1–4 was one slice of a five-joint arm; one spare joint turns "A or B" into a continuous family of poses; the pose map can no longer be drawn; J becomes 3 × 5 (which is why the course writes J⁺), then 6 × 5 with rank 5 | Orbit the SO‑101, drawn from its URDF; unlock joints one at a time; sample the reachable volume; hold the fingertip still while the arm moves (self-motion); drag a target in 3D and watch the same damped pseudo-inverse follow it | 6 steps |
Tabs 1–4 teach the course's simplification: two joints, one flat plane. Tab 5 shows what was simplified away. The arm is the SO‑101 (the current revision of the course's SO‑100), built from the robot's own description file, and the tab starts with three of its five joints locked, which is exactly the arm of tabs 1–4. A translucent sheet marks the plane you have been working in. Then you unlock joints:
Where the numbers come from. Joint order, axes, offsets and limits are read from so101_new_calib.urdf in TheRobotStudio/SO‑ARM100, pinned at commit 385e8d7 (Apache‑2.0). An unmodified copy is in docs/vendor/, and the tests check the page's table against it number for number, then check forward kinematics against a separate implementation (reference_fk.py).
What's exact and what's a model is listed on the tab itself. In short: the kinematics, link lengths, Jacobian and the 5 < 6 count are exact to the URDF; the rods are a schematic of the joint centres (not the printed parts), the reachable points are a random sample, the solver is numerical (within 0.1 mm when it converges, and it says so when it doesn't), and a URDF is an idealised arm.
No 3D library. The view is about a dozen rods, a grid and a few thousand points, so it is drawn on an ordinary 2D canvas with a hand-written camera, perspective divide and depth sort. That keeps the tab at one 55 KB file (18 KB gzipped), with no WebGL requirement, and it still opens from a downloaded copy of the folder (ES-module 3D libraries can't be loaded from file://). Two flat views, side and top, are always shown next to it and are the precise place to drag a target.
Tabs 1–5 let you inspect an arm. The Workbench lets you operate one, and operating is what the rest of the course is about: LeRobot's method is teleoperate, record, train, deploy. Seven missions, each with a predict-then-check question, each one a course idea you feel before you read it:
| # | Mission | The idea | Course |
|---|---|---|---|
| 1 | Put the cube in the bin | Cartesian teleoperation: tab 3's damped pseudo-inverse running under your thumbs | Unit 2 |
| 2 | Now do it joint by joint | Why a leader arm exists: a straight line in the room is a curve in joint space | Unit 2 |
| 3 | Reach the far corner | Joint limits and the workspace, felt as the hand refusing to go | Unit 2 |
| 4 | Record a demonstration | Your episode as rows: 30 a second, six numbers of state and six of action, under the real LeRobotDataset names | Unit 1 |
| 5 | Replay it blind | The cube is moved 4 cm and your recording replays: the jaws close on air, because a replay never looks | Unit 2 |
| 6 | Drive through lag | Every command lands 200 ms late; tab 4's latency lesson, in your hands | Unit 2 |
| 7 | Teach it | A small network trains in the page on your own demonstrations and is scored on eight spots it never saw. One demo is hit or miss; four from different spots make it reliable | Unit 4 |
What's exact: the arm's joints, lengths and limits are the SO‑101 URDF's, the same tested K3 code as tab 5; the control is damped least squares on four joints for four numbers (x, y, z and the jaws' pitch), checked in the tests to 1 mm; a recording replays its own joint path bit for bit; the lag queue delays a command by exactly six frames at 30 updates a second.
What's a toy, and says so on the page: the arm is simplified shapes in the real colours; grasping is one rule (the closed jaws take the cube if its centre is within 21 mm of the fingertip) with no contact physics; falling is plain gravity onto flat surfaces; the policy is a small network that is handed the cube's position, where the course's ACT has to find it in camera images.
How it is built: workbench.html + workbench.js, with three.js r149 vendored as a plain script (docs/vendor/three.min.js, MIT) so the page still opens from a downloaded copy; no build step. The core of workbench.js (control, world, grasp, recorder, replay, lag, the policy's training) is pure and runs in npm test; the view is a three.js layer over it. Training runs in a Web Worker, with a same-thread fallback for file://. Without WebGL the page points you to tab 5, which draws the same arm on a plain canvas.
Unit 1's only code (page 1.4) is about delta_timestamps: asking LeRobotDataset for a window of past observations and future actions around one frame. The course explains it with a static diagram. datasets.html makes it live, against the real facts of lerobot/svla_so101_pickplace (50 episodes, 11,939 frames, 30 fps, six motors, two 480×640 cameras) and the fetch rule in lerobot 0.6.1's dataset_reader.py:
{feature}_is_pad. It never crosses into the neighbouring episode.ValueError LeRobot raises.dataset[t] with its tensor shape, the _is_pad masks, and the batched shapes from a DataLoader, including the 0.6.1 quirk that a single-offset video window is squeezed to [3, 480, 640] while action keeps [1, 6].next(iter(...)), since StreamingLeRobotDataset is an IterableDataset and the course's streaming_dataset[100] raises).~action_is_pad).The course stops at Unit 2; Hugging Face's Robot Learning tutorial, which it distils, goes on to imitation learning and generalist policies. Demos to Deployment (source and docs) is a sibling lab for that material, on its own toy world: a line-painting robot learns Main Street from a master painter. It covers behaviour cloning and compounding error (one pothole, 3.80 m of paint off the line), DAgger (one round of the master riding along fixes it), and then the real-time side of action chunking: synchronous inference's idle share d/(d + s), ACT's temporal ensembling averaging two good plans into the wet cement, SmolVLA's asynchronous queue and its threshold g, naive switching's seams, and Real-Time Chunking's frozen prefix and soft mask (at 500 ms of think time, 1 side flip in 40 streets against 26). Same conventions as this repo: real algorithms, labelled toys, node demos-to-deployment/tests/check.js prints every number.
Demos to Deployment treats the big policy's think time as a given. Inside a VLA (source and docs) opens it up, with SmolVLA as the worked example and π0 as the comparison: how three camera frames and an instruction become 241 tokens, what the backbone's floors cost and what skipping half of them buys, why the prefix is cached while the action expert runs once per flow-matching step, and what that adds up to against the control period on three toy computers. Every weight and FLOP is counted from the released configs; node inside-a-vla/tests/check.js prints every number.
Two-link arm visualisers are a well-worn genre. I checked the closest ones against their own pages on 2026‑09‑25. This playground is narrower in scope (two joints in a plane, plus one tab on the five-joint arm in 3D) and deeper on what Unit 2 teaches.
| Arm Playground | ArmLab | ShareTechnote | CompuTools | |
|---|---|---|---|---|
| FK and both closed-form IK solutions | ✓ | ✓ | ✓ | ✓ |
| Joint limits | elbow only | ✓ | — (ignored by design) | ✓ |
| Obstacles, drawn in configuration space | ✓ | — | — | — |
| Closest feasible pose when IK fails (optimisation form) | ✓ | — | — | — |
| Iterative IK solver + basins of attraction | ✓ | — | — | — |
| Jacobian columns + manipulability ellipse | ✓ | — | ✓ | ✓ (index / SVD) |
| Singularity blow-up, plain vs damped inverse | ✓ | — | described | detection |
| Feedback control with gain, rate, latency, model error, saturation | ✓ | — | — | — |
| Guided lessons with predict-then-check questions | ✓ (30, plus 7 Workbench missions) | quick-start list | written explainer | — |
Use CompuTools for 6‑DOF arms and DH parameters, and ArmLab for trajectory planning. Use this one to understand why Unit 2 ends by arguing for learning. For a comparison of iterative IK solvers (CCD, FABRIK, Jacobian transpose), see Saeed Ghorbani's interactive post. If I've mischaracterised a tool, open an issue.
Any setup can be shared as a link (use the 🔗 button). Parameters go after #tab, joined by &:
| Param | Meaning | Example |
|---|---|---|
fk ik jac fb r3 | Tab (r3 = the real arm in 3D) | #ik |
step | Lesson step (1-based) | step=4 |
t1, t2 | Joint angles (degrees) | t1=30&t2=60 |
tx, ty | IK target | tx=1.2&ty=1.35 |
l1, l2, lim | Link lengths, elbow limit | l2=0.5 |
floor, shelf, basins | Toggles | floor=1&shelf=1 |
inv, lam | Jacobian tab: plain / damped inverse, damping λ | inv=damped&lam=0.1 |
path, kp, rate, lat, merr, qmax, ff | Feedback settings | path=step&kp=75 |
inertia, kd | Give the arm mass; damping gain | inertia=1&kd=11 |
solve | Start the iterative IK solver (2 = run instantly) | solve=1 |
iter | Run exactly N solver iterations and freeze (animation frames) | iter=12 |
theme | light / dark | theme=dark |
q, free | Tab 5: the five joint angles in degrees (pan, lift, elbow, wrist flex, wrist roll); which joints are unlocked, one digit each | q=0,20,-74,0,0&free=01100 |
cam | Tab 5: camera yaw, tilt (degrees) and distance (mm) |
Try it: both IK solutions blocked by a shelf · iterative IK racing to a basin · latency turns a safe gain unstable · the real arm with its pan unlocked · five joints following a target in 3D
npm test
Thirty-eight checks, no dependencies (Node 18+). They slice the math out of the pages and verify it against identities and the lessons' own worked examples: FK↔IK round-trips, the Jacobian against finite differences, det J = l₁l₂ sin θ₂, the closed-form solutions for the lesson targets, that the damped pseudo-inverse stays finite where the plain inverse fails, and, for the Unit 1 page, that the delta_timestamps fetch rule reproduces LeRobot's frame indices, clamping and is_pad masks.
Fourteen of them cover tab 5: the joint table equals the vendored URDF number for number; forward kinematics matches known poses from an independent implementation (python3 docs/vendor/reference_fk.py) and a quarter-turn worked by hand; the links are 116 mm and 135 mm; the side view reduces to tab 1's own formula; the 3 × 5 and 6 × 5 Jacobians match finite differences, with rank 5; self-motion holds the fingertip within 0.1 mm; the Solve button's several-starts search reaches at least 99% of targets that are reachable by construction (a single search misses over 5% of them, which is why it retries); and the numbers the lessons and labels quote are recomputed from the kinematics.
Eight cover the Workbench: the hand follows commands to within 1 mm with the jaws pitched down at every cube spot; pushing past the edge of reach stops the hand and tilts the jaws without breaking a joint limit; the grasp rule at its 21 mm boundary; a recording replays bit for bit, reproduces its outcome, and misses once the cube is moved 4 cm; the world advances in 1/30 s steps at 30, 60, 120 or 144 Hz; lag delays a command by exactly N steps; the toy policy trained on four demonstrations, clean or clumsy, delivers at most of eight unseen spots and beats a policy trained on one; and every number a mission quotes comes from the code that produces it.
index.html (Unit 2), arm3d.js (tab 5, fetched the first time that tab is opened), datasets.html (Unit 1) and workbench.html + workbench.js (the Workbench) are vanilla HTML, CSS and JavaScript. KaTeX (from jsDelivr) renders the Unit 2 equation cards and falls back to plain text offline; three.js r149 is vendored for the Workbench only.An unofficial companion to the Hugging Face Robotics Course, which is based on the Robot Learning Tutorial. Not affiliated with Hugging Face. The equations and the SO‑100 planar example follow the course's Unit 2. Tab 5's arm geometry comes from the SO‑101 URDF in TheRobotStudio/SO‑ARM100 (Apache‑2.0); see docs/vendor/NOTICE.md.
Built by Bakul Badwal while working through the course. MIT licensed.
| PD control on an arm with inertia (spring + damper) |
| ✓ |
| — |
| — |
| — |
| More than two joints / 3‑D / DH tables | 5 joints in 3‑D from the URDF (tab 5 and the Workbench); no DH tables | — | — | ✓ |
| Teleoperate, record an episode, replay it, train a policy on it | ✓ (Workbench) | — | — | — |
| Trajectories, waypoints, export | — | ✓ | — | path trace + CSV export |
cam=-52,22,860 |
plane, cloud, axes, cols, triad | Tab 5 toggles: the plane of tabs 1–4, reachable points, joint axes, Jacobian columns, fingertip orientation | cloud=1&cols=1 |
tg, mode | Tab 5: target x,y,z in mm; mode=follow tracks it, mode=self holds the fingertip while the wrist turns | tg=250,120,170&mode=follow |
m (on workbench.html) | Start the Workbench at mission 1–7 | workbench.html#m=5 |
localStorage