Ordinate 2DDocs Community Open the studio

Python reference

import studio as s

Every function, callback and property of the studio module, generated from its source. Errors say what is wrong: no body called 'x' in the scene (there are: …), force is a pair of numbers, mass must be finite.

Making bodies

s.circle(x, y, r, mass=1.0, *, name=None, static=False, angle=0.0, friction=0.5, restitution=0.2, color=None, velocity=(0.0, 0.0), omega=0.0, collide=True, hole=0.0)

A disk of radius r (m) centred at (x, y). collide=False: it passes through everything (joints still hold it). hole > 0: a ring (a hoop, tube or washer) with a hole of that radius (m, below r); bodies in the hole stay inside it, and its moment of inertia is m (r² + hole²) / 2.

s.box(x, y, w, h, mass=1.0, *, name=None, static=False, angle=0.0, friction=0.5, restitution=0.2, color=None, velocity=(0.0, 0.0), omega=0.0, collide=True)

A w × h (m) rectangle centred at (x, y), turned by angle (rad CCW). collide=False: it passes through everything.

s.ground(y=0.0, *, x=0.0, width=24.0, angle=0.0, name=None, friction=0.8, restitution=0.1)

A ground whose top surface passes through (x, y), width m long, tilted by angle (rad CCW). A contact bounces with the smaller restitution of the two bodies: give the ground restitution=1 to let a ball's own restitution decide.

Finding bodies and joints

s.body(name)

The body called name (as in the Explorer).

s.bodies()

Every body of the scene.

s.joint(name)

The joint called name (as in the Explorer).

s.joints()

Joints

s.pin(a, b, at=None, *, name=None)

A pin joint between a and b at the world point at (default: b's centre). a = None pins b to the world.

s.rod(a, b, at_a=None, at_b=None, *, name=None)

A rigid massless rod from at_a on a to at_b on b (world points; default: the centres).

s.spring(a, b, k, c=0.0, rest=None, at_a=None, at_b=None, *, name=None)

A spring of stiffness k (N/m) and damping c (N·s/m); rest length rest m (default: the distance now).

s.slider(a, b, axis=(1.0, 0.0), at=None, *, name=None)

b slides along axis (a direction fixed in a; a = None: in the world) through at (default: b's centre).

s.weld(a, b, at=None, *, name=None)

Glue b to a (at the world point at, default b's centre).

s.cable(a, b, at_a=None, at_b=None, slack=0.0, *, name=None)

An ideal cable (it pulls, never pushes) from at_a on a to at_b on b; its length is the distance now plus slack (m).

Running

s.run(seconds=None)

Run the simulation for seconds (None: until it is stopped). In the studio this ends the script's top level.

s.stop()

Stop the simulation (the run's @s.on_end functions are called).

s.reset()

Back to the scene as it was when the run started (time 0).

s.clear()

Remove every body and joint (a script that builds its scene starts with this, so running it again starts afresh).

s.open(path)

Locally: load a scene saved by the studio. In the studio the script works on the open scene, and this does nothing.

Recording a table

s.record(**values)

Add a row to the script's table (in the studio: a sheet named Script in the Table tab). record(t=s.time, x=ball.x)

s.rows()

The rows recorded so far, as a list of dicts.

Callbacks

Decorate a function to have it called by the simulation:

@s.on_start

def f() — when a run starts from the beginning

@s.on_step

def f(t, dt) — before every step; set forces, motor speeds, … here

@s.on_collision

def f(a, b) — when two bodies start touching

@s.on_end

def f() — when a run of s.run(seconds) is over, or s.stop() is called

Settings of the scene

NameMeaning
s.timereadSimulation time, s.
s.dtreadThe simulation step, s.
s.gravityread and set(gx, gy) m/s², y up: (0, -9.80665) on Earth.
s.air_densityread and setkg/m³ (0: a vacuum; 1.225 at sea level).
s.Gread and setThe constant of gravitation for the bodies with gravitates (m³/(kg s²); the real 6.674e-11 by default).
s.in_studioreadTrue in the studio, False locally.

Body objects

A rigid body of the scene. Read its state; set a force, a torque, a velocity or a position.

PropertyMeaning
.nameread
.massread and setkg
.inertiaread and setkg·m² about the centre: set it for a hoop (m r²), a flywheel with a heavy rim, any body whose mass is not spread evenly; 0 or None: from the shape again
.gravitatesread and setTrue: pulls and is pulled by every other gravitating body, G m1 m2 / r² (s.G); the engine evaluates it in every substep, so orbits close (a force set in on_step is held over the step)
.staticreadTrue for a support or a fixed body
.xread and setm
.yread and setm
.angleread and setrad, counter-clockwise
.vxread and setm/s
.vyread and setm/s
.omegaread and setrad/s, counter-clockwise
.positionread and set
.velocityread and set
.speedreadm/s
.forceread and set(Fx, Fy) N at the centre of mass, applied every step until changed
.torqueread and setN·m, counter-clockwise, applied every step until changed
.colorread and set
.remove()

Take the body (and its joints) out of the scene.

Joint objects

A pin, rod, spring, slider, weld or cable. Read its state; switch it, drive its motor, change a spring.

PropertyMeaning
.nameread
.kindreadpin, rod, spring, slider, weld or cable
.aread
.bread
.anglereadpin: the turn of b relative to a since it was made, rad CCW
.speedreadpin: rad/s CCW; slider: m/s along the axis
.positionreadslider: m along the axis
.lengthreadrod, spring, cable: m
.tensionreadrod, spring, cable: N, positive when it pulls
.reactionread(Fx, Fy) N: the joint's force on b over the last step
.enabledread and set
.kread and setspring: N/m
.cread and setspring: N·s/m
.restread and setspring: rest length, m
.motor(speed, limit=1000.0)

Drive a pin (speed rad/s CCW, limit N·m) or a slider (m/s along its axis, limit N); motor(None) stops driving.

.remove()