POST_SUBS
ModelingUsed to extract MotionSolve results.
Use
To generate an output file or process the results programmatically, in other words, for real-time animation or plotting.
<Post_UserAPIS
id = "100001"
usrsub_param_string = "USER()"
usrsub_dll_name = "ms_csubdll"
usrsub_fnc_name = "POST_SUBS"
/>
Format
- Fortran Calling Syntax
-
SUBROUTINE POST_SUBS (ID, TIME, IFLAG, INTERPOLATION_FLAG)
- C/C++ Calling Syntax
-
void STDCALL POST_SUBS (int *id, double *time, double *par, int *npar, int *iflag, int *endflag, int *errflg)
- Python Calling Syntax
-
def POST_SUBS(id, time, par, npar, iflag, endflag): return errflg
- MATLAB Calling Syntax
-
function errflg = POST_SUBS(id, time, par, npar, iflag, endflag)
Attributes
- ID
- [integer]
- TIME
- [double precision]
- IFLAG
- [logical]
- INTERPOLATION_FLAG
- [logical]
Example
The following example writes the X,Y,Z and Euler parameters for each rigid body in the model at each time step into a results XML file:
<Post_UserAPIS
id = "1"
usrsub_param_string = "USER(1)"
interpreter = "Python"
script_name = "/post_subs.py"
usrsub_fnc_name = "POST_SUBS"
/>
The contents of post_subs.py are:
NULL = 0
fout = []
foutid = {}
nparts = 0
nrequest = 0
partids = []
reqids = []
def POST_SUBS(id, time, par, npar, iflag, endflag):
global NULL
global fout
global nparts
global nrequest
global partids
global reqids
if endflag!=0:
# Wrap up
if fout[foutid[str(id)]]!=NULL:
fout[foutid[str(id)]].write("</MultiBodyResults>\n")
fout[foutid[str(id)]].close()
return 0
if iflag!=0:
outfile = py_gtonam()
outfile += "_"+str(id)+"_res.xml"
foutid[str(id)] = len(fout)
fout.append(open(outfile,"w"))
# XML Header
fout[foutid[str(id)]].write("<?xml version=\"1.0\"?>\n")
fout[foutid[str(id)]].write("<MultiBodyResults>\n")
# Get ID information
nparts = py_getnumid("PART")
if nparts!=0:
[partids, err_flg] = py_getidlist("PART",nparts)
if err_flg <0:
return err_flg
nrequest = py_getnumid("REQUEST")
if nrequest!=0:
[reqids, err_flg] = py_getidlist("REQUEST",nparts)
if err_flg <0:
return err_flg
else:
if fout[foutid[str(id)]]==NULL:
print ("Output file was not opened, no results will be written\n")
return -1
fout[foutid[str(id)]].write("\t<Results\n")
fout[foutid[str(id)]].write("\t\ttime = \"%f\">\n"% time)
# Rigid Body
if int(par[0]) == 1:
for i in range(nparts):
[grndflag, info] = py_modfnc("Body_Rigid", partids[i],"IsGround")
if grndflag=="FALSE":
states = py_get_post_states("PART", partids[i])
fout[foutid[str(id)]].write("\t\t<RigidBody\n")
fout[foutid[str(id)]].write("\t\t\tid = \"%d\"\n"% partids[i])
fout[foutid[str(id)]].write("\t\t\tx = \"%-11.8G\"\n"% states[0])
fout[foutid[str(id)]].write("\t\t\ty = \"%-11.8G\"\n"% states[1])
fout[foutid[str(id)]].write("\t\t\tz = \"%-11.8G\"\n"% states[2])
fout[foutid[str(id)]].write("\t\t\te0 = \"%-11.8G\"\n"% states[3])
fout[foutid[str(id)]].write("\t\t\te1 = \"%-11.8G\"\n"% states[4])
fout[foutid[str(id)]].write("\t\t\te2 = \"%-11.8G\"\n"% states[5])
fout[foutid[str(id)]].write("\t\t\te3 = \"%-11.8G\"\n"% states[6])
fout[foutid[str(id)]].write("\t\t/>\n")
# Request
if int(par[0]) == 2:
for i in range(nparts):
states = py_get_post_states("REQUEST", reqids[i])
[reqtype, info] = py_modfnc("Post_Request", reqids[i], "type")
fout[foutid[str(id)]].write("\t\t<Request\n")
fout[foutid[str(id)]].write("\t\t\tid = \"%d\"\n"% reqids[i])
fout[foutid[str(id)]].write("\t\t\ttype = \"%s\"\n"% reqtype[i])
fout[foutid[str(id)]].write("\t\t\f1 = \"%-11.8G\"\n"% states[0])
fout[foutid[str(id)]].write("\t\t\f2 = \"%-11.8G\"\n"% states[1])
fout[foutid[str(id)]].write("\t\t\f3 = \"%-11.8G\"\n"% states[2])
fout[foutid[str(id)]].write("\t\t\f4 = \"%-11.8G\"\n"% states[3])
fout[foutid[str(id)]].write("\t\t\f5 = \"%-11.8G\"\n"% states[4])
fout[foutid[str(id)]].write("\t\t\f6 = \"%-11.8G\"\n"% states[5])
fout[foutid[str(id)]].write("\t\t\f7 = \"%-11.8G\"\n"% states[6])
fout[foutid[str(id)]].write("\t\t\f8 = \"%-11.8G\"\n"% states[7])
fout[foutid[str(id)]].write("\t\t/>\n")
return 0
Comments
- The Post_Subs is called by MotionSolve and based on the synchronization type.
-
From within Post_Subs, you may also call the other available utility subroutines, such as MODFNC.