Physics
CRUMB simulates the mechanical world alongside the electronics. A motor turns a real wheel against real friction, a robot drives across the bench, and a sensor sees the obstacle in front of it. This page is about using physics with the parts in your circuit. To make parts that move, see Forces and coupling.
When physics runs
Section titled “When physics runs”Physics runs with the circuit. There’s no separate play mode.
- Run Simulation starts both. The first run after opening or resetting records where every part stands, and parts with a body start to fall.
- Pause Simulation freezes the bench where it is. Resume Simulation carries on.
- Reset State switches everything off and puts the bench back as saved. Parts return to their places, every chip powers up fresh and batteries are full again. EEPROM, flash and saved settings are kept.
Switching to another circuit’s tab pauses the one that was running.
Gravity and the floor
Section titled “Gravity and the floor”The bench has normal Earth gravity and a solid floor at height zero, 100 m across. The floor is there while Ground Plane is ticked in the 3D view’s Settings → Scene menu. Untick it and anything with a body falls forever.
Each body can have its own Gravity Scale: 0 makes it weightless, and a negative value makes it float up.
Giving a part a body
Section titled “Giving a part a body”Only parts with a body fall, collide and get pushed around. Many moving parts, like a motor’s wheel, come with their body already set up. For anything else, select the part and press Add Rigidbody on the BUILD tab.
The body appears as a Rigidbody row under the part in the hierarchy. Select it to set:
| Section | Settings |
|---|---|
| Body | Type: Dynamic moves freely, Kinematic moves only when something moves it, Static never moves. Mass in kg, and Gravity Scale. |
| Contact | Friction (0 to 2) and Bounce (0 to 1). |
| Soft Surface | Makes contacts give a little, like rubber feet or a tyre. |
| Damping | Slows linear and angular motion, like air resistance. |
| Collider | The shape used for collisions, from a quick Box or Convex Hull to Primitive (exact shapes), which also lets you round a wheel’s edge and shape its tread. Group decides what collides: parts in the same group collide, parts in different groups pass through each other. Everything collides with the floor. |
| Center of Mass and Inertia | Override the values worked out from the part’s shape. |
| Sensing | Surface Fields: what a sensor’s beam reads off this body, one per line, such as IrReflectance: 0.8. See Marking surfaces. |
A library part’s own body settings are view-only. To change them, edit the part in the component editor. Collider and soft-surface changes take effect on the next run after a Reset.
A part without a body that is joined to one with a body rides along with it. Parts plugged into a breadboard ride with the breadboard.
Joining parts together
Section titled “Joining parts together”Welding with anchors
Section titled “Welding with anchors”Some parts have anchors: blue wireframe cubes at the points where they bolt to something, such as a motor’s mounting face. In placement mode, hover over a part to see its anchors.
To weld two parts, drag an anchor onto an anchor of the other part. The part snaps into place, turning to match; hold Ctrl to keep its current rotation. When you let go, CRUMB asks whether to lock the two together. Welded parts move as one rigid body, while each keeps its own shape and friction.
An anchor’s Mate Mask decides which anchors it can weld to. It’s a number made of bits (1, 2, 4, 8 and so on, added together), set on the anchor in the component editor, and two anchors weld only if their masks share a bit. Every anchor starts at 1, so any two anchors fit until a part’s maker narrows it down: give a motor’s mount and its bracket a bit of their own, such as 2, and the motor only welds where it’s meant to.
The most fixed member decides for the whole group: weld an arm to a Static base and the arm can’t move either.
To undo a weld, right-click the welded anchor and choose Unlink Anchor, or select the parts and press Break Links on the BUILD tab.
Joints
Section titled “Joints”A joint links one body to another, or to the world. Select a part with a body and press Add Joint (or right-click its Rigidbody row). A new joint starts as Fixed. Set its Type in the inspector:
| Type | Use it for |
|---|---|
| Fixed | Bolting two bodies together, or one body to the world. |
| Hinge | Anything that turns on an axle: a wheel, a door, a lever. It can have limits, friction and a spring. |
| Slider | Anything that slides along a line, with limits, friction and a spring. |
| Ball-Socket | A joint free to turn any way. |
| Custom (6DOF) | Choosing exactly which directions are free. |
| Gear | Making two spinning bodies turn together: external gears, an internal ring, or a belt or chain. Set the teeth on each side, and the backlash. |
| Rack + Pinion | Turning a spin into a straight-line movement. |
To link the joint to another body, press World — Pick Target… in the joint’s panel, then click the other part. A joint with no target pins its body to the world at the joint’s anchor point, so a Fixed joint with no target bolts a part to the bench. Pause or reset the simulation before you pick a target.
Joints don’t break. Break Force can be set, but it isn’t used yet.
Pushing things during a run
Section titled “Pushing things during a run”While the simulation runs, select a part and drag it with the Translate or Rotate handles. Its body follows your hand, pushes other things out of the way, and keeps its speed when you let go. That’s how to shake an accelerometer, or throw something across the bench. A part only stays wired up during the drag if everything it’s connected to moves with it.
The Interactivity tool in the 3D view toolbar is different: it’s for pressing a part’s buttons and turning its knobs.
Motors and robots
Section titled “Motors and robots”Motor parts do the mechanical work themselves. The TT gearbox motor, for example, turns its wheel on a hinge, models its gearbox and back-EMF, stalls when it’s held, and pushes back on whatever it’s mounted to. Weld its anchors to a chassis, add a second motor and a caster, and you have a robot.
Example: a motor’s back-EMF, in code
Section titled “Example: a motor’s back-EMF, in code”There’s no special motor code in CRUMB. A motor is an ordinary part whose two halves pass numbers to each other every physics step, and that loop is its back-EMF.
back-EMF = Ke × speedtorque = Kt × current- The circuit logic is the winding: a resistance, with a voltage in series that grows with the shaft’s speed. That voltage is the back-EMF.
- The component logic turns the winding’s current into torque on the shaft.
- Every physics step, it hands the shaft’s speed back to the winding, which makes the next back-EMF from it.
The part has two connections, Red and Black, a mesh named Shaft with a body and a hinge on its axle, and two circuit logic properties: R in ohms and Ke in volts per rad/s.
private double _g, _src, _amps;
public override bool ConnectionsAreConnected(int l, int r) => true;
public override void StampInitial(){ int a = ConnectionNodes[Connections.Red]; int b = ConnectionNodes[Connections.Black]; Simulation.StampRightSideDynamic(a); Simulation.StampRightSideDynamic(b);}
public override void PreStep(){ // Last tick's current, for the shaft. Published here, before // the solve, so the shaft never sees a trial value. UserData[1] = _amps;
// The shaft's speed makes a voltage: the back-EMF. double backEmf = Properties.Ke * UserData[0];
// The winding: R, with the back-EMF behind it. _g = 1.0 / Math.Max(Properties.R, 1e-6); _src = -_g * backEmf;}
public override void Step(){ int a = ConnectionNodes[Connections.Red]; int b = ConnectionNodes[Connections.Black]; Simulation.StampConductanceDynamic(a, b, _g); Simulation.StampCurrentSourceDynamic(a, b, _src);}
public override void CalculateCurrent(){ double v = ConnectionVoltages[Connections.Red] - ConnectionVoltages[Connections.Black]; _amps = _g * v + _src; // (v - back-EMF) / R SetCurrent(Connections.Red, _amps);}public override void PhysicsUpdate(double delta){ if (Circuit == null) return;
// The winding's current turns the shaft. In SI units the // torque constant Kt equals the back-EMF constant Ke. double amps = Circuit.UserData[1]; double kt = CircuitProperties.Ke; Rendering.Shaft.Rigidbody.ApplyTorque(kt * amps);
// The shaft's speed goes back to the winding, in rad/s. Circuit.UserData[0] = Rendering.Shaft.Rigidbody.SpinRate;}Connect it to a battery and run. The shaft speeds up until its back-EMF nearly matches the battery, and the current falls away. If the shaft can’t turn, there’s no back-EMF, so the current climbs to the battery voltage divided by R, just like a real stalled motor. Put the multimeter in series on DCA to watch it happen.
The full version, with inductance, brush drop, a gearbox and a winding that can burn out, is a TT gear motor: see Example: geared DC motor. For the rules behind the loop, see Forces and coupling.
Add Prop on the BUILD tab places a plain solid box in the middle of the view. Use props for walls, ramps, a maze for a robot or a target for a distance sensor. In the inspector you can make it a Box or a Cylinder, set its size in millimetres and its colour. A prop starts Static: set its body type and mass on its Rigidbody row. Reset the simulation before you change a prop’s shape or size.
Props also make a track for a line-following robot. Give a flat prop IrReflectance: 0.8 in its Surface Fields for white, and lay thin props on it with IrReflectance: 0.05 for the line.
A prop has no anchors. To fix a part to one, add a Fixed joint to the part and pick the prop as its target.
Environment zones
Section titled “Environment zones”An environment zone sets the conditions inside a box, so you can test sensors without building a weather system. Add Env Zone on the BUILD tab places a 100 mm cube in the view. Move it with the handles, and drag its faces to resize it.
A zone sets Temperature C, Humidity % and Air Pressure kPa. Add anything else in Extra Fields, one per line, such as Lux: 800 for light. Each zone shows its values in the 3D view.
A sensor reads the zone it’s in. Where zones overlap, the smallest one wins. Outside every zone, a sensor uses its own property instead, so the value you set in the inspector is the bench value. Temperature and humidity sensors and light dependent resistors read zones. The ultrasonic distance sensor reads the zone’s temperature, for the speed of sound, but measures distance from what’s really in its beam: put a prop in front of it to test it.
Light sources add to what the zones set. The LEDs, for example, give off light that a sensor nearby can see, brighter as their current rises.
To see lamp cones, sensor beams and other helpers, open the 3D view’s Grid Axes menu and tick Physics → Show Gizmos.
Physics settings
Section titled “Physics settings”The SIMULATION tab sets how often physics steps. The default, 1000 Hz, is also the lowest it goes, because below that a light part turned by a motor can shake. Go higher for very light or very fast parts. Under it, the status line shows the rate reached, and says when the circuit or the physics is holding the other back. Settings has finer controls for how hard each step works. These settings are saved with the circuit.
Good to know
Section titled “Good to know”- Light isn’t blocked by objects, and there are no shadows.
- A very fast object can cross a sensor’s beam between two steps without being seen.
- Parts can’t be scaled in a circuit, only in the component editor.

