# BotSims user guide

Edition: 2026-10-23. Generated from the same content as the in-app guide.

Open `/guide` in the running application for chapter navigation, search, and Print / PDF.

## Contents

### Start here

- [What BotSims does](#start)
- [Choose robot families and ESP32 variants](#robot-presets)
- [Walkthrough: your first AI rover](#first-rover)
- [Walkthrough: an expressive emoji robot](#emoji)
- [Find your way around the workspace](#workspace)
- [Make the playground larger and show only the panels you need](#workspace-panels)

### Build and connect

- [Place on the ground, attach parts, and check available force](#ground-and-force)
- [Replace a component model while retaining its wiring](#change-model)
- [Browse the categorized component library](#library)
- [Place, rotate, and inspect components](#placement)
- [Drag, snap, and attach compatible parts](#snap-mount)
- [Object actions, visibility, and edit locks](#object-actions)
- [Save groups as reusable module presets](#module-presets)
- [Group components and edit a subsystem in isolation](#assembly-groups)
- [Remove parts, remove wires, and undo changes](#remove)
- [Connect named pins on the draggable wiring canvas](#visual-wiring)
- [Wire power, signals, and motor outputs](#wiring)
- [Choose wire thickness and plan connectors](#wire-gauges)
- [Plan gears, belts, chains, and mechanisms](#transmission)
- [Edit engineering values with the right units](#model-values)
- [Add a custom component definition](#custom-parts)

### Program and simulate

- [Write and execute your robot program](#programming)
- [Run, pause, reset, and single-step](#runtime)
- [Connect your own AI provider and test a bounded action](#ai)
- [Use camera input, displays, and audio devices](#camera-audio)
- [Export, import and review recorded AI actions](#ai-traces)
- [Use PID feedback with output limits and anti-windup](#pid-control)

### Test and reference

- [Test scenarios and design diagnostics](#scenarios)
- [Read power, motion, and engineering reports](#telemetry)
- [Save, reopen, import, and export projects](#saving)
- [Understand accuracy and physical limits](#accuracy)
- [Troubleshooting and frequently asked questions](#troubleshooting)
- [Test your own program with assertions and export the result](#code-experiments)

<a id="start"></a>

## What BotSims does

*Understand the workbench, its models, and the quickest route to your first working robot.*

BotSims combines a 3D robot assembly, pin-level wiring, a JavaScript controller, a coupled battery/motor simulation, and bounded AI actions in one project. Start with an expressive emoji companion or a two-wheel AI rover, then revise the design and observe what changes.

The component library is broad enough to plan many mechanisms. Simulation behavior is more focused: the working reference systems are the emoji robot and differential-drive rover. A detailed part shape is useful for layout, but it does not mean that every internal physical effect is simulated.

| Model label | What it means |
| --- | --- |
| Behavioral model | A supported simplified device behavior participates in the existing simulation. Read its description and parameters; behavior is device-specific. |
| Geometry only | The part contributes its supported shape and mass. Some explicitly declared connectors/wires also provide ideal pin continuity. Specialist functions such as gear meshing, pneumatic pressure, or chip instructions are not simulated. |
| Generic component | Dimensions, mass, prices, and parameters are illustrative examples rather than manufacturer-qualified specifications. |

> **A useful first session**
>
> Open the AI explorer rover, run it on flat ground, inspect power and sensor readings, try a slope, then remove and restore a wire. You will see the connection between assembly, electrical connectivity, and control.

<a id="robot-presets"></a>

## Choose robot families and ESP32 variants

*Browse 16 prepared robot assemblies and understand their simulation coverage.*

The highlighted Start with an empty workbench button is at the top of the template chooser. All 16 presets include executable demo code. Select a preset and press Run simulation; Pause stops it and Reset restores the design pose.

1. Export your current project before switching designs. Open New project or the chooser beside the project name.

2. Filter by Emoji companions, Mobile robots, Robot arms, Walking robots, Vacuum cleaners, or Research & tools. Search by robot name, board or application.

3. Expand Simulation coverage before choosing a variant. Drive simulation means the supported differential-drive model; Expression demo exercises displays and the servo-horn preview; Kinematic demo moves supported servo descendants while collision shapes and inertia remain at their reference poses.

4. Choose Use preset. The project includes its components, starter circuit, controller code and useful groups. Undo returns to the previous project during this session.

5. The emoji family offers ESP32 DevKit, compact ESP32-C3 and camera-oriented ESP32-S3 variants, plus the original companion. These run the virtual JavaScript API, not Arduino or ESP-IDF firmware.

> **What arm, walking and vacuum presets do**
>
> Arm demos sweep their shoulder and elbow links; walking demos cycle their legs in place; the camera rig sweeps its rendered view. These use forward kinematics, without solved joint torque, balance, footfall or moving-link collision dynamics. Static arm gravity-moment screening remains at the design pose. Inverse kinematics and grasping are not implemented. Vacuum presets drive with range avoidance; SLAM, suction and dust pickup are not modeled.

To recover example code in an existing preset project, open Code and choose Load preset demo. It replaces the controller source and enables the joint preview for matching servo IDs, preserving assembly transforms and wiring. Undo restores previous code. New presets use separate virtual SERVO_1 through SERVO_8 channels; older or edited circuits may need PWM wires corrected. Deleted, replaced, unpowered or disconnected servos cannot be assumed to move.

<a id="ground-and-force"></a>

## Place on the ground, attach parts, and check available force

*Separate loose parts from physical mounts and compare mass, power and traction demand.*

New library and custom components start on the ground in a clear staging footprint. Rotation and dimensions determine the support envelope; Y is not a fixed arbitrary height. If you lift a loose part in design mode, it falls under gravity when Run starts. Wires carry logical connections and do not physically mount or tether a part.

1. Select a component and open Inspector → Physical attachment. Mount to selects its physical parent; an empty parent means a loose body. Groups only organize editing and do not mount components.

2. Use Place on ground for a loose component, or Detach & place on ground to separate a mounted subtree. Ground entire assembly adjusts the connected assembly while preserving its mounts.

3. Translate a mounted parent to translate its descendants by the same displacement. Positions remain stored in the root frame. Revolute/prismatic dynamics remain unsupported.

4. Anchor assembly to world makes a root support immovable. Arm and camera-rig bases start anchored; release it to test unsupported support behavior.

5. Open Test bench → Mass & drive check for mounted mass, weight, available starting force, required slope/rolling/acceleration force and estimated loaded source voltage/current. The Inspector overview has a compact version.

6. Run the actual controller and read telemetry. Add payload, change friction/slope, disconnect motor power or substitute a source, and compare the response. A launch candidate is a screening result, not a guarantee of sustained movement.

> **Force estimate assumptions**
>
> Weight = m × 9.81. Drive force = sum(torque / wheel radius), capped by friction coefficient × m × g × cos(slope). Required force includes m × g × sin(abs(slope)), rolling coefficient 0.015 and target acceleration 0.3 m/s². The source is screened at full command, zero speed and bounded driver current. Starting torque is not a continuous rating. The supported estimate requires two mounted behavioral drive motors and wheels. Loose component masses do not ride on the robot until mounted.

<a id="change-model"></a>

## Replace a component model while retaining its wiring

*Right-click a part, review related models and preview the exact wiring impact.*

1. Right-click a visible part in the 3D playground and choose Change model. You can also use Change model in its Inspector.

2. Choose a related catalog model. Behavioral options appear before layout-only parts. For example, change the source to a larger-capacity 2S pack or choose another ESP32 virtual controller.

3. Review the number of retained and removed wires. Exact compatible pin names are kept; unique supply and ground aliases can map automatically. Bus and GPIO lines are never guessed.

4. Read the voltage/conflict diagnostics and any geometry-only or ground-fit warning. A higher battery voltage can exceed a regulator or device rating even when the wires are retained.

5. Choose Replace model. The part keeps its instance ID, position, rotation, physical parent and group. Catalog ratings and mass replace the old model-specific overrides. Logical wire IDs are retained for matched pins.

6. Adjust mounting or choose Ground entire assembly if a larger model extends below ground. Inspect Wiring and Test bench before running. Undo restores the original model and all wires.

> **Unmatched pins and unsupported boards**
>
> Unmatched endpoint wires are removed only when you apply the reviewed replacement. The preview lists each removed connection. A generic motherboard or battery layout part does not inherit the supported virtual controller or source behavior just because wires remain. Its model label states that limitation.

<a id="first-rover"></a>

## Walkthrough: your first AI rover

*A complete guided session from template to measurements, fault diagnosis, and export.*

1. Export your current project if you want to keep it. Open New / the template chooser and select Atlas · AI explorer. Selecting a preset replaces the active project.

2. Open Assembly. Select the chassis, battery, controller, motor driver, motors, wheels, camera, and range sensor in the assembly list to see how the project is organized.

3. Open Test bench and review Design diagnostics. Errors block Run; warnings explain missing capabilities or model limitations.

4. Choose Flat ground in the scene selector. Press Run. The supplied JavaScript program reads the range sensor, drives forward when clear, turns near obstacles, and stops when its power or range checks fail.

5. Watch the live readings for speed, current, voltage, state of charge, distance, and sensor values. Open Code to inspect the actual program and its runtime console.

6. Press Pause, then choose Obstacle course and Run. The scene change resets the world. Observe the range value and steering near the blocks.

7. Clear the component selection so the inspector shows Environment. Set a slope or add Extra payload. Run again and compare current and battery sag under the new conditions.

8. Open Wiring. Remove one motor connection using its connection-row trash button. Run again and inspect the motor-disconnected diagnostic and changed behavior. Use Undo to restore the connection.

9. Open AI models and leave the connection on the offline fixture. Request an action while running, inspect its normalized wheel values and duration, and choose Apply bounded action. The action expires within two seconds and pauses the simulation at zero command.

10. Open Test bench, run the reference scenario checks, and choose Report. Also export the project JSON so that you can reopen the design later.

> **What to compare**
>
> Change one design variable at a time. Compare the same scene, initial charge, payload, code, and random seed. The scenario suite uses fixed reference commands; run your own program with Run or Single step to test that program.

<a id="emoji"></a>

## Walkthrough: an expressive emoji robot

*Try a display, a servo pose, text events, and optional AI interaction.*

The Emoji companion template is the smaller reference robot. It includes a display, control electronics, a power system, and a simple servo-driven visual mechanism. Its supplied program alternates expressions and returns a bounded servo goal.

1. Open the template chooser and select an Emoji companions variant. Review the wiring and design diagnostics before changing parts.

2. Press Run and watch the expression alternate. In Code, find robot.display(...) and the returned servo value.

3. Pause and change the expression strings. Press Run to start the revised program. Program globals restart after Pause/Run; a design or code edit also resets the simulation world.

4. Try the sample below. It keeps drive motors stopped, changes the expression with simulation time, and moves the supported servo visual pose.

5. Inspect power and the console. A speaker request is a text event, not generated sound. The microphone is not a live speech input in this release.

6. Use AI models for an optional bounded action. A fresh emoji template may not supply a usable range observation for the offline driving fixture; a stop response is expected. Use the rover for the motion/AI walkthrough.

```javascript
let lastExpression = "";

function step(robot) {
  const happy = Math.floor(robot.time / 2) % 2 === 0;
  const expression = happy ? "😊" : "🤖";
  robot.display(expression);
  if (expression !== lastExpression) {
    robot.log("Expression:", expression);
    robot.speak("Hello from my virtual robot.");
    lastExpression = expression;
  }
  return {
    left: 0,
    right: 0,
    expression,
    servo: Math.sin(robot.time) * 0.5
  };
}
```

> **Servo fidelity**
>
> The supported servo command animates a bounded pose and adds an approximate active load. It is not an articulated physics joint with reaction forces, independent moving inertia, or verified actuator performance.

<a id="workspace"></a>

## Find your way around the workspace

*Know which panel to use for assembly, wiring, code, AI, and verification.*

| Area | Use it for |
| --- | --- |
| Project bar | Choose a template, import a project, export a portable JSON backup, and see save status. |
| Component library | Search parts, browse categories, inspect card details, filter by fidelity, and add components. |
| Assembly list | Find every project instance, select a hidden or overlapping part, and remove an instance. |
| Assembly tab | Orbit the 3D design, change views, translate selected parts, show sensor guides, and inspect geometry. |
| Wiring tab | Connect specific named pins, review logical connections, and remove individual connections. |
| Code tab | Edit the synchronous JavaScript controller and inspect output or runtime errors. |
| AI models tab | Configure a supported connector, request an action, review it, and explicitly apply it. |
| Test bench tab | Read design diagnostics, run reference scenario checks, and export an engineering report. |
| Inspector | Edit the selected part's name, transform, mass, and exposed model values. Clear selection to see project/environment settings. |
| Simulation toolbar | Reset, Single step, Run/Pause, and Emergency stop. |
| Telemetry and console | Read the latest measurements, recent charts, faults, logs, and speaker text events. |

Start with a template whenever you want a known wiring baseline. Use an empty workbench for layout planning or deliberate step-by-step construction. Adding parts to an empty project does not automatically create power paths or a working drivetrain.

<a id="workspace-panels"></a>

## Make the playground larger and show only the panels you need

*Show or hide seven workspace panels on every editor tab, and save or restore a focused layout.*

Open Panels in the top workspace toolbar on Assembly, Wiring, Code, AI models or Test bench. This always-accessible menu controls Components & assembly, Inspector, Live telemetry, Runtime console, Camera preview, Environment controls and the Panel shortcut bar. Your choices apply across editor tabs and are saved in this browser separately from the robot project. Camera preview and Environment controls appear in Assembly when relevant; their settings remain available on every tab.

1. Open Panels and uncheck any panel you do not need. Hiding a sidebar or lower panel automatically gives the current editor more room.

2. Choose Focus editor to hide all seven optional panels at once. The top Panels menu remains available.

3. Choose Restore layout to recover your previous panel choices. Both the focused state and its previous layout survive a browser reload.

4. Use Reset layout to return to the default layout for your screen width. The optional shortcut bar also offers quick Telemetry, Console and Focus controls.

5. Turn a panel back on at any time, including while the simulation is running. Telemetry samples, console records and simulated camera capture continue while their displays are hidden.

6. Use the project bar for New, Open and Export. Use the top-right Run/Pause and stop controls to control execution; panel visibility does not start or stop the robot.

> **Working on a small screen**
>
> The component list and inspector become drawers on smaller screens and initially stay closed. Open them through Panels; phones show one side drawer at a time. The Components shortcut opens the library, and a component's Inspect action also reveals its properties. Close buttons hide either sidebar on every tab.

<a id="library"></a>

## Browse the categorized component library

*Find parts by purpose, compare variants, and understand what adding a component creates.*

The current library contains 218 generic component models in 17 categories. Search by the part name, description, subcategory, or tags; narrow the results with category and model-fidelity filters. Clear a restrictive filter if a search appears empty. Expand a card for its description and specifications, then choose Add to create a project instance.

| Category | Typical parts and purpose |
| --- | --- |
| Structure | Chassis, plates, enclosures, extrusions, brackets, and mounting hardware. |
| Compute | Controllers, chips, and single-board-computer layout models. |
| Power | Batteries, supplies, regulators, fuses, and switches. |
| Motion | Motors, servos, wheels, casters, tracks, and actuators. |
| Transmission | Gears, pulleys, timing belts, chains, sprockets, shafts, and lead screws. |
| Wiring | Wire gauges, cable types, and harness layout parts. |
| Connectors | Headers, terminals, plug/socket families, and cable connections. |
| Sensors | Cameras, distance and inertial sensors, encoders, and other sensing layouts. |
| Interaction | Displays, microphones, speakers, LEDs, and human-facing parts. |
| Electronics | Resistors, capacitors, IC packages, relays, and circuit-layout parts. |
| Fasteners | Bolts, nuts, washers, screws, and spacers. |
| Bearings | Bearings, bushings, rails, and motion-support parts. |
| End effectors | Grippers and tool layouts. |
| Pneumatics | Cylinders, valves, fittings, and air-system layouts. |
| Hydraulics | Hydraulic actuator, pump, and fitting layouts. |
| Thermal | Fans, heatsinks, and cooling layouts. |
| Communications | Antennas and communication-module layouts. |

An added instance gets its own name, transform, and parameter overrides. Adding two instances of the same model creates two separate parts. Library definitions remain available after an instance is deleted.

> **Selection is not compatibility**
>
> A sensor, processor, or motor variant can be available for layout while remaining geometry-only. The behavioral APIs support specific devices from the reference templates; catalog breadth is not a promise that every chip runs code or every actuator can be driven.

<a id="placement"></a>

## Place, rotate, and inspect components

*Use the 3D viewport and root-relative transforms with consistent units.*

Parts can now be dragged directly: hold Shift before dragging to move vertically, and Alt to bypass smart mounting/grid. See Drag, snap, and attach compatible parts for the full workflow. Use the question-mark button beside Fit for quick in-app instructions.

3D navigation: hold the left mouse button and drag to orbit; hold the middle mouse button (wheel) and drag to pan; scroll to zoom. Right-click a component opens its actions. Middle clicks on the canvas suppress browser autoscroll.

1. Choose Add on a component card. The new part is selected and staged on a clear ground footprint. It begins as a loose physical body, separate from the mounted robot.

2. Select the part in the viewport or Assembly list. Drag the part or a translation-axis handle to move it. Choose Grid off or a 1, 5 or 10 mm grid in the placement toolbar; hold Alt to bypass the grid and mounting snap.

3. For precise placement, enter Position X, Y, and Z in the inspector. Position fields are metres: 0.10 m is 100 mm.

4. Set Rotation X, Y, and Z in the inspector. The UI uses degrees; exported rotations use radians.

5. Orbit by dragging the background, zoom with the wheel, and use the perspective/top/front views to check alignment. Mouse/touch behavior follows the viewport orbit controls.

6. Use the sensor-field and wireframe controls to inspect orientation and shape. Select in the Assembly list if a small component is difficult to click.

| Coordinate or quantity | Meaning |
| --- | --- |
| +X | Forward along the robot. |
| +Y | Up. |
| +Z | Right. |
| Position | Relative to the robot root, in metres. |
| Stored rotation | XYZ Euler angles in radians; inspector fields display degrees. |
| Dimensions | The inspector summarizes nominal dimensions in millimetres. |
| Mass | Model values use kilograms; summary cards may display grams. |

All part poses are stored relative to the robot root. Editing a mounted parent moves its descendants with the same rigid transform, including their orientations. This does not solve CAD assembly constraints, linkage closure or joint forces.

> **Appearance and contact**
>
> Detailed rendered geometry helps identify parts. The physics uses simpler collision shapes and a compound rigid body for each physically attached assembly; mesh holes, gear teeth, flexible wires, and internal cavities are not detailed contact models.

<a id="snap-mount"></a>

## Drag, snap, and attach compatible parts

*Use magnetic mount previews, exact alignment, grid settings and direct manipulation.*

1. Drag an unlocked part to move it horizontally. Hold Shift before starting the drag to raise or lower it. Attached children follow. Editing clears the running/paused simulation back to its design pose.

2. Keep Smart attach enabled in the assembly toolbar. Choose a snap reach of 10, 30, 60 or 100 mm, and an optional 1, 5 or 10 mm movement grid. Hold Alt to bypass both.

3. A green outline and Release to attach message identify the nearby compatible target. Release to align and physically attach. Escape cancels a direct drag; one Undo restores the whole completed move.

4. For precise or keyboard placement, right-click the object or use its row options → Align & attach. Search compatible targets, review the resulting pose, then apply. Existing electrical wires are preserved; use Wiring to connect power and signals.

5. Use Fit for the assembly or F for a selected part. Drag empty space to orbit, middle-drag to pan and scroll to zoom. The question-mark button beside Fit explains all controls.

> **Mechanical mount, not automatic wiring**
>
> Snapping creates a fixed parent attachment. It does not create electrical wires, emulate a connector mating standard, or add a dynamic joint. Moving a mounted part adjusts its offset; choose Detach from parent to make it independent. Wires and editing groups do not create a physical mount.

Generic mounting profiles support components onto structural faces, wheel/gear/pulley hubs onto shafts, arm links onto servo outputs and shafts into bearings. Known diameters must agree within 0.1 mm. Unknown diameters, keyed connector gender, bolt patterns, strength, interference clearance, tolerances, gear meshing and belt tension need separate engineering checks. Hidden, isolated-outside and cyclic targets are excluded.

<a id="object-actions"></a>

## Object actions, visibility, and edit locks

*Use contextual actions and keyboard shortcuts without losing track of the physical assembly.*

Right-click a visible object, open its assembly-row options button, or use More selected component actions. Actions are grouped into inspection, positioning, reuse, visibility and removal. Arrow keys, Home/End, Enter and Escape navigate the menu. Unsupported or locked actions are disabled.

- Edit component properties or change a related model. Open its Wiring card and copy its stable instance ID.

- Frame the component, align and attach it, detach it, ground it, or rotate its attached assembly by 90 degrees about Y. Numeric rotation and movement are in Inspector.

- Duplicate one component, duplicate a mounted subtree with internal wires, save the subtree as a reusable module, or isolate its editing group. Copies use fresh IDs and stage on clear ground.

- Hide/show editor meshes, protect a component with Lock edits, or delete an unlocked component. Show all restores hidden meshes. Removal has Undo; attached children are preserved and detached when their parent is removed.

> **Visibility and locks are editing tools**
>
> Hidden parts still contribute mass, physics, electrical diagnostics, wiring and the rendered camera observation. Lock edits prevents direct changes, model replacement and deletion. Mounted descendants still follow an unlocked parent. Locking is separate from the physical Anchor assembly to world setting.

| Shortcut | Action |
| --- | --- |
| F | Frame the selected component |
| Ctrl/Cmd+D | Duplicate selected component |
| Ctrl/Cmd+Z | Undo |
| Ctrl/Cmd+Shift+Z or Ctrl+Y | Redo |
| Delete / Backspace | Remove unlocked selected part |
| Alt while moving | Bypass snap and grid |
| Shift before dragging | Use a vertical movement plane |

Shortcuts leave text fields, dialogs, object menus and the wiring editor in control of their own editing keys.

<a id="module-presets"></a>

## Save groups as reusable module presets

*Build from starter subsystems or create your own library with internal wiring and mounts.*

1. Open Modules beside Parts and Assembly in the left sidebar. Four starter modules include a power/control core, differential-drive base, pan/tilt vision module and arm mechanism. Review their connection notes before insertion.

2. Choose Add module. The app inserts fresh instances with their internal wires and mounts, adds a new group, stages it on clear ground and frames it. Your controller code, AI settings and existing project remain intact.

3. Create or edit a group, then use Group options → Save as module preset. Give it a name and wiring notes. Right-click Save assembly as module captures a part and its mounted descendants instead.

4. The module contains selected parts and wires wholly inside that selection. External wire endpoints are excluded and external mounts are detached. The save dialog states these limits.

5. Rename a saved module or update its notes with Edit saved module. Insert it repeatedly; group instance names and all part/wire IDs stay distinct. Existing servo code needs the new inserted IDs, visible in Inspector or Copy component ID.

6. Export a .robot-module.json file for backup, then use Import module JSON on another browser or device. Remove saved modules with the trash button; Undo module removal restores the last removed entry. Project Undo handles insertion or deletion of instances.

> **Local library and remaining setup**
>
> Saved module presets live in this browser, separately from the robot project. Project exports include inserted instances, not the whole reusable library. Modules do not copy code, AI configuration or connector credentials. Connect external power, ground and signals in Wiring. Never put credentials in module notes or part names.

Import validates JSON without executing it. Limits are 1 MB and 1–100 parts per module, 32 saved modules and a 4 MB library guard, with the usual 200-part/64-group/1,200-wire project limits. If browser storage fails, export the session copy. Geometry-only parts remain geometry-only; insertion does not add chip firmware, gear physics, torque dynamics, grasping or walking balance.

<a id="assembly-groups"></a>

## Group components and edit a subsystem in isolation

*Organize a larger robot into power, compute, drivetrain, perception and interaction subsystems.*

A group is a saved collection of component instances. New rover and emoji templates include named subsystem groups. Existing projects keep their original organization. A component belongs to one group at a time; groups are flat collections rather than nested physical joints.

1. Open the Assembly list on the left. Use the checkboxes next to parts to mark the members of a new group.

2. Choose Group selected, enter a useful name, review the member checkboxes, and choose Save group. You can also choose Group first and select members in its dialog.

3. Double-click a group name, choose its Edit button, or right-click it and choose Edit group in isolation.

4. The 3D viewport and assembly list now show only the group members. The breadcrumb names the active subsystem. The camera frames the visible parts automatically.

5. Select a member and edit its position, rotation, name or parameters in the normal inspector. New components added while a group is open join that group.

6. Choose Manage focused group or Add / remove members to rename it or change membership. Selecting a component from another group moves it into this one.

7. Choose Exit group or All components to return to the complete robot. Right-click a group and choose Ungroup to dissolve the collection while keeping its parts and wires.

Double-clicking a grouped part in the 3D scene opens its group. Right-clicking a part offers Edit component properties, Edit group in isolation when applicable, and Delete component. The group name also has an Options button for users who prefer a visible control.

> **Isolation is an editing view**
>
> Grouping does not change root-relative transforms, physical attachments, wiring, controller code or the simulated world. Running still simulates the complete project, and camera observations include the whole robot and environment. Groups are saved in project JSON, and membership edits participate in Undo/Redo. Removing a component removes its membership and incident wires; ungrouping alone removes neither.

<a id="remove"></a>

## Remove parts, remove wires, and undo changes

*Delete components from any project and recover accidental edits.*

Every project component can be removed, including parts supplied by a template. Use the trash button on its Assembly row, select it and choose Remove component in the inspector, or use the selected-part delete control in the viewport toolbar.

With a component selected and focus outside text inputs, Delete or Backspace removes it. When typing in the code editor, search, or an input field, these keys edit text instead. Close a dialog before using the workspace deletion shortcut.

Removing a part also removes logical wires that reference its pins. Parts attached to the removed parent are kept with their root-relative poses and detached ownership. Other components are not automatically deleted.

1. Use Undo to recover the previous project state, including a removed part and its connections.

2. Use Redo to reapply an undone change. A new edit clears the redo branch.

3. To remove only a logical connection, open Wiring and choose the trash button for that connection.

4. To remove a visible cable-layout instance, delete that instance. It is separate from the logical connection list.

> **History and runtime**
>
> Undo/redo tracks the recent project-edit history (up to 40 snapshots). It is not a permanent version archive and does not restore an old running program, AI request, or simulation state. Design edits and history changes reset the runtime.

<a id="visual-wiring"></a>

## Connect named pins on the draggable wiring canvas

*Drag, magnetically snap, reconnect and diagnose real electrical pin connections.*

1. Open Wiring. Every electrical component in the project has a card with named pins. Card banks put inputs/ground/buses on the left and outputs on the right. Drag card headers to arrange them; use Arrange or Fit to navigate.

2. Drag any pin toward another pin, from either direction. Snap defaults to a 24-screen-pixel magnetic reach, with Off, 12, 24 and 40 px choices. The reach stays consistent as you zoom. Release near a highlighted target to create a logical wire.

3. Blue targets have a suggested role match, amber targets need review, and red targets have a known role conflict. Role colors are advice, not circuit certification. Electrically wrong connections can still be created so diagnostics can explain their consequences. Same-pin and duplicate wires are rejected.

4. Click a wire to select it. Drag its larger endpoint circle to a different pin, or use First pin / Second pin and then click a destination. Edit pins provides exact selectors. A successful reconnect keeps the original wire ID; one Undo restores its old endpoints.

5. A cancelled or invalid drop preserves the old connection. Escape, Cancel, leaving the window or changing editors cancels an unfinished gesture. Click two pins, or focus pins and use Enter/Space, to connect without dragging. Connected pins can accept additional branches.

Adding a component with electrical pins automatically creates its wiring card, including generic layout-only electrical parts. Missing supply/ground paths and unwired cards are visible. Expand the live check bar for diagnostics; it refreshes after every connection, disconnection and model swap. Red connections/diagnostics flag modeled conflicts; a clean check is limited to the supported rules, not a datasheet or SPICE certification.

Open Wiring and choose Canvas. Each electrical component is a draggable card with its real named pins. The diagram is an editor for the same logical wires used by validation and simulation. Moving a card changes only its saved diagram position; it does not move the physical part in 3D.

1. Drag a component card by its header to arrange the circuit. Choose Arrange for an automatic layout of the visible cards.

2. Drag from the small colored pin circle on one card to a pin on another. Release on the target circle to create the connection. A click on one handle followed by another is also supported.

3. Use the mouse wheel or trackpad and canvas controls to pan and zoom. Choose Fit for an overview; zoom in to read pin labels. The minimap helps navigate a larger circuit.

4. Click a wire to highlight it and show its exact component/pin endpoints. Choose Delete wire to remove it. Undo restores it. You can also drag a highlighted wire endpoint to reconnect it.

5. Use the Power, Ground, Signals and Motor legend buttons to show or hide connection families. Filters change the view, not the project wiring.

6. Switch to List for a textual connection reference and individual remove buttons. Expand Connect using pin selectors for a keyboard-friendly alternative to dragging.

7. When a group is open, Show external connections displays labeled cards outside the group only where a wire crosses its boundary. Turn it off to see only internal group members and wires.

8. After electrical edits, open Test bench to review diagnostics before Run. Shorts, incompatible voltages and missing paths still matter even when the diagram looks tidy.

| Wire color | Meaning |
| --- | --- |
| Red | Power supply connection |
| Slate | Ground / return connection |
| Blue | Signal or bus connection |
| Amber | Motor connection |

> **Diagram lines and physical wires**
>
> Logical diagram wires provide ideal connectivity. They are separate from tangible AWG cable components in the assembly. Card positions and line curvature do not represent routed harness length, wire gauge, connector mating, bus timing, or cable resistance. Use the Wire DC estimate and the documented model limits for those planning values.

<a id="wiring"></a>

## Wire power, signals, and motor outputs

*Make real logical connections and understand why a device can be visible but unavailable.*

The Wiring tab connects named pins. Select one endpoint in From and another in To, then choose Connect. A connection joins those two electrical nodes; sharing a position, touching meshes, or adding a cable-shaped component does not make a connection.

| Device path | What must be connected |
| --- | --- |
| Battery and regulator | A supported battery supply and return feed the regulator input. Regulator ground must return to battery ground. |
| Controller | Its supply and ground need a complete supported path. |
| Motor driver | Its motor supply and ground need power. Its PWM input must connect to the powered controller, with a shared ground. |
| Drive motor | Both leads must connect to one driver channel. Swapping the leads reverses the modeled polarity. |
| I²C range / IMU / display | Supply, shared ground, matching SDA, and matching SCL paths are needed. |
| Encoder | Power/ground and the supported controller input paths are required. |
| Camera / microphone / speaker | Supply, shared ground, and the supported DATA connection are needed. DATA is a virtual interface, not a USB packet simulation. |

Start by inspecting the reference rover's pin mappings. Pin labels and direction matter. For I²C, connect SDA to SDA and SCL to SCL; both signals are needed. Do not connect independent power outputs together or short a battery positive pin to ground.

Use Test bench after changes. Validation reports missing paths, some voltage/logic mismatches, output conflicts, short circuits, and I²C address collisions. An error blocks Run. A warning may allow a run while leaving that device inactive.

> **Wires and connectors**
>
> The drawn logical nets are ideal connectivity. Some built-in cable/connector models expose explicitly declared ideal pass-through continuity; inspect their pins and connect both ends. Their resistance, contact heating, and harness voltage drops are not fully coupled into the battery/motor solver. A geometry-only connector does not gain continuity just from its shape.

<a id="wire-gauges"></a>

## Choose wire thickness and plan connectors

*Use AWG variants and a clear resistance example without treating it as a wiring rating.*

Wire and cable variants help plan the harness layout and bill of materials. Lower AWG numbers represent thicker nominal conductors. Inspect the actual component's diameter, length, and resistance-related parameters rather than inferring a rating from its rendered thickness.

Choose from nominal copper-wire entries at AWG 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, and 30. In the inspector, Wire gauge (AWG), Length (m), and Insulated diameter (m) define that instance. Changing gauge updates the illustrative jacket diameter; gauge and length update nominal mass unless you supply an explicit mass override. The Wire DC estimate shows conductor diameter, copper area, and resistance for the selected settings; a Copper temperature override, when present, affects that estimate. Cable-layout variants without a copper gauge do not have this conductor estimate.

```text
Conductor resistance: R = ρ × L / A
DC voltage drop:      ΔV = I × R
Resistive heat:        P = I² × R

Example only, using nominal 24 AWG copper:
R ≈ 0.0842 Ω per metre per conductor near 20 °C
1 m outgoing + 1 m return → about 0.1684 Ω
At 1 A: ΔV ≈ 0.1684 V and P ≈ 0.1684 W total
```

This example is a nominal resistance calculation, not an ampacity recommendation. Actual stranded construction, conductor material, temperature, insulation, installation, connector contacts, and allowed voltage drop change an engineering selection. These wire losses are planning estimates; changing a visual wire's gauge does not currently make the full simulation rail sag by that amount.

1. Choose a wire/cable variant and place it to communicate the intended routing.

2. Choose the intended connector family, pitch, pin count, and orientation from its model details.

3. Add logical pin connections in Wiring; inspect any explicit pass-through pin mapping.

4. Include both outgoing and return paths when doing a manual voltage-drop estimate.

5. Review the exported bill of materials and verify the chosen physical hardware's datasheets before fabrication.

> **Length and rendering boundary**
>
> Assembled wire instances support up to 100 m. Thumbnails marked CUT DETAIL show a short section at the configured thickness so the conductor remains visible; the assembly viewport uses the full configured length. The standalone copper calculation can handle a wider numeric range, but that does not make arbitrarily long physical scenes supported. Rendered wires are layout geometry, not flexible routed harnesses.

<a id="transmission"></a>

## Plan gears, belts, chains, and mechanisms

*Arrange transmission parts and distinguish layout formulas from active drivetrain physics.*

Transmission parts include different gear and pulley forms, belts, chains, sprockets, shafts, racks, and screw mechanisms. Use their detailed shapes, dimensions, and parameter descriptions to plan packaging. Place and rotate them with the inspector, including supporting bearings and mounts.

| Relationship | Meaning and boundary |
| --- | --- |
| Gear ratio = Ndriven / Ndriver | An ideal tooth-count ratio for a simple external gear pair. Rotation directions are opposite. |
| ωout = ωin / ratio | Ideal output speed for a reduction ratio greater than one. |
| τout ≈ τin × ratio × efficiency | A first-order torque estimate; real loading and losses require a suitable model. |
| Pitch diameter ≈ module × tooth count | Use consistent units for module and diameter. |
| Belt speed ≈ π × pitch diameter × rotations/second | An ideal no-slip relationship, using pitch diameter rather than the outside mesh diameter. |

> **Current mechanism boundary**
>
> Adding or touching two gear models does not create meshing, a kinematic constraint, or a power path. Belts and chains do not tension, flex, transmit torque, or fail in the solver. Pneumatics/hydraulics are layouts. The two supported drive motors use their own behavioral gearRatio parameter; placing a separate gear does not automatically change that parameter.

For an exploratory ratio change in the working rover, edit the supported motor's gearRatio and efficiency. Keep wheelRadius consistent with the chosen wheel dimensions. Treat the resulting calculation as the documented motor/drivetrain approximation, not validation of the decorative transmission assembly.

<a id="model-values"></a>

## Edit engineering values with the right units

*Understand battery, motor, load, sensor, and environment parameters before changing them.*

Select a part to see its model parameters. Overrides belong to that project instance. Use finite numeric values and SI units unless the parameter explicitly indicates an exception. Changing a parameter stops and resets the current simulation so the next run uses one consistent configuration.

| Parameter family | Units and interpretation |
| --- | --- |
| mass | Kilograms. A mass override affects the part and its physical assembly. Loose parts are excluded from the mounted drive mass. |
| Battery capacityAh / cells | Ampere-hours and an integer cell count. The model converts Ah to charge using 3600 seconds/hour. |
| Battery internalResistance / maxCurrent | Ohms and amperes. Higher internal resistance increases load-dependent battery sag. |
| Motor resistance / inductance | Ohms and henries for the supported winding model. |
| Motor kt / ke | SI torque and back-EMF constants. The supported model requires equal numerical values to preserve its energy conversion. |
| gearRatio / efficiency / wheelRadius | Dimensionless reduction ratio, efficiency in (0,1], and metres. |
| idlePower / activePower | Watts. Nominal load approximations apply only through supported powered-device behavior. |
| Sensor rate / noise | Rate in hertz; noise follows that sensor's measured quantity. This is not a universal noise-density parameter. |
| Servo minAngle / maxAngle | Radians in model values; normalized commands map into this range. |
| Environment slope / payload / initial charge | Degrees, kilograms, and percent in the inspector. Stored initialSoc is a fraction from 0 to 1. |

Some catalog parameters describe geometry or a future specialist model. A value appearing in the inspector is not proof that it affects a simulation equation. Read the part's fidelity label and the supported model description.

> **Protection is latched**
>
> Certain battery or regulator protection faults latch power off until Reset. Open-circuit voltage with zero current after a fault can mean protection has opened; it does not mean the loaded system recovered.

<a id="custom-parts"></a>

## Add a custom component definition

*Create a saved geometry/mass part from JSON and avoid common import errors.*

Choose Define custom component beneath the library. The editor starts with a complete example definition. Change the model ID to a unique identifier that does not replace a built-in model, give it a readable name, and set its dimensions, mass, category, and shape.

```json
{
  "id": "my-camera-bracket",
  "name": "My camera bracket",
  "category": "Structure",
  "description": "User-defined mounting block for layout.",
  "size": [
    0.04,
    0.025,
    0.03
  ],
  "mass": 0.018,
  "color": "#64748b",
  "shape": "box",
  "pins": [],
  "params": {},
  "price": 0,
  "fidelity": "geometry-only",
  "source": "User-defined, unvalidated.",
  "version": 1
}
```

Dimensions are [X,Y,Z] metres and mass is kilograms. Supported custom primitive shapes are box, cylinder, wheel, camera, and display. Use a listed category. Pin IDs must be unique and use supported identifier characters; numeric parameters must be finite JSON numbers.

Choose Add component. The definition is embedded in that project instance and survives project export/import. This editor does not import CAD meshes, generate firmware support, or register a custom physical solver. Imported custom definitions are deliberately geometry-only.

> **JSON troubleshooting**
>
> Use double quotes, no trailing commas, and positive dimensions/mass. Do not use NaN, Infinity, JavaScript expressions, or comments. If adding fails, read the message and fix the source definition rather than changing a built-in ID.

<a id="programming"></a>

## Write and execute your robot program

*Use the actual JavaScript API, safe sensor handling, and persistent controller state.*

Open Code and write a synchronous function step(robot). The application invokes it once per controller update. It receives a frozen observation copy and can emit bounded commands. This is real JavaScript execution inside a QuickJS WebAssembly VM in a dedicated Worker; it is a high-level virtual device API.

```javascript
let ticks = 0;

function step(robot) {
  ticks++;
  const range = robot.sensors.range;
  if (robot.brownout || !Number.isFinite(range)) {
    robot.drive(0, 0);
    robot.display("⚠️");
    return;
  }
  const blocked = range < 0.65;
  robot.drive(blocked ? -0.25 : 0.4, blocked ? 0.25 : 0.4);
  robot.display(blocked ? "🤔" : "😊");
  if (ticks % 20 === 0) {
    robot.log("Range m:", range, "Battery V:", robot.battery.voltage);
  }
}
```

| Observation | Meaning |
| --- | --- |
| robot.time | Simulation time in seconds; use this instead of Date or wall-clock timers. |
| robot.sensors.range | Range in metres. Missing observations arrive as null in the program. |
| robot.sensors.imu | Three chassis-frame specific-acceleration values in m/s². At rest, +Y is about +9.81. |
| robot.sensors.encoders | Two quantized output-shaft angles in radians when the supported encoders are wired. |
| robot.battery | voltage (V), current (A), and soc (fraction 0–1). |
| robot.motors | Two supported motor observations: current, omega, torque, and temperature. |
| robot.brownout | Whether the modeled controller has a power fault. |

| Method / return | Contract |
| --- | --- |
| robot.drive(left,right) | Finite normalized values from −1 to +1. Each tick starts at zero drive. |
| robot.display(text) | Expression text, up to 80 characters, applied through the supported wired display. |
| robot.speak(text) | Console speaker-text event, up to 500 characters; no synthesized audio. |
| robot.log(...values) | Up to 20 lines per tick, each capped at 240 characters. |
| return {left,right,expression?,servo?} | Optional command object. Returned left and right are both required and override drive-method values. servo is a normalized value from −1 to +1. |

Variables declared outside step persist between ticks in one controller instance. Use Number.isFinite(...) for sensor values; checking only whether a value is less than a threshold can mishandle null. Outputs outside their range fail instead of silently clamping.

> **Supported language boundary**
>
> Only synchronous JavaScript is supported. No async step, module imports, npm packages, Python, ROS nodes, GPIO-register access, real bus transactions, or original MCU firmware execution. Network, filesystem, DOM, storage, and operating-system APIs are unavailable to robot code.

Independent servo API: robot.servo(partId, normalizedTarget) accepts finite targets from -1 to 1, up to 32 IDs per tick. You may also return {left:0,right:0,servos:{shoulder:0.3,elbow:-0.2}}. robot.servos[partId] reads a frozen preview angle in radians. Targets move at maxSpeed (default 2 rad/s), obey angle limits, and require valid power, ground and PWM paths. Omitted commands hold the current angle; reset restores the bind pose. The legacy scalar servo output remains supported. Link motion is a kinematic demonstration, not measured joint dynamics.

<a id="runtime"></a>

## Run, pause, reset, and single-step

*Understand simulation timing, restart behavior, and execution limits.*

| Control | Effect |
| --- | --- |
| Run | Validates the design, initializes the runtime if needed, and advances simulation. |
| Pause | Terminates the controller, applies a zero command, and pauses physics. A later Run creates a fresh controller; program globals restart. |
| Single step | While paused, runs one controller invocation and six physics substeps: 50 ms of simulation. Repeated steps keep that controller's globals until it is stopped/reset. |
| Reset | Creates a fresh world on the next run, clearing modeled battery/winding/protection states and observations. |
| Emergency stop | Terminates the program and applies zero command while pausing the simulation. |
| Design/code/environment edit | Resets the runtime so the next run uses the revised project. |
| Hide the browser tab | Stops the running controller and pauses simulation rather than letting an old command continue unseen. |

Physics uses a fixed 1/120 s step (about 8.33 ms). The controller is scheduled at 20 Hz and holds its command for six physics substeps. Rendering is separate. A slow device can run slower than real time; the simulation clock is the reference for control code.

Zero motor command is a modeled coast/open-winding request, not a physical active brake. The UI pauses the physics at a stop, so a stationary picture after Pause does not demonstrate a real braking distance.

| Budget | Current default |
| --- | --- |
| Program source | 64 KiB UTF-8. |
| QuickJS guest heap | 16 MiB; this is not a cap on the whole browser process. |
| Guest stack | 256 KiB. |
| Initialization / invocation interrupt | 30 ms for each protected guest evaluation or step. |
| Worker watchdog | About one second per tick; WASM startup is allowed up to 15 seconds. |
| Guest access | No host network/filesystem/DOM APIs, imports, Date, or host console. Use robot.log and robot.time. |

Syntax errors, missing step, infinite loops, heap exhaustion, invalid commands, or an unresponsive Worker stop execution. Inspect the runtime console, fix the program, then Run again. The error may be intentionally generic so that an arbitrary guest error object cannot bypass output limits.

<a id="ai"></a>

## Connect your own AI provider and test a bounded action

*Discover account models, use a tab-only key, inspect sensor/image inputs and apply validated goals.*

Open AI models. The four-step workbench separates provider connection, model selection, the robot objective and action testing. OpenAI, Anthropic Claude, Google Gemini, Groq, OpenRouter, Mistral, DeepSeek and xAI have dedicated cloud connectors. Local Ollama connects directly to localhost. Legacy cloud chat keeps existing allowlisted projects compatible. The offline sensor fixture works without an account or network.

1. Choose a provider. For a cloud connection, enter a key issued by that provider in Your API key. The key stays in this tab memory, is cleared when switching providers, and is not stored in project exports, reports or action traces. Forget key clears it immediately. A ChatGPT subscription is separate from provider API billing.

2. Choose Load account models (or Load installed models for Ollama). Search the returned models and select one, or manually enter an exact model ID available to your account. Discovery reads a bounded first page; a list entry does not prove JSON, vision or inference access. The test action establishes whether this request format works.

3. Select a Robot objective preset or write your own task. Enable Attach rendered camera image only when needed and supported by the selected model. Run or single-step in Assembly to obtain a powered camera frame first; camera power, return, DATA and host paths still matter.

4. Press Run simulation, then Test model action. This requests an action preview without applying it. Review wheel values, duration, expression/text and optional named servo targets. The offline fixture is explicitly labeled and is never presented as a live model.

5. Choose Apply bounded action to control the running simulation. Commands are validated and expire within two seconds on both simulation and wall clocks, then the simulator pauses at zero drive. Resume with Run and review/request another action. Errors, cancellation and edits stop pending control.

6. Inspect history, provider-reported input/output token counts and the cloud action request counter. The default limit is 20 attempted cloud actions per tab session (adjustable 1–200). Failed/cancelled cloud attempts count. Reset session usage is explicit; counters are not a currency spending cap or a provider invoice.

> **What the model sees and controls**
>
> The provider receives the robot objective, simulation time, range, IMU, encoders, battery readings, installed named servo angles and optionally a rendered camera image. It does not receive source code, the full project or browser microphone input. Named servo targets use installed IDs and normalized values from -1 to 1, with at most 32 goals. Their power/PWM and kinematic-preview limitations still apply. Model output is data, never executable code.

Cloud requests pass through this site’s bounded same-origin server proxy to fixed provider destinations. Provider and infrastructure retention policies still apply. Redirects and arbitrary cloud URLs are rejected. Local Ollama is called directly by the browser and must allow the site origin through CORS; browser HTTPS/local-network rules may affect access. Do not disable browser security.

Requests have a 1–30 second UI timeout and bounded request, image and response sizes. Cloud outputs are limited to 1,200 generated tokens; some reasoning models may spend that budget before producing an action. Authentication, permissions, quota, unsupported model capabilities, refusal, truncation and malformed output have distinct failure messages. Nothing automatically retries a paid generation. No model is guaranteed to work merely because its provider is listed.

<a id="camera-audio"></a>

## Use camera input, displays, and audio devices

*Know what the simulated devices expose and how image-input failures are resolved.*

A supported camera can render a view from its configured robot pose. A visible camera mesh alone is insufficient: the device needs power, a return path, a supported DATA connection, and a functioning host/controller path. Brownout disables availability.

1. Place and orient the camera, then inspect its power and signal wiring.

2. Open Assembly and allow the camera preview to update after the simulation is initialized.

3. Confirm that a usable preview exists before enabling Attach rendered camera image in AI models.

4. Select a model that supports the relevant image format/modality, then request an action.

5. If the app reports no powered camera frame, repair the wiring or turn image input off to test text/sensor-only AI.

The rendered image is a simplified synthetic observation. It is not a calibrated optical model with every lens distortion, exposure effect, lighting artifact, or sensor noise process. A provider receives the frame only when image attachment is enabled.

The display renders supported program expressions when correctly powered and connected. Microphone and speaker components provide wiring/layout and nominal load planning; live microphone capture, speech recognition, generated speech playback, and acoustic propagation are not implemented. robot.speak and AI say currently appear as text events.

<a id="scenarios"></a>

## Test scenarios and design diagnostics

*Use reference checks correctly and test your own program in the live simulator.*

| Scene / fault | What to observe |
| --- | --- |
| Flat ground | Baseline motion, current, voltage, and sensor output. |
| Obstacle course | Range changes, camera view, collision response, and controller steering. |
| Slope climbing | Gravity load, traction, current demand, and battery sag. |
| Low battery | Reduced state of charge and voltage headroom. |
| Motor stall | Intentionally locked motion, increased winding current, and copper heating. |
| Sensor dropout | Unavailable observations after one simulated second; check your program's safe-stop policy. |
| AI timeout | A locally injected delayed connector failure. No provider is contacted for this fault. |

Use the scene selector for an interactive run of your current program. Set slope, friction, payload, initial charge, and seed in the Environment inspector. A scene or parameter change resets the runtime. When comparing runs, record the full conditions rather than only the scene name.

Test bench → Run scenarios uses fixed reference commands to probe the current model and wiring. It does not execute your custom JavaScript as an acceptance suite. A skipped result can mean the project lacks the required device configuration; inspect its detail. Test your actual program through Run or Single step.

Diagnostics distinguish errors, warnings, and information. Errors block Run. Warnings can identify an unpowered device, unsupported joint, geometry-only part, or inactive signal path. Selecting a diagnostic linked to a part helps you find it. Passing checks confirms the implemented assumptions, not hardware certification.

<a id="telemetry"></a>

## Read power, motion, and engineering reports

*Interpret measurements and export the evidence from a run.*

| Measurement | Interpretation |
| --- | --- |
| Voltage / current / power | Shared battery-terminal behavior and nominal connected loads in the supported model. Power is terminal V × I. |
| State of charge | Modeled fraction of pack charge remaining, shown as a percentage in the interface. |
| Energy Wh | Cumulative chemical energy removed, including modeled battery internal-resistance loss. It is not remaining usable energy. |
| Speed / distance / yaw | Motion of the supported compound mobile-robot body. |
| Motor current / torque / temperature | Behavioral drive-motor values, with lumped copper-heating temperature rather than a full thermal simulation. |
| Range / IMU / encoders | Wiring-gated observations. Unavailable values are distinct from a valid zero reading. |
| Faults | Protection, connectivity, or scenario conditions that can explain stopped or unavailable behavior. |

Charts retain recent samples, not an unlimited recording of every physics substep. After a meaningful run, choose Report in Test bench. The JSON report includes the project configuration, per-instance bill of materials, fidelity/source labels, diagnostics, environment conditions, recent measurements, scenario results, AI timing records, and limitations.

A report exported before running can have no measurement. A report after an edit reflects the new design with cleared runtime observations. Estimated component prices are generic planning values, not live quotations. Export the project JSON alongside the report if you want a clear reopenable design backup.

<a id="saving"></a>

## Save, reopen, import, and export projects

*Keep your work across sessions and move it between browsers safely.*

BotSims automatically saves the active project to this browser's local storage shortly after edits. The save indicator confirms storage succeeded. This is one active local-project slot, not a cloud account workspace or a permanent project history.

1. Use Export in the project bar to download the editable project JSON before switching templates or starting a different design.

2. Use Import to select a previously exported project. The importer validates its structure and supported definitions before replacing the active project.

3. Use Duplicate project to create a new project identity and name for the active configuration. Export it to keep the copy separately.

4. Export an engineering report after testing; reports include measurements, while the project export is the normal portable design file.

5. Keep backups outside browser storage. Clearing site data, using another browser/origin, or private browsing can remove or hide the saved local project.

Saved projects include parts, wiring, overrides, code, scene settings, and non-secret AI configuration. They do not store the API key, an active Worker, the running physics state, or permanent undo history. A reload recreates the design rather than resuming the exact physics instant.

> **Import boundaries**
>
> The importer enforces schema version 1 and bounded project sizes (2 MB, up to 200 parts and 1200 logical connections). These are document limits, not a claim of smooth performance for every scene at those limits. Structurally valid electrical mistakes may be imported so you can repair them; numerical or unsupported-definition errors are rejected.

<a id="accuracy"></a>

## Understand accuracy and physical limits

*Use the equations meaningfully and recognize what remains outside this release.*

The supported model couples Rapier contact for mounted and loose assemblies to two DC motor windings, a battery equivalent circuit, a limited power/connectivity graph, and wiring-gated device observations. Its parameters are generic and have not been calibrated against your physical robot.

```text
Battery:
  Vterminal = Voc(SOC) − I × Rinternal
  dSOC/dt   = −I / (capacityAh × 3600)

Supported DC motor:
  L × di/dt = Vapplied − R × i − Ke × ωrotor
  τrotor    = Kt × i
  τoutput   ≈ gearRatio × efficiency × Kt × mean(i)

Traction and motor heat:
  Drive force ≈ τoutput / wheelRadius
  Pcu         = R × mean(i²)
  Cthermal × dT/dt = Pcu − (T − Tambient) / Rthermal
```

The battery rail uses a bounded operating-point solve; the winding response and lumped thermal response are integrated with documented approximations. Switching is averaged. Available traction is limited by a simplified friction envelope. Payload adds mass at the root rather than a fully placed deformable load.

| Included | Current boundary |
| --- | --- |
| Compound rigid-body motion/contact | No independent rolling-wheel joints, arbitrary articulated robot dynamics, flexible structures, or structural stress analysis. |
| Two supported DC drive motors | No independent free-spinning wheel/rotor dynamics, arbitrary motor controllers, or automatic transmission meshing. |
| Battery sag, loads, and generic protection | One equivalent battery source; no charging, aging, regeneration, or general SPICE circuit analysis. |
| Logical electrical nets | No PCB signal integrity, electromagnetic interference, or fully coupled cable/contact losses. |
| Supported range/IMU/encoder observations | Simplified sensing, sampling, and noise; no universal driver model for every catalog sensor. |
| Bounded JavaScript and AI actions | No original MCU instruction execution, ROS integration, arbitrary packages, or physical robot connection. |
| Detailed component appearance | Rendered meshes and simpler physics colliders have different levels of detail. |
| Microphone/speaker layouts | No sound propagation, live transcription, generated playback, or acoustic localization. |

Use results to explore design tradeoffs and software behavior. Before selecting hardware from a result, compare model values with the intended component data and validate against a measured physical reference. A larger-looking robot is not automatically a validated simulation of that scale.

<a id="troubleshooting"></a>

## Troubleshooting and frequently asked questions

*Resolve common assembly, wiring, runtime, AI, and storage issues.*

### I added a component. Why can I not see it?

New components are staged on the ground beside existing footprints. Select it in Assembly and use its inspector, top/front view or orbit/zoom. A large layout may require zooming out. Open component in Wiring locates its electrical card. Group isolation can hide items outside the current group.

### How do I delete a component?

Use its Assembly-row trash button, the selected-part control in the viewport, Remove component in the inspector, or Delete/Backspace when not editing text. Undo restores the part and its logical wires.

### Why does Run say the design has errors?

Open Test bench and resolve error-level diagnostics. Check invalid parameters, shorts, output conflicts, duplicate I²C addresses, and incompatible supply voltages. Warning-only geometry parts can still run within the stated limits.

### The robot does not move. What should I check first?

Start from the working rover template. Check controller power, shared ground, powered motor driver, both motor leads per channel, PWM paths, wheels, zero commands, and battery faults. Verify that your chosen motor is the supported behavioral drive motor rather than a geometry-only variant.

### The wheels look correct but behavior did not change. Why?

Visual wheel size and motor wheelRadius are separate parameters. Gear meshes, belts, and other transmission-layout parts do not automatically alter the behavioral drivetrain ratio.

### Do I need shared ground even if every part has a positive supply?

Yes. A complete modeled supply and return path is required, and the controller/driver/signal devices need compatible shared grounds. A positive lead alone does not power a device.

### I added a wire or connector model. Why is the sensor still disconnected?

A cable mesh is separate from logical pin connections. In Wiring, connect the required endpoints. For a declared pass-through component, wire both sides using its actual continuity mapping. Geometry-only parts do not create unsupported electrical behavior.

### Why did current drop to zero after a brownout or overload?

The generic protection can latch power off. Telemetry may then show open-circuit voltage and zero current. Fix load, supply, or parameter issues and Reset before running again.

### Why does my display not show the expression?

Check the supported display's power, ground, SDA, SCL, and available controller path. Confirm the program actually emits a display expression and the controller is not browned out.

### Why is a range value missing or null?

The supported sensor may be unpowered, missing a signal path, or affected by Sensor dropout. In guest JavaScript, unavailable host values become null. Use Number.isFinite and command a safe stop when unavailable.

### Why is the camera image missing?

Check camera power, shared ground, DATA wiring, host availability, and brownout. Open Assembly so the renderer can update a preview after initialization. Turn image attachment off to isolate a text/sensor-only AI test.

### My code fails before moving anything. What is allowed?

Define a synchronous function step(robot), use finite motor values in [−1,1], and use only the documented API. No async, imports, timers, fetch, DOM, or packages are available. Large or nonterminating programs exceed the sandbox limits.

### Why did my program counter restart after Pause?

Pause terminates the controller. Run starts a new VM and resets program globals. Repeated Single step calls keep the existing controller state unless an edit or stop resets it.

### The offline AI returned a stop. Is it broken?

The fixture stops for unavailable range data or brownout. This is expected for a design without a valid range observation. Test its motion path with the wired rover template.

### Why is Apply bounded action disabled?

The simulation must be running and a validated action must be available. Changing AI configuration resets the runtime; press Run again, request a fresh action, then apply it.

### Why did the AI action stop after a short time?

Actions are limited to 0–2000 ms. Expiry pauses the simulation at zero command and requires an explicit Run. This avoids retaining an old drive command after a response expires.

### Why can my cloud model not connect?

Check the exact allowed host/path, model access, key, timeout, network, and JSON/image capability. A compatible API name alone does not guarantee support. Inspect the reported status; 429 indicates a rate limit.

### Why can local Ollama not connect?

Run the server on localhost, install the named model, permit the app's browser origin in server CORS, and check browser local-network permissions or HTTPS/HTTP restrictions. Remote LAN Ollama addresses are unsupported. Do not disable browser security.

### Why does the AI-timeout scenario fail without a provider call?

It deliberately injects a local delayed failure to exercise stop/watchdog behavior. This is not evidence about a live provider's latency or availability.

### Why does my custom component or imported JSON fail validation?

Use supported categories/shapes, unique non-built-in definition IDs, unique pin IDs, positive dimensions/mass, and finite numbers. Keep schemaVersion 1 for projects. JSON cannot contain comments, trailing commas, NaN, Infinity, or code expressions.

### Does a passing scenario suite prove my program works?

No. The suite exercises fixed reference commands and the implemented model. Run your own program through normal simulation and Single step, then inspect its logs and measurements under your intended conditions.

### Where did my project go after changing browser or deployment URL?

Storage belongs to that browser and site origin. Import your exported project JSON. Keep regular exports because browser data can be cleared and local storage is not a cloud backup.

### Where is my API key after reopening the project?

It was never saved or exported. Enter it again in the memory-only key field. Keep keys out of code, prompts, custom JSON, and report annotations.

### Can I run any processor, sensor, robot arm, or pneumatic system?

You can plan layouts with many component families, but only the documented device and mobile-robot behaviors are active. Geometry-only warnings identify the boundary. Detailed shapes do not imply complete laws, firmware, or specialist solvers.

<a id="ai-traces"></a>

## Export, import and review recorded AI actions

*Replay validated commands without making another provider request.*

1. After an action test, choose Export action trace in Request history. The JSON contains up to 100 validated actions/failure statuses, provider/model names, timing and available token usage; exports from this session contain at most the 50 retained records. Keys, raw provider responses, full project/source and objectives are excluded.

2. Choose Import action trace and select a BotSims trace (schema version 1, at most 1 MB and 100 records). The importer reconstructs permitted fields and rejects malformed or unbounded actions.

3. Choose Review action to load an action into the preview with a Recorded or Imported label. No provider is contacted. Press Run simulation first, then review again and apply if appropriate. Unknown servo IDs cannot be applied to a different robot.

4. An action trace does not restore the original world, source code or physics state. Keep a project export and an experiment/report alongside it when comparing repeated runs.

> **Repeatable command, changed conditions**
>
> A repeated wheel command can produce a different result if the battery, environment, mass, wiring or starting pose changes. Recorded actions are a debugging tool, not proof that a live model will repeat its reasoning.

<a id="pid-control"></a>

## Use PID feedback with output limits and anti-windup

*API v3 provides bounded deterministic loops inside the isolated JavaScript controller.*

robot.pid(id, target, measurement, options) returns a normalized output. Each ID has independent private state, with at most 32 loops and one update per loop per controller tick. robot.pidReset(id) resets one loop; robot.pidReset() resets all. Existing API v1/v2 programs continue to run.

```javascript
function step(robot) {
  const omega = robot.motors[0]?.omega;
  if (robot.brownout || !Number.isFinite(omega)) {
    robot.pidReset(); robot.drive(0, 0); return;
  }
  // Illustrative gains; target/measurement are shaft rad/s.
  const u = robot.pid("left-speed", 2, omega, {
    kp: 0.08, ki: 0.15, kd: 0, min: -0.6, max: 0.6
  });
  robot.drive(u, u);
}
```

The loop uses consecutive simulation-time samples, with P only on the first sample. An optional explicit dt of 0.0001–1 seconds is for deliberately scheduled control; it integrates the first sample. The derivative acts on measurement to avoid setpoint kick and uses a backward-Euler filter (filterTau defaults to 0.02 s). Conditional integration prevents further windup at output limits and allows unwinding; integralLimit bounds the integral output contribution.

> **Tune the plant, not just the numbers**
>
> PID does not infer units, tune gains or guarantee stability. Match target and measurement units, keep the actual sample interval, test limits and faults, and account for sensor delay, available power and downstream saturation. A loop gap over one second needs a reset. Device wiring and simulation-model boundaries remain in force.

<a id="code-experiments"></a>

## Test your own program with assertions and export the result

*Run the current project source in a fresh isolated controller and physics world.*

1. Open Test bench → Test your program. Choose 1–30 simulated seconds and either the project’s current environment or a supported initial stall/dropout scenario. The current source, component parameters, wiring and seed are captured.

2. Enable assertions for no brownout, minimum battery voltage, maximum current, minimum path travel or maximum absolute forward speed. Set thresholds appropriate to the modeled robot; units appear beside each value.

3. Run the code experiment. The live workspace pauses; a fresh real CodeClient worker executes the captured user program at 20 Hz with physics at 120 Hz. Metrics are sampled at every physics step; exported trace samples are at the controller rate.

4. Inspect achieved values and pass/fail checks. Cancel or Emergency stop terminates the experiment. A 60-second wall-time budget and existing guest/worker watchdogs also bound execution. The experiment never makes live AI calls.

5. Export the experiment JSON. It includes the sanitized captured project, actual source, settings, seed, measurements, trace and assertions. If you edit afterward, the displayed result is marked stale. Keep the export for comparison.

> **Different checks answer different questions**
>
> Scenario checks below this panel still use fixed reference commands to test the model. Code experiments execute your source. Initial sensor dropout uses the existing model’s one-second dropout; arbitrary timed events, user assertion scripts, dynamic environment schedules and hardware certification are outside this runner.

---

This guide describes implemented behavior. See docs/PHYSICS.md, docs/RUNTIME.md, and docs/VALIDATION.md in the source repository for model details and test evidence.

