# Throbol Reference Manual

## Overview

Throbol is a time-domain spreadsheet. Like a spreadsheet, every cell has a name and formula, and cells can refer to each other by name. The recalculation engine automatically figures out what order to calculate them in. Unlike most spreadsheets, each cell's value is a time series. You can refer to a cell's current value as foo, and its previous value as foo[-dt].

Throbol can be used in 3 modes:

• controlling live robot hardware.
• controlling a simulated robot.

When controlling a live robot, runs must be started with ⌘L. With a simulated robot, it will re-run the simulation whenever a formula or parameter changes.

## Throbol formula language quick reference

• Types and literals:

• float like 3.0
• complex like 3.0 + 4.2im
• vec3 like [1, 2, 3]: a column vector. Any size works.
• mat2 like [[1, 2], [3, 4]]: a square matrix with columns [1,2] and [3,4]. Any size works.
• mat23x42: a rectangular matrix. Any size works
• string like "foo"
• SymbolSet like 'foo or 'mode.start | 'mode.run
• Parameters:

• value~range like 6.2~10: a float parameter with a current value of 6.2 and a range of -10 .. +10
• expr~range like [1.1, 2.2, 3.3]~5: all numeric values in expr become parameters
• Arithmetic:

• a + b: scalar, complex, vector, or matrix addition
• a - b: as expected
• a * b: as expected for scalar. Matmul semantics for mat * mat or mat * vec
• a / b: as expected, but matrices and vectors can only be divided by a scalar
• a .+ b, a .- b, a .* b, a ./ b: Elementwise arithmetic
• a ^ b: exponentiation
• Math functions:

• sin(a), cos(a), tan(a), sinh(a), cosh(a), tanh(a), exp(a), log(a): as in C
• sqrt(a), sqr(a), cbrt(a), cube(a): as in C, or use a^0.5, a^2, a^(1/3), a^3
• lerp(a, b, c): interpolate between a & b, equivalent to a + c * (b - a)
• Randomness:

• random() uniform in [0..1]
• randomNormal() from $\N(0,1)$ clamped to [-3..3]
• Comparison:

• bool(a): like a >= 0.5 ? 1.0 : 0.0
• a == b: exact equality
• a ~~ b: true if a and b are similar (within 0.1%)
• a ~~~ b: signal an error if a and b aren't similar. Either way, return a
• Sets:

• a | b: union of sets a and b
• a & b: intersection
• Misc:

• repr(a): string representation
• Functions:

• foo{a=1, b=2}: the value of cell foo with cells a and b (which must exist) having the values provided.
• Control Theory:

• lpfilter1(period, input): a single pole low-pass filter
• lpfilter2(period, q, input): a double pole low-pass filter
• vel(a): the time derivative of a, calculated as (a - a[-dt])/dt
• lookahead(t, a): a prediction of the value of a in t seconds, calculated as a + vel(a)*t
• Stateful functions:

• duration(a): the time (in seconds) that a has been continuously true for.
• duration(a, 'foo|'bar): the time that behavior tree a has run either 'foo or 'bar
• latch(a): true if a was ever true
• latch(a, b): becomes true when a is true, or false when b is false. If both are true, returns false.
• hysteresis(a): becomes 1 whenever a > 0.5, or -1 whenever a < -0.5
• clampslew(a, ratelo, ratehi): follows a, but changes at a rate clamped between ratelo and ratehi.
• Geometry:

• length(a): norm2 of a vector
• distance(a, b): length of a-b
• mat4.rotx(a), mat4.roty(a), mat4.rotz(a): 4x4 rotation matrix around an axis.
• mat4.rotxderiv(a), mat4.rotyderiv(a), mat4.rotzderiv(a): the derivative of above matrices WRT a
• mat4.scale(a): 4x4 scale matrix
• mat4.translate(a), mat4.translate(x, y, z): translation by a∊vec3 or x, y, z.
• mat3.rotx(a), mat3.roty(a), mat3.rotz(a): 3x3 rotation around an axis
• mat3.scale(a) or mat3.scale(x, y, z): 3x3 scale matrix
• mat2.rot(a): 2x2 rotation matrix
• mat2.scale(a) or mat2.scale(x, y): 2x2 scale matrix
• normangle(a): modulo 2pi, within -pi to +pi
• normalize(a): like a/length(a)
• Complex:

• 3.0 + 4.2im: complex number. Equivalent to 3.0 + 4.2*im
• polar(length, angle): complex number from length & angle.
• conj(a): complex conjugate
• real(a), imag(a): get real or imaginary component
• arg(a): get angle
• abs(a): get magnitude
• mat2(a): same as [[real(a), -imag(a)], [imag(a), real(a)]]
• Cells:

• Every cells has a name, consisting of alphanumerics and ..
• You can refer to the value of a cell by name like foo, or the previous value with foo[-dt], or a value at some past time with foo[-0.5]. References to times before 0 return a zero or null value (generally safe to work with).
• Any number of expressions terminated by semicolons can preceed the cell value. It's useful for binding cell-local variables, like a=2; b=3; a + b yields 5.
• Graphics:

• line(p0 ∊ vec2|3|4, p1 ∊ same): a line from p0 to p1
• linePlot(x, y) or linePlot(x, y, z)
• Add axis labels: linePlot(volume, pressure){labelX="V", labelY="P"}
• Set ranges: linePlot(volume, pressure){rangeX=[0, 100], rangeY=[0, 800]}
• scatterPlot(x, y) or scatterPlot(x, y, z): as above but with dots
• Add a linear regression line with scatterPlot(x, y){regressionLine=1}
• spline(controlPoints ∊ mat3xN, thickness)
• disk(center, size)
• text(pos, size, str) with size ∊ float is the font size. 0.05 is common.
• solid(filename): a solid loaded from an STL file
• dial(value, range) or dial(center, radius, value, range)
• One or more label(value, str)s can be attached to mark points on the dial
• arcArrow(center, rx, ry, up):
• Set color by adding {color=#ff0000ff} or {color=graphColor(12)}.
• The syntax #RRGGBBAA results in a vec4 of RGBA values in [0..1]
• graphColor(index): returns a pleasing color for each integer index,
• Multiple graphics can be combined (overlaid) with |. They're drawn in left-to-right order, although you should mostly use the Z axis to determine layering
• You can transform graphics by pre-multiplying with a mat4.
• See the Stirling engine sheet for an example of graphs, or the Solo12 for an example of 3D rendering.
• Optimization:

• minimize.lbfgsb(target, params...): apply an L-BFGS-B optimizer to minimize the target value. Parameters aren't directly changed; this cell returns a graphical object you can click on to inspect suggested parameter changes or apply them.
• minimize.newton, minimize.grad, minimize.cgrad, minimize.bfgs, minimize.lbfgs: Like the above using other algorithms from Minpack.
• minimize.particle(target, params...): particle search minimize