Hopp til innhold

PRD · VERSION 1.0 · 2026-09-02 · REMOTE V3.1 "CLEAN ARC"

Remote Studio: the arc remote's 3D design workbench

One web app is the source of truth for the remote. It loads the v3.1 design, shows it photoreal, explodes it so every part is selectable, lets you swap parts between real alternatives, and verifies from the meshes that what you chose actually fits. It exports the STL set and BOM for whatever you picked.

The key requirement: verification is computed from geometry, never asserted. Interference, clearance, stack height, centre of gravity and wall thickness are measured on the meshes and shown in the scene, so decisions are made against geometry, not against rendered images.

Goals and non-goals

  • See the actual geometry from any angle, in the actual materials, without waiting for offline renders.
  • Explode and collapse with every part individually identified and inspectable.
  • Change parts and immediately see the physical consequence.
  • Trust: a fit and clearance report computed from the meshes.
  • Decide and record: configurations can be saved, compared and exported (STLs, BOM, spec deltas).

Out of scope for v1: it is not a general CAD editor (users pick defined variants and adjust a few named parameters), no electrical simulation or firmware, no real-time multi-user collaboration, and no mobile-first layout.

Users and jobs

Inputs

The handover folder holds the parametric OpenSCAD master remote_v31.scad (body from two parabolas, width and rounding functions, tail cap; modules for the shells, pad disc, carrier, grip buttons and a test mule; variant switches for pad and power), the assembled and exploded STLs, the spec and sourcing documents, and the Blender material reference.

Alternates for the swap system

  • Pad click: mech (dome under carrier) or haptic (1 mm aluminium carrier, three FSR 400 pucks, LRA Ø10 × 3, DRV2605L driver).
  • Power: lipo (503450) or aaaa (two AAAA lengthwise, Pololu U1V11F3 boost, BAT60A diode, removable cover). aaa is known not to fit and must be shown as failing.
  • Grip input: side keys, a one-piece grip cup from X 104, or none.
  • Finish: white matte, black matte or black gloss (visual only).
  • Body parameters as sliders: arc_h 3–7, zt_C 6–12, zt_n 6–9, zt_t 10–14, pad_x 34–48, rbot_max 3–8.

Core requirements

  1. Viewer (P0)

    Load the assembled glTF; orbit, pan, zoom; presets hero, top, side, underside, nose, tail. Real-time PBR matching the Blender reference: matte white (roughness 0.32, coat 0.12), soft-touch black (roughness 0.62), gloss black (roughness 0.10, coat 0.8). Studio lighting, soft shadow catcher, body resting on its two feet at Z = 0. 60 fps on a 2022 laptop at 500 k triangles or fewer.

  2. Explode (P0)

    One slider from 0 to 1 moves every part along its own vector (shells vertical, pad stack upward in order, side keys outward, internals stay). Vectors are data. Every part is a separate mesh with an id: hover highlights, click selects, selection persists collapsed with an x-ray outline. Isolate mode shows the selected part plus ghost shells.

  3. Inspect (P0)

    Part panel with name, role, part number, dimensions, mass (density × volume for printed parts), source link and price in NOK, mount, wiring pins, print settings. Live measurement: two points give a distance, a click gives a bounding box, and a section plane cuts the assembly to show wall thickness and clearances.

  4. Swap and adjust (P0)

    Switch the four alternate groups and drag the six body sliders. Every change regenerates geometry with a debounce and progress state, never blocking the viewer, and re-runs verification. Every configuration is URL-encoded so it can be shared and bookmarked.

  5. Verify (P0, the point of the app)

    Computed from meshes after every change, shown as a green, amber or red strip and as overlays in the scene. Interference: pairwise mesh intersection; any hit is red with the volume highlighted and both parts named. Clearance: 0.5 mm for boards, 1.0 mm above the cell, 0.3 mm for moving parts. Stack: disc proud 0.3 ± 0.1, travel 0.5 ± 0.1, carrier clears the module by 0.2, spacer height reported. Stability: centre of gravity between the feet with 10 mm margin. Wall thickness 1.4 mm minimum except the 0.6 mm LED spot, by ray casting, with a heat map. Seam gaps 0.25 ± 0.1 measured from meshes. Printability flags per printed part. The report exports as JSON and PDF and is attached to every saved configuration.

  6. Decide and export (P1)

    Save named configurations, compare two side by side with a synced camera and a diff table, pin notes to parts or points, and export STL per printed part, the assembled glTF, the BOM as CSV, the verification report and a generated spec Markdown.

Architecture

React and TypeScript with react-three-fiber and drei, three-mesh-bvh for intersection and distance queries, Zustand for state, URL state via a small router. Geometry generation runs OpenSCAD compiled to WebAssembly in a Web Worker, fed the master SCAD plus the overrides, emitting STL converted to glTF and cached by parameter hash in IndexedDB, with precomputed glTFs for the default configuration so the app is usable within two seconds.

The parts catalogue is one JSON file and one Barkpark document type: id, name, group, variant tags, dimensions, mass, source, price, mount, pins, explode vector and print settings. It is the BOM source of truth; the SCAD placeholders are generated from it by a script, never duplicated by hand, and a CI check fails when a dimension diverges.

Config { id, name, createdAt, params: {arc_h, zt_n, zt_t, zt_C, pad_x, rbot_max}, variants: {pad, power, grip, finish}, notes: Note[], verification: Report }
Part   { id, name, group, variantTags[], dims_mm, mass_g, source: {vendor, url, partNo, priceNOK}, mount, pins[], explodeVector, print? }
Report { status: 'ok'|'warn'|'fail', checks: Check[] }   Check { id, status, value, threshold, parts[], focusPoint }

Definition of done

  • Default config loads in two seconds or less and regenerates from parameters in fifteen seconds or less in the worker.
  • Explode shows all parts of the default config separately; each is selectable with dimensions matching the catalogue to 0.1 mm.
  • Power set to aaa gives a red interference with the shell; aaaa passes with 0.5 mm clearance; lipo passes.
  • Pad set to haptic swaps the carrier and adds the FSRs, LRA and driver, and the stack check still passes with the recomputed spacer.
  • arc_h at 7 moves the centre-of-gravity check and updates the feet within one regeneration.
  • A section plane at X 40 shows the pad stack with measured travel and gap numbers.
  • Export yields manifold STLs in mm for six printed parts and a BOM whose total matches the sourcing document within 10 %.
  • A saved config reopens from its URL on another machine with identical geometry and report.
  • The three finishes visually match the reference renders.
  • No verification check is faked, hard-coded, or derived from parameters instead of meshes.

Milestones and risks

Risks: openscad-wasm may take 20–60 s per regeneration, so preview quality uses fewer slices and the 24 default-parameter variants are precomputed. Mesh booleans in the browser are avoided; verification uses BVH queries and the section fill is a stencil trick. Part dimensions live in one place only. Every verification run logs the mesh hashes it used.

Day one: run the SCAD once with the defaults, load the reference glTF, and get the viewer on screen before touching generation. The first demo that matters: explode, click the LiPo, read "53 × 34 × 5, 0.8 mm to the FFC adapter", switch to AAA, watch it turn red.