Commit 07d900a4 authored by Nicolas Docquier's avatar Nicolas Docquier
Browse files

Merge branch 'user_hardcoded' into 'master'

User hardcoded

Based on the files used to generate the files "user_models" and "user_all_id", I extended them to generate the header file "user_hardcoded.h" where the values not changing during the simulation (gravity, mass, com positions, inertia, dpt) are saved as define macros with the floating value saved in the .mbs file.

This is potentially relevant for issue #20 : this generates the equivalent of this [file](https://gitlab.robotran.be/robotran/mbsysc/blob/06f1bdcb1f6c65a065a509fea80e8d9cde6a26c6/MBprojects/PendulumSpringC/symbolicR/mbs_dirdyna_hard_PendulumSpringC.h)

On top of that, I wrote a [python script](https://gitlab.robotran.be/robotran/mbsysc/blob/3018ff2250a332fa560cdc25a3dd495fde58820b/MBsysC/mbs_app/hardcoded_notation.py) able to transform a file generated by the current Robotran generator into the new format able to use these hardcoded values.

I tested it on my COMAN project (on dirdyna) and could not see any difference.

However, this is the first time I play with 'MDS_gen_strct* gen', so it could be fine if somebody could carefully look at the lines I implemented before merging this file.

@averle @fisette @TimotheeHabra @lantsoght

See merge request !13
parents 561a752a efa59e30
/* --------------------------------------------------------
* This code was generated automatically by MBsysC modules.
* MBsysC modules are distributed as part of the ROBOTRAN
* software. They provides functionalities for dealing with
* symbolic equations generated by ROBOTRAN.
*
* More info on www.robotran.be
*
* Universite catholique de Louvain, Belgium
*
* Last update : Wed Sep 9 13:31:19 2015
* --------------------------------------------------------
*
*/
#ifndef USER_HARD_PARAM_h
#define USER_HARD_PARAM_h
// ============================================================ //
// gravity
#define G_3 9.81
// mass
#define M_1 5
#define M_3 2
#define M_4 2
#define M_5 2
// center of mass
#define L_3_1 0.4
#define L_3_4 0.075
#define L_1_5 0.29
// inertia
#define IN_5_1 0.1
#define IN_9_3 1
#define IN_5_4 0.1
#define IN_5_5 0.1
// body point
#define DPT_1_1 0.25
#define DPT_1_2 -0.5
#define DPT_3_3 0.5
#define DPT_3_4 0.25
#define DPT_3_5 1.5
#define DPT_3_6 0.15
#define DPT_1_7 0.58
#define DPT_1_8 0.29
// ============================================================ //
# endif
# takes two argument: the first one is an input c file generated by the old version of Robotran
# the second one is the output c file to generate
# example: python hardcoded_notation.py mbs_dirdyna_my_model.c new_mbs_dirdyna_my_model.c
import sys
# return true if it is a float
def isInt(value):
try:
int(value)
return True
except ValueError:
return False
# get line with new pattern when there is one index
def new_line_simple_index(old_line, old_pattern, new_pattern):
elem_1 = old_line.split('{}['.format(old_pattern))
new_line = elem_1[0]
if len(elem_1) > 1:
for i in range(0, len(elem_1)):
elem_2 = elem_1[i].split(']')
if len(elem_2) > 1:
if isInt(elem_2[0]):
ind = int(elem_2[0])
new_line = '{}{}_{}{}'.format(new_line, new_pattern, ind, elem_2[1])
for j in range(2, len(elem_2)):
new_line = '{}]{}'.format(new_line, elem_2[j])
return new_line
# get line with new pattern when there are two indexes
def new_line_double_index(old_line, old_pattern, new_pattern):
elem_1 = old_line.split('{}['.format(old_pattern))
new_line = elem_1[0]
if len(elem_1) > 1:
for i in range(0, len(elem_1)):
elem_2 = elem_1[i].split('][')
if len(elem_2) > 1:
if isInt(elem_2[0]):
ind_1 = int(elem_2[0])
new_line = '{}{}_{}_'.format(new_line, new_pattern, ind_1)
elem_3 = elem_2[1].split(']')
if len(elem_3) > 1:
if isInt(elem_3[0]):
ind_2 = int(elem_3[0])
new_line = '{}{}{}'.format(new_line, ind_2, elem_3[1])
for j in range(2, len(elem_3)):
new_line = '{}]{}'.format(new_line, elem_3[j])
for j in range(2, len(elem_2)):
new_line = '{}][{}'.format(new_line, elem_2[j])
return new_line
# generate output file
def gen_out_file(in_file, out_file):
out_write = open(out_file,'w')
with open(in_file,'r') as f:
# loop on all the lines
for line in f:
new_line = new_line_simple_index(line, 's->g', 'G')
new_line = new_line_simple_index(new_line, 's->m', 'M')
new_line = new_line_double_index(new_line, 's->l', 'L')
new_line = new_line_double_index(new_line, 's->In', 'IN')
new_line = new_line_double_index(new_line, 's->dpt', 'DPT')
new_line = new_line.replace('s->frc','frc')
new_line = new_line.replace('s->trq','trq')
new_line = new_line.replace('#include "mbs_project_interface.h"', '#include "mbs_project_interface.h"\n#include "user_hard_param.h"')
new_line = new_line.replace('#define q s->q', '\ndouble *q = s->q;')
new_line = new_line.replace('#define qd s->qd', 'double *qd = s->qd;')
new_line = new_line.replace('#define qdd s->qdd','double *qdd = s->qdd;\n\ndouble **frc = s->frc;\ndouble **trq = s->trq;')
# write line
out_write.write(new_line)
out_write.close()
# main
if len(sys.argv) == 3:
in_file = sys.argv[1]
out_file = sys.argv[2]
gen_out_file(in_file, out_file)
......@@ -40,7 +40,7 @@ xml_lib()
# function to list all source files in the src/ directory,
# recursing into sub-directories
function(list_gen_source_files HEADER_FILES)
function(list_gen_source_files)
file(GLOB_RECURSE SOURCE_FILES_TMP
"${PROJECT_SOURCE_DIR}/src/*.c"
"${ROBOTRAN_SOURCE_DIR}/mbs_common/mbs_load_xml/mbs_xml_reader.c"
......@@ -50,7 +50,7 @@ endfunction()
# function to list all paths to header files in the src/ directory,
# recursing into sub-directories (includes)
function(list_gen_include_directories FULL_INCLUDE_DIRECTORIES)
function(list_gen_include_directories)
file(GLOB_RECURSE FULL_INCLUDE_DIRECTORIES_TMP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
"${PROJECT_SOURCE_DIR}/src/*.h"
"${ROBOTRAN_SOURCE_DIR}/mbs_common/mbs_load_xml/mbs_xml_reader.h"
......
......@@ -38,5 +38,6 @@ make
specifying which file must be generated:
* "user_models": user model files
* "user_all_id": id header file
* "all": both of the previous option (this is the default option
* "user_hard_param": hardcoded mbs values header file
* "all": all previous options (this is the default option
if the options is omitted)
......@@ -163,6 +163,32 @@ void generate_user_all_id(char* mbsfile)
}
/*! \brief Generates 'user_hard_param.h'
*
* \param[in] mbsfile f.mbs file (with path) to use
*/
void generate_user_hard_param(char* mbsfile)
{
// variables declaration
char *fileoutH, *userpath;
//struct stat mbs_stat, outH_stat;
userpath = find_user_path(mbsfile);
MDS_gen_strct* gen;
gen = NULL;
// files initialization
fileoutH = (char*) malloc(sizeof(char)*(strlen(userpath)+50));
sprintf(fileoutH, "%suser_hard_param.h", userpath);
gen = MDS_mbs_reader(mbsfile);
mbs_print_user_hard_param(gen, fileoutH);
free_MDS_gen_strct(gen);
free(fileoutH);
free(userpath);
}
/**
*
......@@ -203,6 +229,7 @@ int main(int argc, char *argv[])
{
generate_user_models(mbsFile);
generate_user_all_id(mbsFile);
generate_user_hard_param(mbsFile);
}
else if ( !strcmp(argv[2], "user_models") )
{
......@@ -212,10 +239,14 @@ int main(int argc, char *argv[])
{
generate_user_all_id(mbsFile);
}
else if ( !strcmp(argv[2], "user_hard_param") )
{
generate_user_hard_param(mbsFile);
}
else
{
printf("Error: %s is not a good argument !\n", argv[2]);
printf("Arguments accepted: 'user_models' and 'user_all_id' (without '')\n");
printf("Arguments accepted: 'all', 'user_models', 'user_all_id' and 'user_hard_param' (without '')\n");
}
}
return 0;
......
/*
* Functions used to generate 'user_models.c' 'user_models.h'
* Functions used to generate 'user_models.c', 'user_models.h', 'user_all_id.h' and 'user_hard_param.h'
*
* author: Aubain VERLE, Nicolas Docquier
* author: Aubain VERLE, Nicolas Docquier, Nicolas Van der Noot
*
* (c) Universite catholique de Louvain
*
......@@ -388,3 +388,149 @@ void mbs_print_user_all_id(MDS_gen_strct* gen, char *fileoutH)
printf(">> 'user_all_id.h' created\n");
}
int get_index_parent_joint(MDS_body_strct *body, MDS_bodytree_strct *bodytree)
{
int i;
char *joint_name;
joint_name = body->joint_list[body->n_joint-1]->name;
for(i=0; i< bodytree->n_joint; i++)
{
if (!strcmp(bodytree->joint_list[i]->name ,joint_name))
{
return i+1;
}
}
printf("Error: unknown joint %s !\n", joint_name);
return 0;
}
/*! \brief print the 'user_hard_param.h' file
*
* \param[in] gen MDS generated structure (from the .mbs file)
* \param[in] fileoutH file to create
*/
void mbs_print_user_hard_param(MDS_gen_strct* gen, char *fileoutH)
{
int i, j, k;
int ind;
int cur_index;
FILE *fidH;
MDS_bodytree_strct *bodytree;
MDS_body_strct *cur_body;
MDS_point_strct *cur_point;
int inertia_tab[6] = {1, 2, 3, 5, 6, 9};
// File declaration
fidH = NULL; // internal filename
// Opening file
fidH = fopen(fileoutH, "wt");
// Fill the file
if(fidH == NULL)
{
printf("error: cannot open file '%s'\n", fileoutH);
exit(1);
}
bodytree = gen->bodytree;
// -- user_hard_param.h -- //
// print the generic header
mbs_print_header(fidH);
fprintf(fidH,"#ifndef USER_HARD_PARAM_h\n");
fprintf(fidH,"#define USER_HARD_PARAM_h\n");
fprintf(fidH,"\n");
fprintf(fidH,"// ============================================================ //\n\n");
fprintf(fidH,"\n");
// gravity
fprintf(fidH,"// gravity\n");
for(i=0; i<3; i++)
{
if (gen->base->gravity[i])
{
fprintf(fidH,"#define G_%d %g\n", i+1, gen->base->gravity[i]);
}
}
fprintf(fidH,"\n");
// mass
fprintf(fidH,"// mass\n");
for(i=0; i<bodytree->n_body; i++)
{
cur_body = bodytree->body_list[i];
cur_index = get_index_parent_joint(cur_body, bodytree);
if (cur_body->mass)
{
fprintf(fidH,"#define M_%d %g\n", cur_index, cur_body->mass);
}
}
fprintf(fidH,"\n");
// com
fprintf(fidH,"// center of mass\n");
for(i=0; i<bodytree->n_body; i++)
{
cur_body = bodytree->body_list[i];
cur_index = get_index_parent_joint(cur_body, bodytree);
//x y z
for(j=0; j<3; j++)
{
if (cur_body->com[j])
{
fprintf(fidH,"#define L_%d_%d %g\n", j+1, cur_index, cur_body->com[j]);
}
}
}
fprintf(fidH,"\n");
// inertia
fprintf(fidH,"// inertia\n");
for(i=0; i<bodytree->n_body; i++)
{
cur_body = bodytree->body_list[i];
cur_index = get_index_parent_joint(cur_body, bodytree);
// Ixx Ixy Ixz Iyy Iyz Izz
for(j=0; j<6; j++)
{
if (cur_body->inertia[j])
{
fprintf(fidH,"#define IN_%d_%d %g\n", inertia_tab[j], cur_index, cur_body->inertia[j]);
}
}
}
fprintf(fidH,"\n");
// body point
fprintf(fidH,"// body point\n");
for(i=0; i< gen->n_point; i++)
{
cur_point = gen->point_list[i];
for(j=0; j<3; j++)
{
if (cur_point->pt[j])
{
fprintf(fidH,"#define DPT_%d_%d %g\n", j+1, i+1, cur_point->pt[j]);
}
}
}
fprintf(fidH,"\n");
fprintf(fidH,"// ============================================================ //\n\n");
fprintf(fidH,"# endif""\n");
fclose(fidH);
printf(">> 'user_hard_param.h' created\n");
}
......@@ -16,3 +16,5 @@ void print_empty_file(char *fileout);
void mbs_print_user_models(MDS_gen_strct* gen, char *fileoutC, char *fileoutH);
void mbs_print_user_all_id(MDS_gen_strct* gen, char *fileoutH);
void mbs_print_user_hard_param(MDS_gen_strct* gen, char *fileoutH);
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