MV-1024: Using User Subroutines in MotionSolve Models |
|||||
MV-1024: Using User Subroutines in MotionSolve Models |
User subroutines are created for various reasons. Some include:
• | To describe a physical phenomenon that is determined by non-trivial logical conditions. |
• | When it is impractical to formulate a complicated expressions in an explicit form. |
• | To take full advantage of a programming language like C/C++ or Fortran and simpler programming with interpreters like Tcl, Python, and Ruby. |
To use your own subroutines in MotionSolve, follow these steps:
1. | Create a C/C++, FORTRAN, Tcl, or Python source file that contains the user-defined modeling entity. |
Refer to the MotionSolve User's Guide for a list of supported solver subroutines and a general guideline on setting up and using subroutines in your model.
2. | Obtain a DLL by compiling and linking your user subroutine(s) for C/C++ or Fortran, or use the source file directly for Tcl or Python. |
MotionSolve supports two separate levels of user DLLs and the algorithm attempts to resolve the symbols, starting from the most specific library.
A) Element Level DLL (most specific)
Specify the name of the DLL in the modeling element definition.
B) Machine Level DLL
You can create an environment variable called MS_USERSUBDLL and set it to the DLL file. This environment variable is not defined automatically when MotionSolve is installed. However, Fortran, and C/C++ DLLs are provided in the installation folder <installation_directory>\hwsolvers\usersub\subdll\win32\. This allows you to run some of the test models that use user subroutine DLLs.
Note | The DLL that is loaded is based on the "most specific" rule: number one overrides number two. |
3. | Modify the corresponding entity in your multi-body model to be "user defined" and point it to your DLL. This can be done in two ways: |
A) By modifying the entity in the MotionView interface.
B) By editing the MotionSolve XML file.
Regardless of the method you select, you will end up with an XML file where one or more entities are now user defined.
For example, consider the coupler modeling element in the XML file:
<Constraint_Coupler
id = "1"
type = "TwoJoint"
i_marker_id_joint1 = "30603030"
j_marker_id_joint1 = "30602031"
body1_id_joint1 = "30603"
body2_id_joint1 = "30602"
joint_type_joint1 = " "
i_marker_id_joint2 = "30603040"
j_marker_id_joint2 = "30604040"
body1_id_joint2 = "30603"
body2_id_joint2 = "30604"
joint_type_joint2 = " "
usrsub_param_string = "USER(-8.5)"
usrsub_dll_name = "C:/work/testsub.dll">
</Constraint_Coupler>
The usrsub_dll_name argument defines C:/work/testsub.dll as the element level DLL for this coupler element. Any element can be defined by pointing to a different DLL.
The coupler modeling element in the XML file can also be defined as:
<Constraint_Coupler
id = "1"
type = "TwoJoint"
i_marker_id_joint1 = "30603030"
j_marker_id_joint1 = "30602031"
body1_id_joint1 = "30603"
body2_id_joint1 = "30602"
joint_type_joint1 = " "
i_marker_id_joint2 = "30603040"
j_marker_id_joint2 = "30604040"
body1_id_joint2 = "30603"
body2_id_joint2 = "30604"
joint_type_joint2 = " "
usrsub_param_string = "USER(-8.5)"
usrsub_dll_name = "NULL">
</Constraint_Coupler>
In this case, MotionSolve looks for a machine level DLL as defined by the value of the MS_USERSUBDLL environment variable.
4. | Run MotionSolve, verifying that it picks up the appropriate DLL during simulation. |
Exercise
Copy the model file required for this exercise, Pendu_model.mdl, from the mbd_modeling\motionsolve to your <working directory>.
Step 1: Using an expression to define motion.
1. | Launch a new MotionView session. |
2. | Load the MDL model file Pendu_model.mdl from your <working directory>. |
3. | From the Project Browser, right-click on Model and select Add Constraint > Motions (or right-click the Motions icon, , from the toolbar). Add a Displacement motion to the revolute joint between the Pendulum Body and the Ground Body. |
4. | Click the Properties tab. |
Set an expression of 3.142* TIME for the displacement motion.
5. | Click the Outputs panel icon, , to access the Outputs panel. |
Review the output request.
6. | Click the Run panel icon, , to access the Run panel. |
7. | Click the Save and run current model: folder icon, , and browse to your <working directory>. Specify the name as Pendu_model.xml for the MotionSolve input XML file. |
8. | Confirm that the Simulation type: is set to Transient. |
9. | Specify 1 as the End Time. |
10. | Click the Check button, , to check for any modeling errors. |
11. | After verifying that there are no errors, click the Run button. |
12. | Once the run is complete, the Animate button is activated. Click Animate to view the animation of the simulation. |
13. | From the Run panel, click the Plot button to view the time-histories of the output request. |
Step 2: Using the MOTSUB user subroutine to define motion.
In this step, we will use the user subroutine MOTSUB. This user subroutine has been compiled and linked in the DLL ms_csubdll.dll. This machine level DLL is provided in the HyperWorks installation. For the Windows 32-bit platform, the DLL is located at: <installation_directory>\hwsolvers\usersub\subdll\WIN32\.
We will use the ms_csubdll.dll as a machine level DLL.
1. | Create an environment variable MS_USERSUBDLL and set the value to the DLL file. |
For Windows 32-bit platform users, this will be: <installation_directory>\hwsolvers\usersub\subdll\WIN32\ms_csubdll.dll
- | Right-click on the My Computer icon. From the Advanced tab, select Environment variables > New (under User variables). |
- | Set Variable name: to MS_USERSUBDLL. |
- | Set Variable value: to <installation_directory>\hwsolvers\usersub\subdll\win32\ms_csubdll.dll. |
2. | With the Pendu_model.mdl from the previous step open in the MotionView model window, go to the Motions panel, . |
3. | From the Connectivity tab, check the User-defined properties check box. |
4. | Click the User-Defined tab and enter `USER(100001,5,2)` in the text-box. |
Note | To use an element level (specific) DLL/Interpreter function, you can check the Use local dll and function name check-box and point to the DLL using the folder icon, . |
The string `USER(100001,5,2)` is used to pass arguments to the MOTSUB user subroutine. The MOTSUB user subroutine calculates motion using the parameters par1 and par2 in USER(branch_id, par1, par2) as follows:
motion_val= par1*TIME^par2
5. | From the File menu, select Export > Model. |
Note | Click the Save File icon, , on the Main toolbar to save the file in working directory with the existing name. If it’s a new model, you will be prompted for the name of the model. |
The Export Model panel is displayed.
Specify the file name as Pendu_model_usersub.mdl.
6. | Click the Run panel icon, , to access the Run panel. |
7. | Save and run current model , , and browse to your <working directory>. Specify Pendu_model_usersub.xml for the MotionSolve input XML file. |
8. | Confirm that the Simulation type: is set to Transient. |
9. | Specify 1 as the End Time. |
10. | From the Main tab, click the Check button to check for any modeling errors. |
11. | After verifying that there are no errors, click the Run button. |
12. | In the plot window, plot the results from the ABF file Pendu_model_usersub.abf to overlay the results on top of the results from the Pendu_model.abf file |
13. | In the animation window, check the Overlay option on the Load Model panel. |
14. | Select the file Pendu_model_usersub.h3d using the Load model folder icon . |
15. | Click Apply. |
This will overlay the new animation over the existing animation.
Note | If the value of the usrsub_param_string is set as “USER(3.142, 1)” the results from step 2 will be the same as results from step 1. |
17. | Open the MotionSolve XML file Pendu_model.xml (saved in step 1) from the <working directory>. |
18. | Browse through the XML file to locate the Motion_Joint block. |
<Motion_Joint
id = "301001"
label = "Motion 0"
type = "EXPRESSION"
val_type = "D"
expr = "3.142*TIME"
joint_id = "301001"
joint_type = "R"
/>
19. | Open the MotionSolve XML file Pendu_model_usersub.xml from the <working directory>. |
20. | Browse through the XML file to locate the Motion_Joint block. |
<Motion_Joint
id = "301001"
label = "Motion 0"
type = "USERSUB"
val_type = "D"
usrsub_param_string = "USER(100001,5,2)"
usrsub_dll_name = "NULL"
usrsub_fnc_name = "MOTSUB"
joint_id = "301001"
joint_type = "R"
/>
Note | When the value for the usrsub_dll_name parameter in the above block is set to NULL, MotionSolve looks for the subroutine in a machine level DLL. This DLL is passed to MotionSolve by the MS_USERSUBDLL environment variable. |
To use an element level DLL, set the value of the usrsub_dll_name parameter to point to the DLL.
The usrsub_param_string parameter is used to pass arguments to the user subroutine.
For example, the MOTSUB user subroutine calculates motion using the parameters par1 and par2 in USER(branch_id, par1, par2) as follows:
motion_val= par1*TIME^par2
MotionSolve uses the value returned from the user subroutine to calculate the motion.