#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>
#include <Eigen/Dense>
// #include "types.hpp"
#include "codegen.hpp"
#ifdef __cplusplus
extern "C"
{
#endif
/* Define the maximum allowed length of the path (directory + filename + extension) */
#define PATH_LENGTH 2048
/* Define the maximum allowed length of the dirname */
#define DIR_NAME_LENGTH 100
/* Define the maximum allowed length of the filename (no extension)*/
#define FILE_LENGTH 100
#define BUF_SIZE 65536
using namespace Eigen;
IOFormat CleanFmt(4, 0, ", ", "\n", "[", "]");
static void copy_file(char *src_file_name, char *dest_file_name)
{
FILE *src_f, *dst_f;
src_f = fopen(src_file_name, "r");
if (src_f == NULL)
printf("ERROR OPENING SOLVER SOURCE FILE\n");
// return tiny_error(TINY_FOPEN_ERROR);
dst_f = fopen(dest_file_name, "w+");
if (dst_f == NULL)
printf("ERROR OPENING SOLVER DESTINATION FILE\n");
// return tiny_error(TINY_FOPEN_ERROR);
char c;
// Copy contents of solver to code generated solver file
c = fgetc(src_f);
while (c != EOF)
{
fputc(c, dst_f);
c = fgetc(src_f);
}
fclose(src_f);
fclose(dst_f);
}
static void copy_dir(char *src_dir_name, char *dest_dir_name)
{
// Open folder at given directory path
DIR *src_dir = opendir(src_dir_name);
if (src_dir == NULL)
{
printf("SOURCE DIRECTORY NAME DOES NOT EXIST\n");
return;
}
struct dirent *dir_entry;
// printf("reading source directory %s\n", src_dir_name);
char dir_entry_full_name[PATH_LENGTH + DIR_NAME_LENGTH];
char codegen_dest_file_name[PATH_LENGTH + DIR_NAME_LENGTH];
struct stat buffer;
while (dir_entry = readdir(src_dir))
{
// printf("dir_entry->d_name: %s\n", dir_entry->d_name);
sprintf(dir_entry_full_name, "%s/%s", src_dir_name, dir_entry->d_name);
stat(dir_entry_full_name, &buffer);
// printf("dir_entry_full_name: %s\n", dir_entry_full_name);
sprintf(codegen_dest_file_name, "%s/%s", dest_dir_name, dir_entry->d_name);
// printf("codegen_dest_file_name: %s\n", codegen_dest_file_name);
// Check if file is directory or not
if (S_ISDIR(buffer.st_mode) && strcmp(dir_entry->d_name, "..") != 0 && strcmp(dir_entry->d_name, ".") != 0)
{
// If directory entry is another directory, create that folder
// in the codegen directory and call copy_dir again
// printf("%s is a directory\n", dir_entry->d_name);
struct stat st = {0};
if (stat(codegen_dest_file_name, &st) == -1)
{
// printf("Creating new folder %s\n", codegen_dest_file_name);
mkdir(codegen_dest_file_name, 0700);
}
copy_dir(dir_entry_full_name, codegen_dest_file_name);
}
else if (!S_ISDIR(buffer.st_mode))
{
// Otherwise, copy file into code gen directory
// printf("%s is not a directory\n", dir_entry->d_name);
copy_file(dir_entry_full_name, codegen_dest_file_name);
}
}
closedir(src_dir);
}
static void print_matrix(FILE *f, MatrixXd mat, int num_elements)
{
for (int i = 0; i < num_elements; i++)
{
fprintf(f, "(tinytype)%.16f", mat.reshaped<RowMajor>()[i]);
if (i < num_elements - 1)
fprintf(f, ",");
}
}
static void codegen_example_main(time_t start_time, const char *codegen_dname)
{
// Write main function
char main_fname[PATH_LENGTH + DIR_NAME_LENGTH + FILE_LENGTH];
FILE *main_f;
sprintf(main_fname, "%s/tiny_main.cpp", codegen_dname);
// Open global options file
main_f = fopen(main_fname, "w+");
if (main_f == NULL)
printf("ERROR OPENING EXAMPLE MAIN FILE\n");
// return tiny_error(TINY_FOPEN_ERROR);
// Preamble
time(&start_time);
fprintf(main_f, "/*\n");
fprintf(main_f, " * This file was autogenerated by TinyMPC on %s", ctime(&start_time));
fprintf(main_f, " */\n\n");
fprintf(main_f, "#include <iostream>\n\n");
fprintf(main_f, "#include <tinympc/admm.hpp>\n");
fprintf(main_f, "#include <tinympc/tiny_data_workspace.hpp>\n\n");
fprintf(main_f, "using namespace Eigen;\n");
fprintf(main_f, "IOFormat CleanFmt(4, 0, \", \", \"\\n\", \"[\", \"]\");\n\n");
fprintf(main_f, "#ifdef __cplusplus\n");
fprintf(main_f, "extern \"C\" {\n");
fprintf(main_f, "#endif\n\n");
fprintf(main_f, "int main()\n");
fprintf(main_f, "{\n");
fprintf(main_f, "\tint exitflag = 1;\n");
fprintf(main_f, "\t// Double check some data\n");
fprintf(main_f, "\tstd::cout << tiny_data_solver.settings->max_iter << std::endl;\n");
fprintf(main_f, "\tstd::cout << tiny_data_solver.cache->AmBKt.format(CleanFmt) << std::endl;\n");
fprintf(main_f, "\tstd::cout << tiny_data_solver.work->Adyn.format(CleanFmt) << std::endl;\n\n");
fprintf(main_f, "\texitflag = tiny_solve(&tiny_data_solver);\n\n");
fprintf(main_f, "\tif (exitflag == 0) printf(\"HOORAY! Solved with no error!\\n\");\n");
fprintf(main_f, "\telse printf(\"OOPS! Something went wrong!\\n\");\n");
fprintf(main_f, "\treturn 0;\n");
fprintf(main_f, "}\n\n");
fprintf(main_f, "#ifdef __cplusplus\n");
fprintf(main_f, "} /* extern \"C\" */\n");
fprintf(main_f, "#endif\n");
// Close codegen example main file
fclose(main_f);
printf("Example tinympc main generated in %s\n", main_fname);
}
int tiny_codegen(const int nx, const int nu, const int N,
double *Adyn_data, double *Bdyn_data, double *Q_data, double *R_data,
double *x_min_data, double *x_max_data, double *u_min_data, double *u_max_data,
double rho, double abs_pri_tol, double abs_dua_tol, int max_iters, int check_termination, int gen_wrapper,
const char *tinympc_dir, const char *output_dir)
{
int en_state_bound = 0;
int en_input_bound = 0;
if (x_min_data != nullptr && x_max_data != nullptr)
{
en_state_bound = 1;
}
else
{
en_state_bound = 0;
}
if (u_min_data != nullptr && u_max_data != nullptr)
{
en_input_bound = 1;
}
else
{
en_input_bound = 0;
}
MatrixXd Adyn = MatrixXd::Map(Adyn_data, nx, nx);
MatrixXd Bdyn = MatrixXd::Map(Bdyn_data, nx, nu);
MatrixXd Q = MatrixXd::Map(Q_data, nx, 1);
MatrixXd R = MatrixXd::Map(R_data, nu, 1);
MatrixXd x_min = MatrixXd::Map(x_min_data, nx, N);
MatrixXd x_max = MatrixXd::Map(x_max_data, nx, N);
MatrixXd u_min = MatrixXd::Map(u_min_data, nu, N - 1);
MatrixXd u_max = MatrixXd::Map(u_max_data, nu, N - 1);
// Update by adding rho * identity matrix to Q, R
Q = Q + rho * MatrixXd::Ones(nx, 1);
R = R + rho * MatrixXd::Ones(nu, 1);
MatrixXd Q1 = Q.array().matrix().asDiagonal();
MatrixXd R1 = R.array().matrix().asDiagonal();
// Printing
std::cout << "A = " << Adyn.format(CleanFmt) << std::endl;
std::cout << "B = " << Bdyn.format(CleanFmt) << std::endl;
std::cout << "Q = " << Q1.format(CleanFmt) << std::endl;
std::cout << "R = " << R1.format(CleanFmt) << std::endl;
没有合适的资源?快使用搜索试试~ 我知道了~
TinyMPC项目代码
共414个文件
h:356个
hpp:10个
cpp:7个
5星 · 超过95%的资源 1 下载量 128 浏览量
2024-04-30
11:26:42
上传
评论
收藏 2.12MB ZIP 举报
温馨提示
卡内基梅隆大学的开源机器人TinyMPC项目代码,可运行在单片机上;如STM32F405、树莓派PICO、RP2040。在自动驾驶和无人车领域的路径规划常常被分为运动轨迹生成与车辆路径跟踪控制两个部分。传统的基于几何条件的跟踪算法如pure-pursuit由于没有考虑车辆运动学导致控制精度和稳定性等方面存在不足,因此目前大部分采用线性MPC控制算法,从而平衡控制精度与计算量。 MPC控制算法,全称Model Predictive Control(模型预测控制),是一种基于系统动态模型的控制技术。它的工作原理是通过数学模型预测系统的未来行为,并基于这些预测结果来优化系统的控制输入,从而实现期望的输出。 MPC控制算法的核心在于其预测模型,这个模型可以根据系统的当前状态信息预测未来的系统状态。预测模型的形式并不固定,可以是状态空间方程、传递函数、阶跃响应模型、脉冲响应模型、模糊模型等,具体形式取决于被控对象和需要预测的状态。
资源推荐
资源详情
资源评论
收起资源包目录
TinyMPC项目代码 (414个子文件)
AccelerateSupport 2KB
Cholesky 1KB
CholmodSupport 2KB
Core 13KB
codegen.cpp 27KB
tiny_wrapper.cpp 6KB
admm.cpp 6KB
quadrotor_tracking.cpp 5KB
quadrotor_hovering.cpp 4KB
codegen_cartpole.cpp 4KB
codegen_random.cpp 2KB
Dense 122B
Eigen 35B
Eigenvalues 2KB
Geometry 2KB
.gitignore 513B
lapacke.h 1.01MB
PacketMath.h 190KB
MatrixProduct.h 145KB
GeneralBlockPanelKernel.h 138KB
PacketMath.h 119KB
PacketMath.h 109KB
MatrixVectorProduct.h 109KB
PacketMath.h 98KB
GenericPacketMathFunctions.h 91KB
PacketMath.h 81KB
SparseMatrix.h 79KB
CoreEvaluators.h 74KB
Transform.h 61KB
BDCSVD.h 61KB
Eigen_Colamd.h 60KB
TypeCasting.h 59KB
MathFunctions.h 58KB
BlockMethods.h 58KB
PacketMath.h 57KB
TrsmKernel.h 54KB
ProductEvaluators.h 54KB
GenericPacketMath.h 53KB
Memory.h 49KB
PlainObjectBase.h 48KB
Macros.h 47KB
GemmKernel.h 47KB
UnaryFunctors.h 46KB
AssignEvaluator.h 42KB
Half.h 40KB
XprHelper.h 37KB
TriangularMatrix.h 37KB
CwiseNullaryOp.h 37KB
PacketMath.h 36KB
SparseCwiseBinaryOp.h 35KB
Visitor.h 35KB
SelfAdjointEigenSolver.h 35KB
JacobiSVD.h 34KB
VectorwiseOp.h 34KB
SparseLU.h 34KB
Quaternion.h 34KB
BFloat16.h 34KB
SuperLUSupport.h 34KB
PacketMath.h 33KB
FullPivLU.h 33KB
BinaryFunctors.h 31KB
DenseBase.h 31KB
SparseQR.h 29KB
DenseStorage.h 28KB
FullPivHouseholderQR.h 28KB
MatrixProductMMAbfloat16.h 28KB
MatrixProductMMA.h 27KB
ColPivHouseholderQR.h 26KB
PacketMathFP16.h 26KB
BlasUtil.h 26KB
SparseSelfAdjointView.h 25KB
CholmodSupport.h 25KB
CompleteOrthogonalDecomposition.h 24KB
LDLT.h 24KB
UmfPackSupport.h 24KB
DenseCoeffsBase.h 24KB
Matrix.h 24KB
SimplicialCholesky.h 24KB
SparseBlock.h 24KB
MatrixBase.h 24KB
PacketMath.h 23KB
RealQZ.h 23KB
HouseholderSequence.h 23KB
SparseCompressedBase.h 23KB
EigenSolver.h 22KB
ArrayCwiseUnaryOps.h 22KB
Tridiagonalization.h 22KB
Redux.h 22KB
PartialPivLU.h 22KB
MoreMeta.h 22KB
PaStiXSupport.h 22KB
Constants.h 22KB
GeneralMatrixVector.h 22KB
Complex.h 21KB
GeneralProduct.h 21KB
SelfadjointMatrixMatrix.h 21KB
StlIterators.h 21KB
TriangularMatrixMatrix.h 21KB
RealSchur.h 21KB
PacketMath.h 21KB
共 414 条
- 1
- 2
- 3
- 4
- 5
资源评论
- zoweetize2024-05-08#内容详尽 #注释完整 #完美解决问题,好用,值得参考。
鹿屿二向箔
- 粉丝: 495
- 资源: 14
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功