160 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
******************
 | 
						|
Custom Expressions
 | 
						|
******************
 | 
						|
 | 
						|
Since OpenRocket 12.09, you are not limited to using just the built-in simulation variables in your plots and
 | 
						|
analysis. With the custom expression feature, you can write expressions to calculate other values of interest during the
 | 
						|
simulation. These can then be plotted or exported just like the built-in variables.
 | 
						|
 | 
						|
.. contents:: Table of Contents
 | 
						|
   :depth: 2
 | 
						|
   :local:
 | 
						|
   :backlinks: none
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
Overview
 | 
						|
========
 | 
						|
 | 
						|
Custom expressions are added to your rocket document from the 'Analyze' menu under custom expressions. This will open a
 | 
						|
window showing all your custom expressions.
 | 
						|
 | 
						|
.. figure:: /img/user_guide/custom_expressions/custom_expressions.png
 | 
						|
   :align: center
 | 
						|
   :width: 55%
 | 
						|
   :figclass: or-image-border
 | 
						|
   :alt: The Custom Expressions window.
 | 
						|
 | 
						|
   The Custom Expressions window.
 | 
						|
 | 
						|
Initially, there will be no custom expressions, so you will need to add one using the *New expression* button in the
 | 
						|
lower right. This opens the expression builder window. You can also import expressions from another .ork file.
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
Building expressions
 | 
						|
====================
 | 
						|
 | 
						|
.. figure:: /img/user_guide/custom_expressions/expression_builder.png
 | 
						|
   :align: center
 | 
						|
   :width: 45%
 | 
						|
   :figclass: or-image-border
 | 
						|
   :alt: The Expression Builder window.
 | 
						|
 | 
						|
   The Expression Builder window.
 | 
						|
 | 
						|
You must specify a name for the expression, a short symbol, the units of the resulting value, and of course the expression
 | 
						|
itself. After you enter a valid value in each of the fields the adjacent indicator will change from red to green. Only
 | 
						|
when all indicators are green will you be able to add or update the expression.
 | 
						|
 | 
						|
- The :guilabel:`Name` field can be arbitrary; it only must have not been used before.
 | 
						|
- The :guilabel:`Symbol` field is intended for a short (locale-independent) symbol representing the value. It must not have been
 | 
						|
  used before, contain no numbers, whitespaces, or special characters such as brackets or operators.
 | 
						|
- There are no restrictions on the :guilabel:`Units`; it can even be empty for dimensionless quantities. However, if you enter a
 | 
						|
  standard SI unit then you will be able to automatically convert the units when plotting or exporting. The available
 | 
						|
  SI units are: m, m^2, m/s, kg, kg m^2, kg m^3, N, Ns, s, Pa, V, A, J, W, kg m/s, Hz, K. They must match exactly.
 | 
						|
- The :guilabel:`Expression` must only contain valid symbols, operators, and numbers and must make sense mathematically.
 | 
						|
  For convenience, the adjacent indicator updates on-the-fly.
 | 
						|
- It is possible to nest custom expressions, i.e., you can use the symbol defined for a custom expression in another
 | 
						|
  expression. However, you must ensure that expressions are calculated in the correct order if you do this. This can be
 | 
						|
  done using the blue arrows in the custom expression pane to adjust the order of calculation.
 | 
						|
 | 
						|
To see a list of the available variables and their symbols, click the :guilabel:`Insert Variable` button. This will open a window
 | 
						|
from which you can choose a variable and insert it (at the current cursor position) in the expression box. This is
 | 
						|
particularly useful because you may not be able to type some of the symbols on your keyboard. The :guilabel:`Insert Operator`
 | 
						|
window is similar and shows all the available mathematical operators and functions.
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
Index expressions
 | 
						|
=================
 | 
						|
 | 
						|
The custom expressions are calculated at each time step of the simulation; however, there are some cases where it is
 | 
						|
useful to have access to earlier values of a given variable. This is possible using **index expressions**. These use a
 | 
						|
square bracket syntax to specify the time (in seconds) for the variable you want. For example, the expression:
 | 
						|
 | 
						|
.. code-block:: none
 | 
						|
 | 
						|
  m / m[0]
 | 
						|
 | 
						|
