HyperWorks Solvers

Writing Custom Functions for MotionSolve

Writing Custom Functions for MotionSolve

Previous topic Next topic No expanding text in this topic  

Writing Custom Functions for MotionSolve

Previous topic Next topic JavaScript is required for expanding text JavaScript is required for the print function  

The steps below describe how to write a Custom Function for a MotionSolve input deck. The example makes use of the Python scripting support for MotionSolve. Appendix A contains an example of a Custom Function written using the C programming language.

Create a Custom Mapping File

1.Copy and paste the following XML element into a file. For example, C:/test/my_custom_mapping.xml.

 

<?xml version="1.0"?>

<!-- MotionSolve custom mapping definition file -->

<MSolve_Custom_Mapping>

  <CustomFunction

      symbol           = "MyCustomFnc"

      interpreter      = "Python"

      script_name      = "C:/my_python_scripts/test.py"

      usrsub_fnc_name  = "CustomFnc"     

      num_param        = "5"

  />

</MSolve_Custom_Mapping>

The name defined by the parameter symbol will be used as the Custom Function name by MotionSolve. Thus, the symbol name is merely an alias for the function defined by the parameter usrsub_fnc_name contained in the script file defined by the parameter script_name. So, the script file (test.py in this case) should contain the method CustomFnc.

Define the Environment Variable

1.Define and set the environment variable “MS_CUSTOM_MAPPING_FILE”.

custom_func_editvar

After completing the above steps, you will be able to use the Custom Function MyCustomFnc(..,..) as you would a regular MotionSolve expression, such as CUBSPL(..).

The same procedure described above works if you want to use a user subroutine that does not make use of an interpreted script, but of compiled C code instead. In this case, the CustomFunction needs to be defined as:

 

  <CustomFunction

     symbol           = "MyCustomFnc"

     usrsub_dll_name  = "valid_path_name"

     usrsub_fnc_name  = "CustomFnc"

     num_param        = "5"

  />

Appendix A

The following example illustrates a Custom Function written to calculate the dot product of a unit axis of marker J with another unit axis of marker I.

DOT1(I,1,J,3) = UVX(I)*UVZ(J).

 

<!-- Custom Function Mapping section-->

<CustomFunction

     symbol           = "DOT1"

     usrsub_dll_name  = "NULL"

     usrsub_fnc_name  = "VARSUB_DOT1"

     num_param        = "4"

 />

 

An implementation of the corresponding usersub associated with the dot1:

DLLFUNC void STDCALL VARSUB_DOT1

(int *id, double *time, double *par, int *npar,  int *dflag, int *iflag, double *value)

{

   int nstates,errflg;

   int i_marker_id = (int)par[0];

   int i_axis_idx = (int)par[1];

   int j_marker_id = (int)par[2];

   int j_axis_idx = (int)par[3];

   double axis_i[3], axis_j[3];

   switch (i_axis_idx)

   {

   case 1:

       c_sysary("uvx",&i_marker_id,1,axis_i, &nstates, &errflg);

       break;

   case 2:

       c_sysary("uvy",&i_marker_id,1,axis_i, &nstates, &errflg);

       break;

   case 3:

       c_sysary("uvz",&i_marker_id,1,axis_i, &nstates, &errflg);

       break;

   default:

       break;

   }

   switch (j_axis_idx)

   {

   case 1:

       c_sysary("uvx",&j_marker_id,1,axis_j, &nstates, &errflg);

       break;

   case 2:

       c_sysary("uvy",&j_marker_id,1,axis_j, &nstates, &errflg);

       break;

   case 3:

       c_sysary("uvz",&j_marker_id,1,axis_j, &nstates, &errflg);

       break;

   default:

       break;

   }

   *value = axis_i[0]*axis_j[0]+axis_i[1]*axis_j[1]+axis_i[2]*axis_j[2];

}

 

Now, the function DOT1 can be used.  For example, DOT1(I,1,J,3) which is simply UVX(I)*UVZ(J).