# Custom Functions

You can expand the set of MotionSolve functions by adding new, custom functions.

For instance, two new functions may be defined to compute special scalar (dot) products of two vectors as follows:
DOT1
(i_marker_id, i_axis_idx, j_marker_id, j_axis_idx)
Dot product of a unit axis of marker J with another unit axis of marker I. For example,
DOT1(I,1,J,3)=UVX(I)*UVZ(J)
DOT2
(i_marker_id, j_marker_id, j_axis_idx)
Dot product of a unit vector along one axis of marker J, with a unit vector from marker J to I. For example,
DOT2(I, J,3)=DXYZ(I,J)*UVZ(J)

Custom functions defined this way may be used in exactly the same way as pre-defined MotionSolve functions. For instance, custom functions may be used in expressions as well as SYSFNC and CUSFNC calls from within user written subroutines.

When a custom function has the same name as a pre-defined MotionSolve function, the custom function takes precedence. Custom functions override pre-defined functions.

## Create Custom Functions

1. Edit the mapping file.
An entry is made to the mapping file declaring the custom function as shown in the image below:
The general syntax for the CustomFunction element is:
<CustomFunction
SYMBOL              = "string"
USRSUB_DLL_NAME     = "valid path name"
USRSUB_FNC_NAME     = "valid function name"
NUM_PARAM           = "integer"
/>
Attributes
Description
SYMBOL
Specifies the symbol to be used to identify the custom function. This symbol would be used in the MotionSolve XML trying to access the function.
USRSUB_DLL_NAME
Specifies the path and name of the DLL or shared library containing the user subroutine. MotionSolve uses this information to load the user subroutine in the DLL at run time.
USRSUB_FNC_NAME
Specifies the function within the DLL to be used by the solver for the current purpose.
NUM_PARAM
Specifies the number of parameters the custom function takes as input to perform the computation.
2. Define the path to the mapping file.
1. Modify the environment variable Variable name: MS_CUSTOM_MAPPING_FILE to point to the mapping file, as shown in the image below:
3. Set the environment variables.
1. Create a VARSUB-like user-written subroutine and build DLL as shown in the image below:
From this point forward, the DOT1 and DOT2 custom functions can be used in models just like the pre-defined MotionSolve functions. For instance, the example in the image below shows the use of the DOT1 function for defining a general constraint element. The constraint specifies that the angle between the x-axis (i_axis_idx = 1) of the I marker (i_marker_id = 100) and the y-axis (j_axis_idx = 2) of the J marker (j_marker_id = 200) must be equal in magnitude but opposite to the angle between the y-axis of the I marker and the x-axis of the J marker.
If all the arguments are in the form of integers, then you can use the SYSFNC as shown in the image below:
Or, you use CUSFNC if the arguments are mixed (integers and doubles):