would give the ratio of the current mass to the launch mass at time 0. Similarly,
 | 
						|
 | 
						|
.. code-block:: none
 | 
						|
 | 
						|
  m - m[t-1]
 | 
						|
 | 
						|
would give you the change in mass over the last second.
 | 
						|
 | 
						|
You can specify any valid sub-expression inside the square brackets; the only restriction is that you can't nest another
 | 
						|
index/range expression inside the square brackets.
 | 
						|
 | 
						|
When indexed expressions are calculated, interpolation is used to get the value exactly at the specified time, independent
 | 
						|
of the time steps of the simulation.
 | 
						|
 | 
						|
If you specify a time smaller than 0 or greater than t then it will be clipped to 0 or t respectively. You can't access
 | 
						|
data that has not been calculated yet.
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
Range expressions
 | 
						|
=================
 | 
						|
 | 
						|
It is sometimes useful to have access to a range of values of a particular variable rather than just one point.
 | 
						|
OpenRocket includes a number of useful operators for calculating statistics and other properties of ranges. These
 | 
						|
operators can be identified in the operator selection box by the *\[\:\]* which will already have been filled out in place
 | 
						|
of one or more of the parameters.
 | 
						|
 | 
						|
Range expressions are defined with a square bracket syntax similar to index expressions, but with a ':' used to separate
 | 
						|
the lower and upper bounds of a range. For example, suppose we had an accelerometer on our rocket which (as many do)
 | 
						|
includes some low-pass filtering on the output. This can be modeled as a moving average and defined with a custom
 | 
						|
expression such as:
 | 
						|
 | 
						|
.. code-block:: none
 | 
						|
 | 
						|
   mean(At[t-0.5:t])
 | 
						|
 | 
						|
which will calculate a moving mean for the variable At (total acceleration) over the last 0.5 seconds of data.
 | 
						|
 | 
						|
As with index expressions, the upper and lower bounds can be any valid expression. If omitted, the upper bound will
 | 
						|
default to t and the lower bound to 0, so the above expression can also be written
 | 
						|
 | 
						|
.. code-block:: none
 | 
						|
 | 
						|
   mean(At[t-0.5:])
 | 
						|
 | 
						|
In this particular case, we might want to make the expression more realistic by clipping accelerations above a given
 | 
						|
threshold and perhaps returning the actual voltage from the sensor, for example:
 | 
						|
 | 
						|
.. code-block:: none
 | 
						|
 | 
						|
   0.2 * uclip( mean(At[t-.5:]), 10 )
 | 
						|
 | 
						|
Note that when range expressions are calculated the data is generated by interpolation over the specified range with a
 | 
						|
fixed time step equal to the default time step set in your simulation options. This is independent of the current time step
 | 
						|
*dt* used by the simulation engine. When generated, range expressions include the start time and step information.
 | 
						|
This facilitates easy integration or optimization with functions such as *trapz([:])* for trapezoidal integration or
 | 
						|
*tnear([:],x)* for finding the time value when a variable is nearest a specified value.
 | 
						|
 | 
						|
For a complete list of all the operators available see the operator selection list when making a new expression.
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
Troubleshooting
 | 
						|
===============
 | 
						|
 | 
						|
While OpenRocket makes a reasonable attempt to check your expression as you enter it, it is still possible to enter
 | 
						|
something invalid or that can't be calculated for some reason. In this case you will simply end up with no data available
 | 
						|
to plot after running the simulation.
 | 
						|
 | 
						|
If you can't figure out why your expression is not generating any data or can't be accepted by the expression builder
 | 
						|
then you might find some useful information in the error log. This can be accessed from the help -> debug log menu. Any
 | 
						|
relevant messages are probably under the 'USER' category.
 | 
						|
 | 
						|
It should not be possible to cause a crash with an invalid expression. If you manage to, please report the bug and
 | 
						|
include your expression.
 | 
						|
 | 
						|
Custom expressions are interpreted during the simulation and are necessarily much slower than "native" datatypes.
 | 
						|
For a few simple expressions you probably won't notice much speed difference but it can become particularly significant
 | 
						|
if you have range expressions. If speed is an issue for you then you might want to consider implementing your expression
 | 
						|
as a `simulation listener <Simulation_Listeners>`_.
 |