| 382 | } |
| 383 | |
| 384 | int codegen_example(const char* output_dir, int verbose) { |
| 385 | char example_cpp_fname[PATH_LENGTH]; |
| 386 | FILE *example_cpp_f; |
| 387 | |
| 388 | sprintf(example_cpp_fname, "%s/src/tiny_main.cpp", output_dir); |
| 389 | |
| 390 | // Open example file |
| 391 | example_cpp_f = fopen(example_cpp_fname, "w+"); |
| 392 | if (example_cpp_f == NULL) |
| 393 | ERROR_MSG(EXIT_FAILURE, "Failed to open file %s", example_cpp_fname); |
| 394 | |
| 395 | // Preamble |
| 396 | time_t start_time; |
| 397 | time(&start_time); |
| 398 | fprintf(example_cpp_f, "/*\n"); |
| 399 | fprintf(example_cpp_f, " * This file was autogenerated by TinyMPC on %s", ctime(&start_time)); |
| 400 | fprintf(example_cpp_f, " */\n\n"); |
| 401 | |
| 402 | fprintf(example_cpp_f, "#include <iostream>\n\n"); |
| 403 | |
| 404 | fprintf(example_cpp_f, "#include <tinympc/tiny_api.hpp>\n"); |
| 405 | fprintf(example_cpp_f, "#include <tinympc/tiny_data.hpp>\n\n"); |
| 406 | |
| 407 | fprintf(example_cpp_f, "using namespace Eigen;\n"); |
| 408 | fprintf(example_cpp_f, "IOFormat TinyFmt(4, 0, \", \", \"\\n\", \"[\", \"]\");\n\n"); |
| 409 | |
| 410 | fprintf(example_cpp_f, "#ifdef __cplusplus\n"); |
| 411 | fprintf(example_cpp_f, "extern \"C\" {\n"); |
| 412 | fprintf(example_cpp_f, "#endif\n\n"); |
| 413 | |
| 414 | fprintf(example_cpp_f, "int main()\n"); |
| 415 | fprintf(example_cpp_f, "{\n"); |
| 416 | fprintf(example_cpp_f, "\tint exitflag = 1;\n"); |
| 417 | fprintf(example_cpp_f, "\t// Double check some data\n"); |
| 418 | fprintf(example_cpp_f, "\tstd::cout << \"rho: \" << tiny_solver.cache->rho << std::endl;\n"); |
| 419 | fprintf(example_cpp_f, "\tstd::cout << \"\\nmax iters: \" << tiny_solver.settings->max_iter << std::endl;\n"); |
| 420 | fprintf(example_cpp_f, "\tstd::cout << \"\\nState transition matrix:\\n\" << tiny_solver.work->Adyn.format(TinyFmt) << std::endl;\n"); |
| 421 | fprintf(example_cpp_f, "\tstd::cout << \"\\nInput/control matrix:\\n\" << tiny_solver.work->Bdyn.format(TinyFmt) << std::endl;\n\n"); |
| 422 | |
| 423 | fprintf(example_cpp_f, "\t// Visit https://tinympc.org/ to see how to set the initial condition and update the reference trajectory.\n\n"); |
| 424 | |
| 425 | fprintf(example_cpp_f, "\tstd::cout << \"\\nSolving...\\n\" << std::endl;\n\n"); |
| 426 | fprintf(example_cpp_f, "\texitflag = tiny_solve(&tiny_solver);\n\n"); |
| 427 | fprintf(example_cpp_f, "\tif (exitflag == 0) printf(\"Hooray! Solved with no error!\\n\");\n"); |
| 428 | fprintf(example_cpp_f, "\telse printf(\"Oops! Something went wrong!\\n\");\n"); |
| 429 | |
| 430 | fprintf(example_cpp_f, "\treturn 0;\n"); |
| 431 | fprintf(example_cpp_f, "}\n\n"); |
| 432 | |
| 433 | fprintf(example_cpp_f, "#ifdef __cplusplus\n"); |
| 434 | fprintf(example_cpp_f, "} /* extern \"C\" */\n"); |
| 435 | fprintf(example_cpp_f, "#endif\n"); |
| 436 | |
| 437 | // Close codegen example main file |
| 438 | fclose(example_cpp_f); |
| 439 | if (verbose) { |
| 440 | printf("Example tinympc main generated in %s\n", example_cpp_fname); |
| 441 | } |