# How to write expression to change HW component behavior#

## Exprtk library#

In various scenarios, you may want to modify the drone components behavior. To
achieve that, Parrot Sphinx offers the feature of injecting mathematical
expressions using the ExprTk
syntax in real time. It is possible in JSON-RPC variables that generally end
with `Expr`

or `Function`

.

Most of the keywords recognized by ExprTk are listed below:

Mathematical operators:

+, -, *, /, %, ^

Functions:

min, max, avg, sum, abs, ceil, floor, round, roundn, exp, log, log10, logn, root, sqrt, clamp, inrange, swap

Trigonometry:

sin, cos, tan, acos, asin, atan, atan2, cosh, cot, csc, sec, sinh, tanh, d2r, r2d, d2g, g2d, hyp

Equalities, Inequalities:

=, ==, <>, !=, <, <=, >, >=

Assignment:

:=, +=, -=, *=, /=, %=

Boolean logic:

and, mand, mor, nand, nor, not, or, xor, xnor

Control Structures (if-then-else, ternary conditional, switch case, return-statement)

Loop Structures (while loop, for loop, repeat until loop, break, continue)

String operations (equalities, inequalities, boolean logic, concatenation and ranges)

Expression local variables, vectors and strings

User defined variables, vectors, strings, constants and function support

Component parameters that support ExprTk syntax are recognized by the “_expr” at
the end of their name. For instance, IMU’s acceleration in X can be modified by
setting the value of its `acceleroX_expr`

component parameter (see
Interact with the simulation for more information on component parameters).

## Special variables and functions#

To help the user write expressions for component parameters, Parrot Sphinx provides additional variables and functions in the expression evaluation context.

### Current value#

By default, expressions are often set to `val`

. `val`

usually refers to the
exact and actual value before any modification. For example, in the context of
the `acceleroX_expr`

component parameter, the `val`

variable refers to the
real acceleration in X. In the context of the `gyroP_expr`

component
parameter, the `val`

variable refers to the real angular velocity around the
X axis. So, setting an expression to `val`

usually means the original value
will remain unaffected.

### Predefined variables#

All ExprTk JSON-RPC expressions can have access to a set of predefined variables. Some of them are common to all the functions, while others are specific to a given type of drone component, such as motor or aerodynamics.

Below is the list of the predefined variables common to all ExprTk expressions:

`posX`

: X coordinate in world frame [m]`posY`

: Y coordinate in world frame [m]`posZ`

: Z coordinate in world frame [m]`speedX`

: linear body speeds [m/s]`speedY`

: linear body speeds [m/s]`speedZ`

: linear body speeds [m/s]`accX`

: linear body accelerations [m/s²]`accY`

: linear body accelerations [m/s²]`accZ`

: linear body accelerations [m/s²]`p`

: roll [rad]`q`

: pitch [rad]`r`

: yaw [rad]`phi`

: angular body speeds [rad/s]`theta`

: angular body speeds [rad/s]`psi`

: angular body speeds [rad/s]`phidot`

: X angular body accelerations [rad/s²]`thetadot`

: Y angular body accelerations [rad/s²]`psidot`

: Z angular body accelerations [rad/s²]`temperature`

: atmospheric pressure at the current location of the drone. [°C]`pressure`

: atmospheric pressure at the current location of the drone. [Pa]`atm_density_ratio`

: ratio between current atmospheric density over reference atmospheric density (atmospheric density at altitude 0 at 15°C)`time`

: time of the simulation since the launch of Parrot Sphinx. [s]`rtime`

: time of the simulation since the last expression edition drone-wide. [s]

### Noise functions#

`noise()`

#

The `noise()`

function is defined as \(~\mathcal{N}(0,1)\).

By editing the expression string, it is easy to change the standard
deviation (`std = 10`

) and the mean (`mean = 2`

) of the noise:

```
acceleroX_expr = val + noise() * 10 + 2
```

`randu()`

#

The `randu()`

function is defined as \(~\mathcal{U}\) (uniform
distribution between 0 and 1).

This function is useful in particular to select an output function with a given probability, for example:

```
acceleroX_expr = (0.001 > randu()) ? val + noise() * 0.05 : val + noise() * 0.01
```

`randwalk()`

#

The `randwalk()`

function is defined as an accumulation of noise data
following \(~\mathcal{N}(0,1)\) over time (random walk).

Example:

```
pressure_expr = 1.756*noise()+0.05*randwalk()
```

Accumulated data is reset to zero each time that a parameter held by the transformer is changed.

`markov_noise()`

#

The `markov_noise(k, std)`

function is defined as an accumulation of
noise data which depends on the previously computed value.
Mathematically it corresponds to:

where acc is what was accumulated at the previous iteration (starts at 0).

It has two parameters:

k (between 0.0 and 1.0) which defines how much of the previous value is kept.

std is the standard deviation of the noise range.

Example:

```
markov_noise(0.5, 1.0) # 50% of the accumulator value is added to a gaussian of std 1.0
markov_noise(1.0, 0.0) # Same as noise()
markov_noise(1.0, 1.0) # Same as randwalk()
```

Accumulated data is reset to zero each time that a parameter held by the transformer is changed.

### Area functions#

`outside_area()`

#

The `outside_area('area_name')`

function returns 1.0 if the drone is outside
the area named area_name and any areas that contain the tag area_name, 0.0
otherwise.

This function can be used, for example, to restrict the number of satellites in view for the GPS device:

```
num_sv_expr = 12 * outside_area('indoor_area')
```

`inside_area()`

#

The `inside_area('area_name')`

function returns 1.0 if the drone is inside the
area named area_name and any areas that contain the tag area_name, 0.0
otherwise.

## Modify the output of sensors#

Most of the expressions affecting the output of sensors are set to `val`

to
return a perfect output. For some sensors, like the barometer, the firmware
considers the sensor to be defective if it receives perfect output. In such
cases, a minimal noise is added by default:

```
pressure_expr = val + noise() * 0.01
```

The list of available expressions for each sensor can be found on their respective reference page.

You can modify the expressions altering the output of sensors with the
`sphinx-cli param`

command.

**Example 1:** The following example shows how to modify the Y-axis component
of the accelerometer output by adding a sinus to it:

```
$ sphinx-cli param imu/icm40609 acceleroY_expr "val + sin(time) * 10"
```

**Example 2:** The following example shows how to modify the barometer pressure
output by adding noise and a bias error of 12 Pa to it:

```
$ sphinx-cli param barometer/lps22hb pressure_expr "val + noise() * 0.01 + 12"
```

**Example 3:** The following example shows how to modify the barometer pressure
output by adding noise and a bias error depending on the altitude to it:

```
$ sphinx-cli param barometer/lps22hb pressure_expr "val + noise() * 0.01 + posZ"
```

You can also define local variables to write more complex expressions in a clear way. For instance, you can define constants, or normalize variables. Here is the syntax to use (don’t forget the semicolon).

```
var name := value;
```

Warning

Do not try to override the definition of predefined variables.