00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #include <acado/utils/acado_types.hpp>
00034 #include <acado/utils/acado_constants.hpp>
00035 #include <acado/utils/acado_io_utils.hpp>
00036 #include <acado/code_generation/templates/templates.hpp>
00037
00038 #if defined( __WIN32__ ) || defined( WIN32 )
00039
00040 #include <windows.h>
00041 #include <direct.h>
00042
00043 #elif defined( LINUX )
00044
00045 #include <sys/stat.h>
00046 #include <sys/time.h>
00047 #include <sys/types.h>
00048 #include <unistd.h>
00049
00050 #else
00051
00052 #warning "File I/O is not supported on this platform"
00053
00054 #endif
00055
00056 using namespace std;
00057
00058 BEGIN_NAMESPACE_ACADO
00059
00060 #define AUTOGEN_NOTICE_LENGTH 23
00061 static const char* autogenerationNotice[ AUTOGEN_NOTICE_LENGTH ] =
00062 {
00063 "This file was auto-generated by ACADO Code Generation Tool.\n",
00064 "\n",
00065 "ACADO Code Generation tool is a sub-package of ACADO toolkit --\n",
00066 "A Toolkit for Automatic Control and Dynamic Optimization.\n",
00067 "Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,\n",
00068 "Milan Vukov, Rien Quirynen, KU Leuven.\n",
00069 "Developed within the Optimization in Engineering Center (OPTEC)\n",
00070 "under supervision of Moritz Diehl. All rights reserved.\n",
00071 "\n",
00072 "ACADO Toolkit is free software; you can redistribute it and/or\n",
00073 "modify it under the terms of the GNU Lesser General Public\n",
00074 "License as published by the Free Software Foundation; either\n",
00075 "version 3 of the License, or (at your option) any later version.\n",
00076 "\n",
00077 "ACADO Toolkit is distributed in the hope that it will be useful,\n",
00078 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n",
00079 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n",
00080 "Lesser General Public License for more details.\n",
00081 "\n",
00082 "You should have received a copy of the GNU Lesser General Public\n",
00083 "License along with ACADO Toolkit; if not, write to the Free Software\n",
00084 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00085 "\n"
00086 };
00087
00088 static uint getStringLength(const char* string)
00089 {
00090 if (string != 0)
00091 return strlen(string);
00092
00093 return 0;
00094 }
00095
00096 returnValue getGlobalStringDefinitions( PrintScheme _printScheme,
00097 char** _startString,
00098 char** _endString,
00099 uint& _width,
00100 uint& _precision,
00101 char** _colSeparator,
00102 char** _rowSeparator
00103 )
00104 {
00105 switch (_printScheme) {
00106 case PS_DEFAULT:
00107
00108 *_startString = new char[getStringLength(DEFAULT_START_STRING) + 1];
00109 strcpy(*_startString, DEFAULT_START_STRING);
00110
00111 *_endString = new char[getStringLength(DEFAULT_END_STRING) + 1];
00112 strcpy(*_endString, DEFAULT_END_STRING);
00113
00114 _width = DEFAULT_WIDTH;
00115 _precision = DEFAULT_PRECISION;
00116
00117 *_colSeparator = new char[getStringLength(DEFAULT_COL_SEPARATOR) + 1];
00118 strcpy(*_colSeparator, DEFAULT_COL_SEPARATOR);
00119
00120 *_rowSeparator = new char[getStringLength(DEFAULT_ROW_SEPARATOR) + 1];
00121 strcpy(*_rowSeparator, DEFAULT_ROW_SEPARATOR);
00122
00123 break;
00124
00125 case PS_PLAIN:
00126
00127 *_startString = new char[1];
00128 (*_startString)[0] = '\0';
00129
00130 *_endString = new char[2];
00131 (*_endString)[0] = '\n';
00132 (*_endString)[1] = '\0';
00133
00134 _width = DEFAULT_WIDTH;
00135 _precision = DEFAULT_PRECISION;
00136
00137 *_colSeparator = new char[2];
00138 (*_colSeparator)[0] = ' ';
00139 (*_colSeparator)[1] = '\0';
00140
00141 *_rowSeparator = new char[2];
00142 (*_rowSeparator)[0] = '\n';
00143 (*_rowSeparator)[1] = '\0';
00144
00145 break;
00146
00147 case PS_MATLAB:
00148 case PS_MATLAB_BINARY:
00149
00150 *_startString = new char[3];
00151 (*_startString)[0] = '[';
00152 (*_startString)[1] = ' ';
00153 (*_startString)[2] = '\0';
00154
00155 *_endString = new char[5];
00156 (*_endString)[0] = ' ';
00157 (*_endString)[1] = ']';
00158 (*_endString)[2] = ';';
00159 (*_endString)[3] = '\n';
00160 (*_endString)[4] = '\0';
00161
00162 _width = DEFAULT_WIDTH;
00163 _precision = DEFAULT_PRECISION;
00164
00165 *_colSeparator = new char[3];
00166 (*_colSeparator)[0] = ',';
00167 (*_colSeparator)[1] = ' ';
00168 (*_colSeparator)[2] = '\0';
00169
00170 *_rowSeparator = new char[3];
00171 (*_rowSeparator)[0] = ';';
00172 (*_rowSeparator)[1] = '\n';
00173 (*_rowSeparator)[2] = '\0';
00174
00175 break;
00176
00177 default:
00178 return ACADOERROR( RET_UNKNOWN_BUG );
00179 }
00180
00181 return SUCCESSFUL_RETURN;
00182 }
00183
00184 returnValue acadoCopyFile( const std::string& source,
00185 const std::string& destination,
00186 const std::string& commentString,
00187 bool printCodegenNotice
00188 )
00189 {
00190 std::ifstream src( source.c_str() );
00191 if (src.is_open() == false)
00192 {
00193 LOG( LVL_ERROR ) << "Could not open the source file: " << source << std::endl;
00194 return ACADOERROR( RET_INVALID_ARGUMENTS );
00195 }
00196
00197 std::ofstream dst( destination.c_str() );
00198 if (dst.is_open() == false)
00199 {
00200 LOG( LVL_ERROR ) << "Could not open the destination file: " << destination << std::endl;
00201 return ACADOERROR( RET_INVALID_ARGUMENTS );
00202 }
00203
00204 if (printCodegenNotice == BT_TRUE)
00205 {
00206 if (commentString.empty())
00207 {
00208 dst << "/*" << endl;
00209 for (unsigned i = 0; i < AUTOGEN_NOTICE_LENGTH; ++i)
00210 dst << " * " << autogenerationNotice[ i ];
00211 dst << " */" << endl << endl;
00212 }
00213 else
00214 {
00215 dst << commentString << endl;
00216 for (unsigned i = 0; i < AUTOGEN_NOTICE_LENGTH; ++i)
00217 dst << commentString << " " << autogenerationNotice[ i ];
00218 dst << endl;
00219 }
00220 }
00221
00222 dst << src.rdbuf();
00223
00224 src.close();
00225 dst.close();
00226
00227 return SUCCESSFUL_RETURN;
00228 }
00229
00230 returnValue acadoCopyTemplateFile( const std::string& source,
00231 const std::string& destination,
00232 const std::string& commentString,
00233 bool printCodegenNotice
00234 )
00235 {
00236 const string folders( TEMPLATE_PATHS );
00237 ifstream inputFile;
00238 size_t oldPos = 0;
00239
00240 while( 1 )
00241 {
00242 size_t pos;
00243 string tmp;
00244
00245 pos = folders.find(";", oldPos);
00246 tmp = folders.substr(oldPos, pos) + "/" + source;
00247
00248 inputFile.open(tmp.c_str());
00249
00250 if (inputFile.is_open() == true)
00251 return acadoCopyFile(tmp, destination, commentString, printCodegenNotice);
00252
00253 if (pos == string::npos)
00254 break;
00255
00256 oldPos = pos + 1;
00257 }
00258
00259 LOG( LVL_ERROR ) << "Could not open the template file: " << source << std::endl;
00260 return ACADOERROR( RET_INVALID_ARGUMENTS );
00261 }
00262
00263 returnValue acadoCreateFolder( const std::string& name
00264 )
00265 {
00266 #if defined( __WIN32__ ) || defined( WIN32 )
00267
00268 int status = _mkdir( name.c_str() );
00269 errno_t err;
00270 _get_errno( &err );
00271 if (status && err != EEXIST)
00272 {
00273 LOG( LVL_ERROR ) << "Problem creating directory " << name << endl;
00274 return ACADOERROR( RET_INVALID_ARGUMENTS );
00275 }
00276
00277 #elif defined( LINUX )
00278
00279 struct stat st = {0};
00280
00281 if (stat(name.c_str(), &st) == -1)
00282 {
00283 if (mkdir(name.c_str(), 0700) == -1)
00284 {
00285
00286 LOG( LVL_ERROR ) << "Problem creating directory " << name << endl;
00287 return ACADOERROR( RET_INVALID_ARGUMENTS );
00288 }
00289 }
00290
00291 #else
00292
00293 return ACADOERRORTEXT(RET_INVALID_OPTION, "Unsupported platform.");
00294
00295 #endif
00296
00297 return SUCCESSFUL_RETURN;
00298 }
00299
00300
00301
00302
00303 returnValue acadoPrintCopyrightNotice( const std::string& subpackage
00304 )
00305 {
00306 if (subpackage.empty())
00307 cout << "\nACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.\n" \
00308 "Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,\n" \
00309 "Milan Vukov, Rien Quirynen, KU Leuven.\n" \
00310 "Developed within the Optimization in Engineering Center (OPTEC)\n" \
00311 "under supervision of Moritz Diehl. All rights reserved.\n\n" \
00312 "ACADO Toolkit is distributed under the terms of the GNU Lesser\n" \
00313 "General Public License 3 in the hope that it will be useful,\n" \
00314 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
00315 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \
00316 "GNU Lesser General Public License for more details.\n\n";
00317 else
00318 cout << "\nACADO Toolkit::" << subpackage << endl
00319 << "Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,\n" \
00320 "Milan Vukov, Rien Quirynen, KU Leuven.\n" \
00321 "Developed within the Optimization in Engineering Center (OPTEC)\n" \
00322 "under supervision of Moritz Diehl. All rights reserved.\n\n" \
00323 "ACADO Toolkit is distributed under the terms of the GNU Lesser\n" \
00324 "General Public License 3 in the hope that it will be useful,\n" \
00325 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
00326 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \
00327 "GNU Lesser General Public License for more details.\n\n";
00328
00329 return SUCCESSFUL_RETURN;
00330 }
00331
00332
00333 returnValue acadoPrintAutoGenerationNotice( std::ofstream& stream,
00334 const std::string& commentString
00335 )
00336 {
00337 if (stream.is_open() == false)
00338 return RET_INVALID_ARGUMENTS;
00339
00340 if (commentString.empty())
00341 {
00342 stream << "/*\n";
00343 for (unsigned i = 0; i < AUTOGEN_NOTICE_LENGTH; ++i)
00344 stream << " * " << autogenerationNotice[ i ];
00345 stream << " */\n";
00346 }
00347 else
00348 {
00349 stream << commentString << endl;
00350 for (unsigned i = 0; i < AUTOGEN_NOTICE_LENGTH; ++i)
00351 stream << commentString << " " << autogenerationNotice[ i ];
00352 }
00353
00354 stream << endl << endl;
00355
00356 return SUCCESSFUL_RETURN;
00357 }
00358
00359
00360
00361
00362
00363
00364 double acadoGetTime( )
00365 {
00366 double current_time = 0.0;
00367
00368 #if defined(__WIN32__) || defined(WIN32)
00369 LARGE_INTEGER counter, frequency;
00370 QueryPerformanceFrequency(&frequency);
00371 QueryPerformanceCounter(&counter);
00372 current_time = ((double) counter.QuadPart) / ((double) frequency.QuadPart);
00373 #elif defined(LINUX)
00374 struct timeval theclock;
00375 gettimeofday( &theclock,0 );
00376 current_time = 1.0*theclock.tv_sec + 1.0e-6*theclock.tv_usec;
00377 #endif
00378
00379 return current_time;
00380 }
00381
00382 CLOSE_NAMESPACE_ACADO
00383
00384
00385
00386