Commit d01e98f9 authored by Olivier Lantsoght's avatar Olivier Lantsoght
Browse files

[Ctypes] C-library for symbolic functions

parent 1c0e5f24
......@@ -71,7 +71,7 @@ MbsData* mbs_load_with_loader(const char* mbs_filename, const char* build_path,
char *userfctLib_name = NULL;
char *userfctLib_path = NULL;
//-------------------------------------------------------------------------
if (!opts->no_project_fct) {
if (opts->load_symb_user != LOAD_NONE) {
// 0. build
if (build_path == NULL) // Error management
{
......@@ -107,29 +107,32 @@ MbsData* mbs_load_with_loader(const char* mbs_filename, const char* build_path,
}
// 3. userfct Library name (without extension)
if (opts->userfctLib_name == NULL)
if (opts->load_symb_user == LOAD_ALL)
{
userfctLib_name = (char*)malloc(sizeof(char)*(strlen(mbs_infos->mbsfile) + 100));
sprintf(userfctLib_name, "Project_userfct");
}
else
{
userfctLib_name = strdup(opts->userfctLib_name);
}
// 4. userfct Library path (without name)
if (opts->userfctLib_path == NULL)
{
userfctLib_path = (char*)malloc(sizeof(char)*(strlen(mbs_infos->mbsfile) + 100));
if (opts->userfctLib_name == NULL)
{
userfctLib_name = (char*)malloc(sizeof(char)*(strlen(mbs_infos->mbsfile) + 100));
sprintf(userfctLib_name, "Project_userfct");
}
else
{
userfctLib_name = strdup(opts->userfctLib_name);
}
// 4. userfct Library path (without name)
if (opts->userfctLib_path == NULL)
{
userfctLib_path = (char*)malloc(sizeof(char)*(strlen(mbs_infos->mbsfile) + 100));
#ifdef UNIX // To clean up One day !
sprintf(userfctLib_path, "%s/userfctR", build_path);
sprintf(userfctLib_path, "%s/userfctR", build_path);
#else
strcpy(userfctLib_path, build_path);
strcpy(userfctLib_path, build_path);
#endif
}
else
{
userfctLib_path = strdup(opts->userfctLib_path);
}
else
{
userfctLib_path = strdup(opts->userfctLib_path);
}
}
}
......@@ -141,14 +144,24 @@ MbsData* mbs_load_with_loader(const char* mbs_filename, const char* build_path,
// if we call project and user function pointer, init them
#ifdef PRJ_FCT_PTR
if (!opts->no_project_fct) {
if (opts->load_symb_user!=LOAD_NONE) {
mbs_load_symbolic_functions(mbs_data, symbolicLib_path, symbolicLib_name);
}
else{
mbs_set_symb_fun_null(mbs_data);
}
if(opts->load_symb_user==LOAD_ALL) {
mbs_load_user_functions(mbs_data, userfctLib_path, userfctLib_name);
}
else {
else{
mbs_set_user_fun_null(mbs_data);
mbs_data->user_IO = NULL;
}
if (opts->load_symb_user==LOAD_NONE) {
mbs_data->build_path = NULL;
mbs_data->user_IO = NULL;
mbs_set_prj_fun_null(mbs_data);
}
#endif
......@@ -190,7 +203,7 @@ MbsLoadOptions* mbs_new_load_options()
opts->symbolicLib_path = NULL;
opts->userfctLib_name = NULL;
opts->userfctLib_path = NULL;
opts->no_project_fct = 0;
opts->load_symb_user = LOAD_ALL;
return opts;
}
......@@ -216,9 +229,22 @@ void mbs_delete_loader(MbsLoader* loader)
free(loader);
}
#ifdef PRJ_FCT_PTR
void mbs_set_prj_fun_null(MbsData *s) {
void mbs_set_symb_fun_null(MbsData *s) {
s->fct.symbolicLibHandle = NULL;
// Symbolic functions
s->fct.symb.mbs_link = NULL;
s->fct.symb.mbs_link3D = NULL;
s->fct.symb.mbs_extforces = NULL;
s->fct.symb.mbs_accelred = NULL;
s->fct.symb.mbs_dirdyna = NULL;
s->fct.symb.mbs_invdyna = NULL;
s->fct.symb.mbs_cons_hJ = NULL;
s->fct.symb.mbs_cons_jdqd = NULL;
s->fct.symb.mbs_sensor = NULL;
s->fct.symb.mbs_gensensor = NULL;
}
void mbs_set_user_fun_null(MbsData *s) {
s->fct.userfctLibHandle = NULL;
// User functions
s->fct.user.user_JointForces = NULL;
......@@ -262,17 +288,6 @@ void mbs_set_prj_fun_null(MbsData *s) {
s->fct.user.user_realtime_visu = NULL;
#endif
#endif
// Symbolic functions
s->fct.symb.mbs_link = NULL;
s->fct.symb.mbs_link3D = NULL;
s->fct.symb.mbs_extforces = NULL;
s->fct.symb.mbs_accelred = NULL;
s->fct.symb.mbs_dirdyna = NULL;
s->fct.symb.mbs_invdyna = NULL;
s->fct.symb.mbs_cons_hJ = NULL;
s->fct.symb.mbs_cons_jdqd = NULL;
s->fct.symb.mbs_sensor = NULL;
s->fct.symb.mbs_gensensor = NULL;
}
#endif
......
......@@ -11,11 +11,23 @@ typedef struct MbsLoadOptions
char *userfctLib_name;
char *userfctLib_path;
int no_project_fct;
int load_symb_user;
} MbsLoadOptions;
/** @brief Enumeration of the possible project function to load
*
* This value is compared to the 'MbsLoadOptions::load_symb_user'
* - LOAD_NONE : Do not load any project-secific function.
* - LOAD_SYMBOLIC : Only load the symbolic functions.
* - LOAD_ALL : Load the symbolic and the user functions.
*
* Default: ALL
*/
enum { LOAD_NONE, LOAD_SYMBOLIC, LOAD_ALL };
typedef struct MbsLoader
{
MbsLoadOptions *opts;
......@@ -27,9 +39,9 @@ typedef struct MbsLoader
extern "C" {
#endif
/**
* \brief Load the data from the given *.mbs file (data in the xml
* \brief Load the data from the given *.mbs file (data in the xml
format). The memory of a new MbsData is allocated.
*
*
* \param mbs_filename path to the file to load including filename and extension.
* \param build_path, path to the build folder (including build) of MBsysC libraries
*/
......@@ -42,7 +54,7 @@ MbsData* mbs_load(const char* mbs_filename, const char* build_name);
*
* \param mbs_filename, path to the file to load including filename and extension.
* \param build_path, path to the build folder (including build) of MBsysC libraries
* \param mbs_load_opts, options for loading (mainly a collection of paths and names)
* \param mbs_load_opts, options for loading (mainly a collection of paths and names)
*/
MbsData* mbs_load_with_loader(const char* mbs_filename, const char* build_path, MbsLoader *mbs_loader);
......@@ -71,17 +83,23 @@ MbsLoader* mbs_new_loader();
/**
* \brief Free the memory associated to the given MbsLoader.
*
*
*
* \param opts the MbsLoader to delete
*/
void mbs_delete_loader(MbsLoader* loader);
/**
* @brief Set the pointer to project specific functions to NULL
* @brief Set the pointer to project symbolic functions to NULL
* @param[in, out] fct the MbsData instance containing the pointer of functions
*/
void mbs_set_symb_fun_null(MbsData *s);
/**
* @brief Set the pointer to project user functions to NULL
* @param[in, out] fct the MbsData instance containing the pointer of functions
*/
void mbs_set_prj_fun_null(MbsData *s);
void mbs_set_user_fun_null(MbsData *s);
/**
* \brief Free the memory used by the given MbsData structure.
......@@ -95,7 +113,7 @@ void mbs_delete_data(MbsData *s);
#endif
/**
* \brief Load the user model data
* \brief Load the user model data
*/
void mbs_load_user_model_xml(MbsInfos* mbs_infos, UserModel* ums);
......
......@@ -13,3 +13,23 @@
* Les output vector ne sont pas chargé dans results
* Uniquement "user functions" en python
## Amelioration
* Instructions de génération du package
# Currently for loading C symb lib
## Symbolic
Seems to work fine.
Modification to to in MBsysC (MBsysTRAN):
* In `mbs_extforces` :
* __REQUIRED__ : declare and assign `Swri` (i being a number) as `double *SWri=s->SWr[i];`
* __REQUIRED__ : do not use `user_ExtForces` return value (python will not return anything, C will still return `s->SWr[i]` that you had already)
* __BONUS__ : do fields in `MbsData` structure to handle `PxF`, `RxF`, `VxF`... because converting them at each call is slow...
* Same in `mbs_link3D`
## User functions
__TO DOC__
### Load User model
UmPy variable can be simplified.
Need to be checked
......@@ -12,7 +12,7 @@ version MBsysC v1.11.2
Portable Python interface to MBsysC using Ctypes.
"""
print("WELCOME")
from .mbsysc_loader import *
from .mbsyspy import *
from .mbs_utilities import *
......
......@@ -53,8 +53,9 @@ user_DrivenJoints_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(MbsData_c), ctype
user_cons_hJ_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.POINTER(ctypes.c_double)), ctypes.POINTER(MbsData_c), ctypes.c_double)
user_cons_jdqd_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(MbsData_c), ctypes.c_double)
user_LinkForces_wrap = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.POINTER(MbsData_c), ctypes.c_double, ctypes.c_int)
user_Link3DForces_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.POINTER(ctypes.c_double)), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(MbsData_c), ctypes.c_double, ctypes.c_int)
user_ExtForces_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.POINTER(ctypes.c_double)), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(MbsData_c), ctypes.c_double, ctypes.c_int)
# Correctly working with static array: https://stackoverflow.com/questions/20752834/ctypes-initialize-array-of-arrays-and-pass-to-c-function
user_Link3DForces_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(MbsData_c), ctypes.c_double, ctypes.c_int)
user_ExtForces_wrap = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double), ctypes.POINTER(MbsData_c), ctypes.c_double, ctypes.c_int)
mbs_new_user_IO_wrap = ctypes.CFUNCTYPE(ctypes.POINTER(UserIO_c), ctypes.POINTER(UserIoInfo_c))
mbs_new_user_model_wrap = ctypes.CFUNCTYPE(ctypes.POINTER(UserModel_c))
......
......@@ -24,6 +24,7 @@ from .loadlibs import libmodules
# importing MBsysC related classes
from .forward_decl import MbsData_c
from .forward_decl import MbsSensor_c
from .forward_decl import MbsInfos_c
from .forward_decl import MbsLoader_c
from .forward_decl import MbsPart_c
......@@ -108,6 +109,16 @@ libloadXML.mbs_delete_infos.argtypes = [ctypes.POINTER(MbsInfos_c)]
libloadXML.mbs_delete_infos.restype = None
# modules
libmodules.mbs_new_sensor.argstypes = [ctypes.POINTER(MbsData_c)]
libmodules.mbs_new_sensor.restype = ctypes.POINTER(MbsSensor_c)
libmodules.allocate_sensor.argstypes = [ctypes.POINTER(MbsSensor_c), ctypes.c_int]
libmodules.allocate_sensor.restype = None
libmodules.init_sensor.argstypes = [ctypes.POINTER(MbsSensor_c), ctypes.c_int]
libmodules.init_sensor.restype = None
libmodules.mbs_new_part.argtypes =[ctypes.POINTER(MbsData_c)]
libmodules.mbs_new_part.restype = ctypes.POINTER(MbsPart_c)
......@@ -163,7 +174,6 @@ libmodules.mbs_equil_add_variable.argtypes = [ctypes.POINTER(MbsEquilOptions_c),
ctypes.c_void_p, ctypes.c_int]
libmodules.mbs_equil_add_variable.restypes = None
libmodules.mbs_new_modal.argtypes =[ctypes.POINTER(MbsData_c)]
libmodules.mbs_new_modal.restype = ctypes.POINTER(MbsModal_c)
......
......@@ -272,7 +272,7 @@ class MbsData(object):
"""
def __init__(self, name, user_path=None, symbolic_path=None):
def __init__(self, name, user_path=None, symbolic_path=None, prj_functions_c=None, prj_lib_path = None):
"""
Load a specific *.mbs file into a MbsData class instance.
......@@ -286,7 +286,42 @@ class MbsData(object):
symbolic_path : str, optionnal
The path to the folder containing the symbolic functions if the
default project structure are not used.
prj_functions_c : None or str
Option to load some of the project functions from the project C
library. Accepted values are:
- None : All project function are defined in python
- "symbolic_only" or "S" : Symbolic function comes from C library
- "symbolic_and_user" or "SU" : Symbolic and user functions come from C library
default is None
prj_lib_path : None or str
Required if 'prj_functions_c' is not None
Give the location of the folder containing "symbolicR/" and, or
"userfctR/". Each one of the subfolder have to contain the corresponding
library (ie: libProject_symbolic.so for linux).
"""
# Retrieve prj_functions_c value
if prj_functions_c is None:
self.opt_load_c = 0
if not (prj_lib_path is None):
print("Argument 'prj_lib_path' is ignored as option 'prj_functions_c' is 'None'.")
prj_lib_path = None
elif (type(prj_functions_c) is str):
if prj_functions_c == "symbolic_only" or prj_functions_c == "S":
self.opt_load_c = 1
elif prj_functions_c == "symbolic_and_user" or prj_functions_c == "SU":
self.opt_load_c = 2
else:
raise ValueError("prj_functions_c is not valid:'"+prj_functions_c+"'.")
if (prj_lib_path is None):
raise ValueError("prj_lib_path must be given if 'prj_functions_c' is set.")
if not (type(prj_lib_path) is str):
raise TypeError("prj_lib_path type must be str but it is '"+type(prj_lib_path)+"'.")
else:
prj_lib_path = os.path.abspath(prj_lib_path).encode('utf-8')
else:
raise TypeError("prj_functions_c type is not valid:'"+type(prj_functions_c)+"'.")
# Create a byte object from the string
name_c = name.encode('utf-8')
# Load the MbsInfos and keep a copy
......@@ -298,14 +333,15 @@ class MbsData(object):
loader = libloadXML.mbs_new_loader()
if __DEBUG__ : print( "DEBUG>> Loader structure created")
loader.contents.opts.contents.no_project_fct = 1
loader.contents.opts.contents.no_project_fct = self.opt_load_c
if __DEBUG__ : print( "DEBUG>> flag ignoring project function set")
loader.contents.mbs_infos = self.mbs_infos_ptr
if __DEBUG__ : print( "DEBUG>> mbs_infos assigned to loader")
# Load and retrieve MbsData structure
self.mbs_data_ptr = libloadXML.mbs_load_with_loader(name_c, None, loader)
self.mbs_data_ptr = libloadXML.mbs_load_with_loader(name_c, prj_lib_path, loader)
print(type(self.mbs_data_ptr))
if __DEBUG__ : print( "DEBUG>> MbsData loaded")
libloadXML.mbs_delete_loader(loader)
# symbolic and user function folder
......@@ -423,11 +459,13 @@ class MbsData(object):
# Loading user function
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(user_path)
if self.opt_load_c < 2:
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(user_path)
# Loading symbolic function
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symb_fct__(symbolic_path)
if self.opt_load_c < 1:
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(symbolic_path)
def __str__(self):
......@@ -528,7 +566,7 @@ class MbsData(object):
return
def __load_symb_fct__(self, symb_path=None):
def __load_symbolic_fct__(self, symb_path=None):
"""
Load all symbolic functions if all args are in MbsData instance.
......@@ -830,7 +868,6 @@ class MbsData(object):
self.user_model[name][name2] = np.array(np.ctypeslib.as_array(val_ptr, (1,size)), dtype = np.int)
else:
self.user_model[name][name2] = np.ctypeslib.as_array(val_ptr, (1,size))
#in full python project, the C memory is always a double
else :
#not yet tested, it requires user and symbolic fonctions in C
......
......@@ -151,11 +151,13 @@ class MbsDirdyn(object):
self._F = np.ctypeslib.as_array(self.mbs_dirdyn_ptr.contents.mbs_aux.contents.F, (self.mbs.njoint+1,))
# Loading user function
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
if self.mbs.opt_load_c < 2:
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
# Loading symbolic function
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
if self.mbs.opt_load_c < 1:
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
def __str__(self):
......@@ -381,15 +383,16 @@ class MbsDirdyn(object):
(5.0, 10.0)
>>> mbs_dirdyn.run()
"""
"""
# Assing required user functions
self.__assign_user_fct__()
self.mbs.__assign_user_fct__()
if self.mbs.opt_load_c < 2:
self.__assign_user_fct__()
self.mbs.__assign_user_fct__()
# Assing required symbolic functions
self.__assign_symbolic_fct__()
self.mbs.__assign_symb_fct__()
if self.mbs.opt_load_c < 1:
self.__assign_symbolic_fct__()
self.mbs.__assign_symb_fct__()
if not self.store_results:
......@@ -449,12 +452,14 @@ class MbsDirdyn(object):
libmodules.mbs_dirdyn_finish(self.mbs_dirdyn_ptr, self.mbs.mbs_data_ptr)
# Anassign user functions
self.__unassign_user_fct__()
self.mbs.__unassign_user_fct__()
if self.mbs.opt_load_c < 2:
self.__unassign_user_fct__()
self.mbs.__unassign_user_fct__()
# Anassing required symbolic functions
self.__unassign_symbolic_fct__()
self.mbs.__unassign_symb_fct__()
if self.mbs.opt_load_c < 1:
self.__unassign_symbolic_fct__()
self.mbs.__unassign_symb_fct__()
return self.results
......
......@@ -141,13 +141,14 @@ class MbsEquil(object):
self._F = np.ctypeslib.as_array(self.mbs_equil_ptr.contents.aux.contents.F, (self.mbs.njoint+1,))
self._phi = np.ctypeslib.as_array(self.mbs_equil_ptr.contents.aux.contents.phi, (self.mbs.njoint+1,))
# Loading user function
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
if self.mbs.opt_load_c < 2:
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
# Loading symbolic function
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
if self.mbs.opt_load_c < 1:
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
def __str__(self):
......@@ -377,27 +378,32 @@ class MbsEquil(object):
"""
# Assing required user functions
self.__assign_user_fct__()
self.mbs.__assign_user_fct__()
if self.mbs.opt_load_c < 2:
self.__assign_user_fct__()
self.mbs.__assign_user_fct__()
self._compute_exchange()
self._compute_extra_variable()
# Assing required symbolic functions
self.__assign_symbolic_fct__()
self.mbs.__assign_symb_fct__()
if self.mbs.opt_load_c < 1:
self.__assign_symbolic_fct__()
self.mbs.__assign_symb_fct__()
self._compute_exchange()
self._compute_extra_variable()
libmodules.mbs_run_equil(self.mbs_equil_ptr, self.mbs.mbs_data_ptr)
if self.store_results:
self.load_results()
# Anassign user functions
self.__unassign_user_fct__()
self.mbs.__unassign_user_fct__()
if self.mbs.opt_load_c < 2:
self.__unassign_user_fct__()
self.mbs.__unassign_user_fct__()
# Anassing required symbolic functions
self.__unassign_symbolic_fct__()
self.mbs.__unassign_symb_fct__()
if self.mbs.opt_load_c < 1:
self.__unassign_symbolic_fct__()
self.mbs.__unassign_symb_fct__()
return self.results
......
......@@ -132,11 +132,13 @@ class MbsInvdyn(object):
self._phi = np.ctypeslib.as_array(self.mbs_invdyn_ptr.contents.mbs_aux.contents.phi, (self.mbs.njoint+1,))
# Loading user function
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
if self.mbs.opt_load_c < 2:
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
# Loading symbolic function
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
if self.mbs.opt_load_c < 1:
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
def __str__(self):
if __DEBUG__ : print( "DEBUG>> start of __str")
......@@ -337,12 +339,14 @@ class MbsInvdyn(object):
Results are stored in the field results (if store_results == True)
"""
# Assing required user functions
self.__assign_user_fct__()
self.mbs.__assign_user_fct__()
if self.mbs.opt_load_c < 2:
self.__assign_user_fct__()
self.mbs.__assign_user_fct__()
# Assing required symbolic functions
self.__assign_symbolic_fct__()
self.mbs.__assign_symb_fct__()
if self.mbs.opt_load_c < 1:
self.__assign_symbolic_fct__()
self.mbs.__assign_symb_fct__()
if not self.store_results:
libmodules.mbs_run_invdyn(self.mbs_invdyn_ptr, self.mbs.mbs_data_ptr)
......@@ -359,12 +363,14 @@ class MbsInvdyn(object):
libmodules.mbs_invdyn_finish(self.mbs_invdyn_ptr, self.mbs.mbs_data_ptr)
# Anassign user functions
self.__unassign_user_fct__()
self.mbs.__unassign_user_fct__()
if self.mbs.opt_load_c < 2:
self.__unassign_user_fct__()
self.mbs.__unassign_user_fct__()
# Anassing required symbolic functions
self.__unassign_symbolic_fct__()
self.mbs.__unassign_symb_fct__()
if self.mbs.opt_load_c < 1:
self.__unassign_symbolic_fct__()
self.mbs.__unassign_symb_fct__()
def _load_results(self):
"""
......
......@@ -115,11 +115,13 @@ class MbsModal(object):
self._phi = np.ctypeslib.as_array(self.mbs_modal_ptr.contents.aux.contents.phi, (self.mbs.njoint+1,))
# Loading user function
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
if self.mbs.opt_load_c < 2:
if __DEBUG__ : print( "DEBUG>> Loading user functions")
self.__load_user_fct__(self.user_path)
# Loading symbolic function
if __DEBUG__ : print( "DEBUG>> Loading symbolic functions")
self.__load_symbolic_fct__(self.symbolic_path)
if self.