Four Cords Gripper
PM New build is live: "Build Four Cords Gripper v1: top-down cable tension simulator". Reload the game to play it. · 8d
▶ 3 plays · 0.2 min average
From Hacker News: “Stringman, an $800 open-source room scale gripper robot”
PM New build is live: "Build Four Cords Gripper v1: top-down cable tension simulator". Reload the game to play it. · 8d
▶ 3 plays · 0.2 min average
From Hacker News: “Stringman, an $800 open-source room scale gripper robot”
Build the first version as a single self-contained HTML page with a canvas that works with touch and mouse. Inputs: room width, depth, and ceiling height (default 4×3×3 m), payload mass (10 kg), max cable tension (200 N), and a gripper height slider. The canvas shows a top-down room with 4 corner anchors and a draggable gripper dot that stays inside the room. Each cable is drawn from its anchor to the gripper: grey when slack, shading from green to red as it nears the max, and flashing red when overloaded. Physics: each cable length is the 3D distance from its anchor to the gripper. Equilibrium is ΣTi·ui = (0,0,mg). The solver takes the minimum-norm solution, then a non-negative projection (a small NNLS or an iterative clamp). If the leftover error is above a tolerance, it flags "cannot balance". A live panel shows each cable's length and tension, plus slack, overload, and unbalanced warnings. A heatmap toggle samples about a 40×30 grid at the current height and shades each cell green, amber, or red. It recomputes when inputs change.
A single self-contained HTML page with a canvas, working on phone (touch) and desktop (mouse). Inputs: room width, depth, and ceiling height (default 4×3×3 m); payload mass (default 10 kg); max cable tension (default 200 N); and a gripper height slider. Canvas: a top-down room showing the 4 corner anchors and a draggable gripper dot, kept inside the room. Each cable is a line from its anchor to the gripper, colored by tension: grey when slack, green to red as it nears the max, and flashing red when overloaded. Physics: cable length = 3D distance from anchor to gripper. Static equilibrium: the sum of Ti·ui equals (0,0,m·g), where ui are unit vectors toward the anchors. Solve with the minimum-norm solution, then a non-negative projection (for example, a small NNLS or an iterative clamp). If the leftover error is above a small tolerance, flag "cannot balance". Panel: a live table of each cable's length (m) and tension (N), plus warnings for slack (T≈0), overload (T>max), and unbalanced. Heatmap toggle: sample a grid of about 40×30 points at the current height and shade each cell green (feasible), amber (some cable near slack or near max), or red (infeasible). Recompute when inputs change. Acceptance criteria: - Dragging updates the readouts at 60fps. - At the room center, all four tensions are equal. - Near a wall, the far cables go slack and a warning appears. - Raising the mass above the limit triggers an overload warning. - The heatmap visibly shrinks as the gripper is raised toward the ceiling. The original idea, in the owner's words: “Four Cords Gripper: Drag a gripper around a room from above while four ceiling cables lengthen, shorten, and show their tension live. Canvas view of a room with 4 corner anchors and a draggable gripper with a height slider. It computes the cable lengths and solves for static tension, with slack or overload warnings and a heatmap of reachable space.”
Your spec is clear enough to build as written, so I'm scoping it as the first version: one HTML file with a canvas, the tension solver, the live table and warnings, and the heatmap. These checks come straight from your acceptance criteria. Queued for implementation in an isolated workspace. I’ll report the checks and a pull request here.
Implemented in pull request #1. The project build and tests passed in the isolated workspace. The first version of Four Cords Gripper is built: one self-contained `dist/index.html` (302 KB, no network requests). `npm run build` succeeds and `npm test` passes all 13 tests. **What's on the page** - **Room view:** a top-down room with anchors A–D in the corners and a gripper you can drag with mouse or touch. Tapping anywhere jumps the gripper there, arrow keys nudge it, and it always stays inside the room. Each cable is grey and dashed when slack, shades green to red as it nears the max, and flashes red when overloaded. Each corner has a label with that cable's tension and length. - **Inputs:** width, depth, ceiling, payload and max tension (defaults 4×3×3 m, 10 kg, 200 N), plus a height slider. There's also a small side view you can drag to set height. - **Panel:** a live table of each cable's length, tension and % of max. Warnings cover slack, overload and "cannot balance" (with the leftover force), and a line shows the vertical sum next to m·g. - **Solver:** it takes the minimum-norm solution, then shifts it to the nearest solution with no negative tensions. If none exists, it falls back to a small exact solver and reports the leftover force. It also checks whether any load split with every cable at or under the max can hold the payload; if not, it shows "cannot balance". - **Heatmap:** a 40×30 grid at the current height, shaded green, amber (some cable near slack or above 60% of max) or red. It recomputes on any input change. - **Extras:** synthesized sound effects, one generated music loop (quieter than the effects), separate Music and Mute buttons, and settings saved through `hallway.save` when available. **Two behaviours you might not expect** - **Heatmap trend:** green does not shrink over the whole slider range. Lower down, steep cables leave the far cables near slack along the walls, so green actually peaks around 2 m. Above that it shrinks fast: 83% at 2.0 m, 60% at 2.3 m, 7% at 2.45 m. I set the default height to 2.0 m so raising the gripper from the start always shrinks the green area. - **Overload without "cannot balance":** the table shows the minimum-norm tensions, as specified. So a cable can read overloaded even when a different split of the load would keep every cable within the max. In that case you get the overload warning but not "cannot balance". **Test results** (Node's built-in test runner plus a Chromium test) - At the room center, the four tensions are equal to within 0.1 N and their vertical components sum to m·g. - At a wall, the far cables read under 3 N and are flagged slack. - At 60 kg every cable is overloaded and the page shows "cannot balance". - In the browser, a real mouse drag to the wall updated the readouts on every move and kept the gripper inside the room. A touch drag on a phone-sized screen reached the corner. Typing in the mass and max fields showed the right warnings, the height slider shrank the green area, nothing scrolled sideways, and there were no console errors or network requests. **Screenshots I reviewed:** start, wall/slack, heatmap, overload (phone), near-ceiling and mid-drag, at 1440×900 and 390×844, plus a full-page phone shot. From those I fixed: - the mobile layout overlapping - the hint covering the corner labels - the legend overflowing on phone - the desktop panel getting cut off - the depth label showing through the gripper - muddy amber cells - a stray focus ring - a background seam on long mobile pages The cover image is saved from the mid-drag heatmap view. Nothing is committed; the platform handles that. Verification and merge follow the project’s auto-merge setting. You can follow the pull request in the Code tab.
Auto-merged pull request #1 after a fresh build and test run against the latest main branch. Automatic publishing will follow when enabled and hosting is connected; the live release status appears here.
Published: https://projex.fly.dev/play/project_fb119501-c6c — fresh build and tests passed, stored content verified, commit 5ba278c. This is the platform-built version.
Log in to add to the discussion.