Skip to content

Solver

A solver process allows the user to define a mathematical expression that will be computed in real time at a configured rate. The expression produces an output signal from 0 to 16 input signals or 0 to 32 constant values.

The solver is most useful for running custom controllers and models on the actual devices.


JCS Network Configuration

structure.yaml Configuration

type proc_solver

Signals - From Process

Signal name Type Required Description
user defined float32 required Computed expression output
Signal name shall be defined by the user

Signals - To Process

Signal name Type Required Description
user defined float32 optional Expression input
Signal name shall be defined by the user

Configuration Parameters

No parameters.


Operation

An expression is defined in the process configuration file. At system startup JCS host converts the expression to a byte code, which is transferred to the device. Once all required signals become available, a byte code interpreter on the device evaluates the expression at each rate tick.


The solver is configured by defining any constants, any input variables and any expressions.

Constants and intermediate values

storage is used to store any constants or any intermediate values.

The solver does not interpret any numerical values in the expression. Any constants must be pre-allocated, given a name and value, then referenced by the name in the expression.

Intermediate values should have an initial value defined.

Example of intermediate value storage:

(In this example th_offset is used as storage to pre-compute an angle offset, which is then used multiple times in a complex expression)

storage:
  # Constant angle offset
  - name: angle_offset
    val:  1.443

  # Variable storage to pre-compute theta offset
  - name: th_offset
    val:  0.0

signals:
  - name: theta

expressions:
  - name: th_offset
    expr: theta - angle_offset

  - name: tau
    expr: sin(th_offset) / 2*cos(th_offset)

A maximum of 32 constant values is supported.

Signals

signals defines any input signals into the solver from the outside world. Once defined, a signal may be referenced as an input signal into the solver within the 'structure.yaml' configuration file.

A maximum of 16 input signals is supported.

Expressions

expressions defines any actual expressions used by the solver.

The expression is given a name and an equation. The expression name becomes the output signal name and can be referenced within the 'structure.yaml' configuration file.

A maximum of 16 expressions is supported.


Available Operators

Name Function Example Description
+ \(x + y\) x+y Computes the addition of \(x\) and \(y\).
- \(x - y\) x-y Computes the subtraction of \(y\) from \(x\).
- \(-y\) -y Computes the unary minus of \(y\).
* \(x \times y\) x*y Computes the multiplication of \(x\) and \(y\).
/ \(x \over y\) x/y Computes the division of \(x\) and \(y\).
Will return an error and possibly estop if \(y\) is equal to \(0\).
^ \(x^y\) x^y Computes \(x\) raised to the power of \(y\).
Approximated.

Available Functions

Exponential functions

Name Function Example Description
log2 \(y = \log_2{x}\) log2(x) Computes the approximated base-2 logarithm of \(x\).
ln \(y = \ln{x}\) ln(x) Computes the approximated natural (base-\(e\)) logarithm of \(x\).
log10 \(y = log_{10}(x)\) log10(x) Computes the approximated base-10 logarithm of \(x\).
exp \(y = e^{x}\) exp(x) Computes approximated \(e\) raised to the power \(x\).
exp2 \(y = 2^{x}\) exp2(x) Computes approximated \(2\) raised to the power \(x\).

Power functions

Name Function Example Description
sqrt \(y = \sqrt{x}\) sqrt(x) Returns the square root of \(x\).
Will return an error and possibly cause an estop if \(x\) is negative.
hypot \(z = \sqrt{x^2 + y^2}\) hypot(x,y) Computes the square root of the sum of square of the two arguments.

Trigonometric functions

Name Function Example Description
sin \(y = sin{x}\) sin(x) Approximated sine function.
Computed with lookup table and cubic interpolation.
Valid input range \([0, 2\pi]\).
cos \(y = cos{x}\) cos(x) Approximated cosine function.
Computed with lookup table and cubic interpolation.
Valid input range \([0, 2\pi]\).
tan \(y = tan{x}\) tan(x) Approximated tangent function.
Computed as \(tanx = {sinx \over cosx}\).
Valid input range \([0, 2\pi]\).
atan2 \(y = arctan({{y}\over{x}})\) atan2(y, x) Approximated arc tangent of \(y \over x\) using the signs of the arguments to determine the correct quadrant.

Hyperbolic functions

Name Function Example Description
sinh \(y = sinh{x}\) sinh(x) Approximated hyperbolic sine function.
cosh \(y = cosh{x}\) cosh(x) Approximated hyperbolic cosine function.
tanh \(y = tanh{x}\) tanh(x) Approximated hyperbolic tangent function.

Functions

Name Function Example Description
abs \(y = \lvert x \rvert\) abs(x) Computes the absolute value of the argument.
sgn \(y = \begin{cases} -1, & \text{if } x\lt 0, \\ 0 , & \text{if } x = 0,\\ 1 , & \text{if } x\gt 0\\ \end{cases}\) sgn(x) Returns the sign of the argument \(x\).
max \(y =\begin{cases} a, & \text{if } a\gt b, \\ b, & \text{if } b\gt a.\\ \end{cases}\) max(a,b) Returns the maximum of a or b.
min \(y =\begin{cases} a, & \text{if } a\lt b, \\ b, & \text{if } b\lt a.\\ \end{cases}\) min(a,b) Returns the minimum of a or b.
clamp \(y =\begin{cases} a, & \text{if } x\geq a,\\ x, & b \lt x \lt a,\\ b, & \text{if } y\leq b\\ \end{cases}\) clamp(x,a,b) Clamps the value \(x\) to be between the maximum value \(a\) and the minimum value \(b\).
normpi \(y = \lvert x \rvert\) normpi(x) Normalise an angle to the range \([-\pi, \pi]\).
norm2pi \(y = \lvert x \rvert\) norm2pi(x) Normalise an angle to the range \([0, 2\pi]\).

Special sources

Note: \(dt\) is defined by the rate at which the solver process is ticked at.

time

Monotonically increasing time (seconds) in increments of \(dt\).

Notes:

  • time will get large.
  • time will wrap to \(0\) at \(uint32\) max.
  • Approximated functions, such as sin / cos can fail at very large values of time (Fast angle normalisation has been used for speed).

time_p

Periodic time (seconds).

Counts from \(0\) to \(2\pi\) in increments of \(dt\).

dt

Timestep \(dt\) (seconds) at which the solver is called at.


Practical Notes:

Functions must have parentheses

sin x is not valid.

sin(x) is valid.

Implicit multiplication not supported

twox is not valid (this will be interpreted as a constant called twox).

two*x is valid.

Unicode characters not supported

Only */-+><= are supported.

Divide by 0

Divide by zero will return an error from the solver and may result in an E-stop.

All trigonometric functions are in radians

Most trigonometric functions are approximations

and are optimised for the range \([0, 2\pi]\).

Boolean conditions return 1.0f or 0.0f (float)

Conditional statements (if, etc) compare floats.

Only CamelCase or snake_case variable or constant names are allowed

Expressions take a finite amount of time to be evaluated.

If the expression is too complex, it may not be evaluated in time before the next tick comes around. In this case the solver will overrun and the system may shut down. The time taken by the solver can be found by calling JCS host function process_timing_print.

The solver does not yet do any optimisation of the expression.

It is recommended to pre-compute any constants. For example:

expr: A * sin(two * pi * f * time_p)
might become:
expr: A * sin(two_pi_f * time_p)
where the constant two * pi * f is precomputed and stored as two_pi_f.