Commit a507d6d2 authored by Nicolas Docquier's avatar Nicolas Docquier
Browse files

Add functions for dynamic loading at run time of symbolic and user functions

parent 37bc005b
This folder is used to copy the content of the Robotran/MBsysC folder.
This can be used to run a Standalone version of Robotran (with C code), anywhere, for instance on an external cluster.
This folder is used to let the user add his personal files.
In comparison, _userfctR_ is used for the generic Robotran files that the user can modify.
......@@ -27,9 +27,11 @@ increment_src( ${PROJECT_SOURCE_DIR} )
init_include()
set(INCLUDE_DIR ${INCLUDE_DIR} ${PROJECT_SOURCE_DIR} PARENT_SCOPE)
find_package( LibRobotranC REQUIRED )
include (GenerateExportHeader)
add_library(Project_userfct ${SOURCE_FILES} ${INCLUDE_DIR})
target_link_libraries (Project_userfct MBsysC_realtime)
add_library(Project_userfct SHARED ${SOURCE_FILES} ${INCLUDE_DIR})
target_link_libraries (Project_userfct ${LIB_MBSYSC_REALTIME} ${LIB_MBSYSC_UTILITIES})
GENERATE_EXPORT_HEADER( Project_userfct )
include_directories(${CMAKE_CURRENT_BINARY_DIR})
......@@ -48,4 +50,4 @@ if (FLAG_PLOT)
sdl_header_lib(userfct)
include_directories(${ROBOTRAN_SOURCE_DIR}/mbs_common/mbs_realtime/sdl)
include_directories(${ROBOTRAN_SOURCE_DIR}/mbs_common/mbs_realtime/sdl/auto_plot)
endif ( )
\ No newline at end of file
endif ( )
......@@ -112,7 +112,7 @@ init_src()
increment_src( ${PROJECT_SOURCE_DIR}/src )
#increment_src( ${PROJECT_SOURCE_DIR}/../userfctR )
#add_subdirectory( ${PROJECT_SOURCE_DIR}/../userfctR ${CMAKE_CURRENT_BINARY_DIR}/userfctR)
add_subdirectory( ${PROJECT_SOURCE_DIR}/../userfctR ${CMAKE_CURRENT_BINARY_DIR}/userfctR)
if (NOT FLAG_SEPARATE_SYMBOLIC)
#increment_src( ${PROJECT_SOURCE_DIR}/../symbolicR )
......
......@@ -93,9 +93,16 @@ int main(int argc, char const *argv[])
#include "user_realtime.h"
//void mbs_load_user_functions(MbsData* mbs_data);
//void mbs_load_symbolic_functions(MbsData* mbs_data);
void mbs_get_project_functions(MbsData *mbs_data)
{
#ifdef UNIX
/* #ifdef UNIX
void *lib_handle;
char *error;
......@@ -112,7 +119,7 @@ void mbs_get_project_functions(MbsData *mbs_data)
printf("symbolic DLL Failed To Load!\n");
//exit(1);
}
#endif
#endif*/
// user function pointers
/* mbs_data->user_JointForces = user_JointForces;
......@@ -148,7 +155,7 @@ void mbs_get_project_functions(MbsData *mbs_data)
//mbs_data->mbs_dirdyna = mbs_dirdyna;
//mbs_data->mbs_cons_hJ = mbs_cons_hJ;
//mbs_data->mbs_cons_jdqd = mbs_cons_jdqd;
/*
#ifdef UNIX
mbs_data->fct.symb.mbs_link = dlsym(lib_handle, "mbs_link");
mbs_data->fct.symb.mbs_link3D = dlsym(lib_handle, "mbs_link3D");
......@@ -174,7 +181,7 @@ void mbs_get_project_functions(MbsData *mbs_data)
mbs_data->mbs_cons_hJ = (mbs_cons_hJ_ptr)GetProcAddress(hInstLibrary, "mbs_cons_hJ");
mbs_data->mbs_cons_jdqd = (mbs_cons_jdqd_ptr)GetProcAddress(hInstLibrary, "mbs_cons_jdqd");
#endif
#endif*/
}
......@@ -2,18 +2,177 @@
#include "mbs_load_xml.h"
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void mbs_load_user_functions(MbsData* mbs_data);
void mbs_load_symbolic_functions(MbsData* mbs_data);
#ifdef UNIX
#include <dlfcn.h> // linux function to dynamically load libraries
#else
#include <windows.h>
#endif
typedef struct{
#ifdef UNIX
void *lib_handle;
#else
HINSTANCE lib_handle;
#endif
}MbsDataLibInfo;
MbsDataLibInfo* mbs_load_dynamic_library(char* libpath){
MbsDataLibInfo* li = (MbsDataLibInfo*)malloc(sizeof(MbsDataLibInfo)) ;
#ifdef UNIX
char *error;
// note : no need to call dlclose(), the library will be automatically closed at the end of the execution
li->lib_handle = dlopen(libpath, RTLD_LAZY);
if (!li->lib_handle)
{
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
#else
li->lib_handle = LoadLibrary(libpath);
if(!li->lib_handle)
{
printf("symbolic DLL Failed To Load!\n");
//exit(1);
}
#endif
return li;
}
#ifdef UNIX
void* mbs_load_function(MbsDataLibInfo* li, char* fct_name){
char *error;
void* fct;
fct = dlsym(li->lib_handle, fct_name);
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "Error loading %s: %s\n", fct_name, error);
exit(1);
}
return fct;
}
#else
FARPROC WINAPI mbs_load_function(MbsDataLibInfo* li, char* fct_name){
return li->GetProcAddress(hInstLibrary, "mbs_link");
}
#endif
void mbs_load_symbolic_functions(MbsData* mbs_data){
char* lib_path;
#ifdef UNIX
lib_path = "/home/ndocquier/Documents/MBsysC_WinDll/MBprojects/PendulumSpringC/workR/build/symbolicR/libproject_symbolic.so";
#else
lib_path = "\\build\\symbolicR\\Debug\\project_symbolic.dll";
#endif
MbsDataLibInfo* symbLibInfo = mbs_load_dynamic_library(lib_path) ;
mbs_data->fct.symb.mbs_link = (mbs_link_ptr) mbs_load_function(symbLibInfo, "mbs_link");
mbs_data->fct.symb.mbs_link3D = (mbs_link3D_ptr) mbs_load_function(symbLibInfo, "mbs_link3D");
mbs_data->fct.symb.mbs_extforces = (mbs_extforces_ptr)mbs_load_function(symbLibInfo, "mbs_extforces");
mbs_data->fct.symb.mbs_accelred = (mbs_accelred_ptr) mbs_load_function(symbLibInfo, "mbs_accelred");
mbs_data->fct.symb.mbs_dirdyna = (mbs_dirdyna_ptr) mbs_load_function(symbLibInfo, "mbs_dirdyna");
mbs_data->fct.symb.mbs_cons_hJ = (mbs_cons_hJ_ptr) mbs_load_function(symbLibInfo, "mbs_cons_hJ");
mbs_data->fct.symb.mbs_cons_jdqd = (mbs_cons_jdqd_ptr)mbs_load_function(symbLibInfo, "mbs_cons_jdqd");
free(symbLibInfo);
}
void mbs_load_user_functions(MbsData* mbs_data){
char* lib_path;
#ifdef UNIX
lib_path = "/home/ndocquier/Documents/MBsysC_WinDll/MBprojects/PendulumSpringC/workR/build/userfctR/libProject_userfct.so";
#else
lib_path = "\\build\\symbolicR\\Debug\\project_userfct.dll";
#endif
MbsDataLibInfo* userLibInfo = mbs_load_dynamic_library(lib_path) ;
mbs_data->fct.user.user_JointForces = (user_JointForces_ptr) mbs_load_function(userLibInfo, "user_JointForces");
mbs_data->fct.user.user_init = (user_init_ptr) mbs_load_function(userLibInfo, "user_init");
mbs_data->fct.user.user_loop = (user_loop_ptr) mbs_load_function(userLibInfo, "user_loop");
mbs_data->fct.user.user_finish = (user_finish_ptr) mbs_load_function(userLibInfo, "user_finish");
mbs_data->fct.user.user_Derivative = (user_Derivative_ptr) mbs_load_function(userLibInfo, "user_Derivative");
mbs_data->fct.user.user_DrivenJoints = (user_DrivenJoints_ptr) mbs_load_function(userLibInfo, "user_DrivenJoints");
mbs_data->fct.user.user_cons_hJ = (user_cons_hJ_ptr) mbs_load_function(userLibInfo, "user_cons_hJ");
mbs_data->fct.user.user_cons_jdqd = (user_cons_jdqd_ptr) mbs_load_function(userLibInfo, "user_cons_jdqd");
mbs_data->fct.user.user_LinkForces = (user_LinkForces_ptr) mbs_load_function(userLibInfo, "user_LinkForces");
mbs_data->fct.user.mbs_new_user_IO = (mbs_new_user_IO_ptr) mbs_load_function(userLibInfo, "mbs_new_user_IO");
mbs_data->fct.user.mbs_new_user_model = (mbs_new_user_model_ptr) mbs_load_function(userLibInfo, "mbs_new_user_model");
mbs_data->fct.user.mbs_delete_user_model = (mbs_delete_user_model_ptr) mbs_load_function(userLibInfo, "mbs_delete_user_model");
mbs_data->fct.user.mbs_delete_user_IO = (mbs_delete_user_IO_ptr) mbs_load_function(userLibInfo, "mbs_delete_user_IO");
mbs_data->fct.user.mbs_load_user_model_xml = (mbs_load_user_model_xml_ptr) mbs_load_function(userLibInfo, "mbs_load_user_model_xml");
#ifdef REAL_TIME
mbs_data->fct.user.user_realtime_options = (user_realtime_options_ptr) mbs_load_function(userLibInfo, "user_realtime_options");
#ifdef SDL
mbs_data->fct.user.user_keyboard = (user_keyboard_ptr) mbs_load_function(userLibInfo, "user_keyboard");
mbs_data->fct.user.user_realtime_plot = (user_realtime_plot_ptr) mbs_load_function(userLibInfo, "user_realtime_plot");
mbs_data->fct.user.user_joystick_axes = (user_joystick_axes_ptr) mbs_load_function(userLibInfo, "user_joystick_axes");
mbs_data->fct.user.user_joystick_buttons = (user_joystick_buttons_ptr) mbs_load_function(userLibInfo, "user_joystick_buttons");
#endif
#ifdef JAVA
mbs_data->fct.user.user_realtime_visu = (user_realtime_visu_ptr) mbs_load_function(userLibInfo, "user_realtime_visu");
#endif
#endif
free(userLibInfo);
}
MbsData* mbs_load(const char* mbs_filename){
MDS_gen_strct *mds;
MbsData *mbs_data;
MbsData *mbs_data;
mds = MDS_mbs_reader(mbs_filename);
mbs_data = (MbsData*) malloc(sizeof(MbsData));
mbs_load_symbolic_functions(mbs_data);
mbs_load_user_functions(mbs_data);
mbs_data = MDS_create_MBSdataStruct(mds, mbs_data);
mds = MDS_mbs_reader(mbs_filename);
mbs_data = MDS_create_MBSdataStruct(mds);
free_MDS_gen_strct(mds);
mbs_data->mbs_filename = (char*) malloc (1+strlen(mbs_filename));
strcpy(mbs_data->mbs_filename, mbs_filename);
return mbs_data;
}
......@@ -41,15 +200,13 @@ MbsData* mbs_load(const char* mbs_filename){
return q_MBSdataStruct;
}
MbsData* MDS_create_MBSdataStruct(MDS_gen_strct* mds_gen_strct)
MbsData* MDS_create_MBSdataStruct(MDS_gen_strct* mds_gen_strct, MbsData* s)
{
int i,j;
int ind_joint = 0;
int ind_state_value = 0;
MbsData *s;
s = (MbsData*) malloc(sizeof(MbsData));
s->nbody = mds_gen_strct->bodytree->n_joint;
s->njoint = mds_gen_strct->bodytree->n_joint;
......
......@@ -8,18 +8,18 @@
#include "mbsysc_loadxml_export.h"
/**
* Load the data from the given *.mbs file (data in the xml
* format). The memory of a new MbsData is allocated.
* Load the data from the given *.mbs file (data in the xml
* format). The memory of a new MbsData is allocated.
*/
MBSYSC_LOADXML_EXPORT MbsData* mbs_load(const char* mbs_filename);
/**
* Load the user model data
* Load the user model data
*/
void mbs_load_user_model_xml(MDS_gen_strct* gen, UserModel* ums);
/**
* Free the memory used by the given MbsData structure.
*/
......@@ -29,7 +29,7 @@ MBSYSC_LOADXML_EXPORT void mbs_delete_data(MbsData *s);
/**
* Retrieve a MbsData structure from the given MDS_gen_strct
*/
MbsData* MDS_create_MBSdataStruct(MDS_gen_strct* mds_gen_strct);
MbsData* MDS_create_MBSdataStruct(MDS_gen_strct* mds_gen_strct, MbsData* s);
#endif
\ No newline at end of file
#endif
......@@ -82,7 +82,7 @@ if (FLAG_VISU)
endif ( )
# include directories
#include_directories("./")
include_directories("./")
include_directories("./sdl" "./sdl/auto_plot")
include_directories("./realtime")
include_directories("../mbs_struct")
......
......@@ -3,6 +3,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Those utility functions should be move elsewhere
// We should use function of useful_functions. h but signature is not the same ... we need to merge that all!
......
# TO DO FOR THIS BRANCH
* mbs_load_symbolic: utiliser le bon mbs_path depuis la structure mbs_data
* mbs_load_function: ajouter message d'erreur si mauvais chargement de fct en windows
New Robotran Project
====================
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment