Writing main.c file for C/C++ code Generated from mpcmoveCodeGeneration Command

2 views (last 30 days)
Edward Kim
Edward Kim on 30 Jan 2021
Answered: Gaurav Garg on 3 Feb 2021
I'm trying to understand MATLAB Coder and mpcmove so I've tested the example here: Generate Code to Compute Optimal MPC Moves in MATLAB - MATLAB & Simulink (mathworks.com)
It generated a bunch of .c and .h files and, please correct me if I'm wrong, but I have to write my own main.c file to actually use the functions and files produced by MATLAB Coder.
I'm trying to reproduce the results from that webpage by running the C/C++ code on a piece of Linux hardware but I'm quite clueless on how to use the great number of .c files it generated for the main.c file and I'm also unsure of how exactly the mpcmove and mpcmoveCodeGeneration commands work.
The following files are generated, just to name a few:
mpcmoveCodeGeneration.c
mpcmoveCodeGeneration_data.c
mpcmoveCodeGeneration_initialize.c
mpcmoveCodeGeneration_terminate.c
I'm really clueless so any sort of advice on code generation or the mpcmoveCodeGeneration command would be greatly appreciated.
For example, here's the code for mpcmoveCodeGeneration.c:
#include "mpcmoveCodeGeneration.h"
#include "mpcmoveCodeGeneration_types.h"
#include "qpkwik.h"
#include "rt_nonfinite.h"
#include <string.h>
/* Function Definitions */
void mpcmoveCodeGeneration(struct3_T *mpcmovestate, const struct4_T *mpcmovedata,
double *u, struct9_T *Info)
{
static const double Ac[72] = { -0.083037111170812361, -0.097623488903372108,
-0.0995927636417564, -0.099858610346689469, -0.099894498923985137,
-0.099899343783659514, -0.099899997826450648, -0.099900086120436729,
-0.0999000980398831, -0.099900099648975726, 0.083037111170812361,
0.097623488903372108, 0.0995927636417564, 0.099858610346689469,
0.099894498923985137, 0.099899343783659514, 0.099899997826450648,
0.099900086120436729, 0.0999000980398831, 0.099900099648975726, -1.0, -1.0,
1.0, 1.0, -0.0, -0.083037111170812361, -0.097623488903372108,
-0.0995927636417564, -0.099858610346689469, -0.099894498923985137,
-0.099899343783659514, -0.099899997826450648, -0.099900086120436729,
-0.0999000980398831, 0.0, 0.083037111170812361, 0.097623488903372108,
0.0995927636417564, 0.099858610346689469, 0.099894498923985137,
0.099899343783659514, 0.099899997826450648, 0.099900086120436729,
0.0999000980398831, -0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
0.0, 0.0 };
static const double Mx[72] = { -0.01458637773255974, -0.0019692747383842917,
-0.00026584670493307239, -3.5888577295669282E-5, -4.8448596743753593E-6,
-6.5404279113680324E-7, -8.8293986077764386E-8, -1.1919446377431031E-8,
-1.6090926263009991E-9, -2.1722309896194071E-10, 0.01458637773255974,
0.0019692747383842917, 0.00026584670493307239, 3.5888577295669282E-5,
4.8448596743753593E-6, 6.5404279113680324E-7, 8.8293986077764386E-8,
1.1919446377431031E-8, 1.6090926263009991E-9, 2.1722309896194071E-10, 0.0,
0.0, 0.0, 0.0, 0.00026122119385124865, 4.5886362754438393E-5,
6.1950167934390758E-6, 8.3631032757372381E-7, 1.1289960446134619E-7,
1.5241137490666415E-8, 2.0575118320182185E-9, 2.7775846399177547E-10,
3.749663215467102E-11, 5.0619426775932234E-12, -0.00026122119385124865,
-4.5886362754438393E-5, -6.1950167934390758E-6, -8.3631032757372381E-7,
-1.1289960446134619E-7, -1.5241137490666415E-8, -2.0575118320182185E-9,
-2.7775846399177547E-10, -3.749663215467102E-11, -5.0619426775932234E-12,
0.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 };
static const double Sx[30] = { 0.01458637773255974, 0.0019692747383842917,
0.00026584670493307239, 3.5888577295669282E-5, 4.8448596743753593E-6,
6.5404279113680324E-7, 8.8293986077764386E-8, 1.1919446377431031E-8,
1.6090926263009991E-9, 2.1722309896194071E-10, -0.00026122119385124865,
-4.5886362754438393E-5, -6.1950167934390758E-6, -8.3631032757372381E-7,
-1.1289960446134619E-7, -1.5241137490666415E-8, -2.0575118320182185E-9,
-2.7775846399177547E-10, -3.749663215467102E-11, -5.0619426775932234E-12,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
static const double Mu1[24] = { -0.083037111170812361, -0.097623488903372108,
-0.0995927636417564, -0.099858610346689469, -0.099894498923985137,
-0.099899343783659514, -0.099899997826450648, -0.099900086120436729,
-0.0999000980398831, -0.099900099648975726, 0.083037111170812361,
0.097623488903372108, 0.0995927636417564, 0.099858610346689469,
0.099894498923985137, 0.099899343783659514, 0.099899997826450648,
0.099900086120436729, 0.0999000980398831, 0.099900099648975726, -1.0, -1.0,
1.0, 1.0 };
static const double Kr[20] = { -0.083037111170812361, -0.097623488903372108,
-0.0995927636417564, -0.099858610346689469, -0.099894498923985137,
-0.099899343783659514, -0.099899997826450648, -0.099900086120436729,
-0.0999000980398831, -0.099900099648975726, -0.0, -0.083037111170812361,
-0.097623488903372108, -0.0995927636417564, -0.099858610346689469,
-0.099894498923985137, -0.099899343783659514, -0.099899997826450648,
-0.099900086120436729, -0.0999000980398831 };
static const double Su1[10] = { 0.083037111170812361, 0.097623488903372108,
0.0995927636417564, 0.099858610346689469, 0.099894498923985137,
0.099899343783659514, 0.099899997826450648, 0.099900086120436729,
0.0999000980398831, 0.099900099648975726 };
static const double H[9] = { 0.34619485412196427, 0.087648902028869213, 0.0,
0.087648902028869213, 0.33621482421208904, 0.0, 0.0, 0.0, 100000.0 };
static const double Hinv[9] = { 3.0926682253437314, -0.80623742550969557, 0.0,
-0.80623742550969557, 3.1844694166284473, 0.0, 0.0, 0.0,
9.9999999999999974E-6 };
static const double Linv[9] = { 1.6995725021573662, -0.45179811338061227, 0.0,
0.0, 1.7845081721943576, 0.0, 0.0, 0.0, 0.003162277660168379 };
static const double b_A[9] = { 0.13504277567360504, 0.001953125, 0.0,
-0.0031458367249060587, 0.0, 0.0, 0.0, 0.0, 1.0 };
static const double Kx[6] = { 0.0014340778384808065, -2.6884169943746316E-5,
0.97950609840602121, 0.00019360934076650773, -4.5113746624002463E-6,
0.87960599875704548 };
static const double c_a[3] = { 0.0039872714934198117, 5.7666576979280203E-5,
0.61696029737038915 };
static const signed char A[100] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1 };
static const signed char Mrows[24] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 31, 32 };
static const signed char Jm[20] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0 };
static const signed char b_a[3] = { 1, 0, 0 };
double xopt[33];
double Bc[24];
double unusedU0[24];
double uopt[11];
double yopt[11];
double aux2[10];
double r[10];
double aux[3];
double f[3];
double x[3];
double zopt[3];
double d;
double d1;
double d2;
double d3;
double umax_incr;
double umin_incr;
double xk_idx_0;
double xk_idx_1;
double xk_idx_2;
double y_innov;
double ymax_incr;
double ymin_incr;
int b_j1;
int i1;
int kidx;
short iAnew[24];
signed char a[100];
signed char i;
boolean_T umax_incr_flag;
boolean_T umin_incr_flag;
boolean_T ymax_incr_flag;
boolean_T ymin_incr_flag;
memset(&r[0], 0, 10U * sizeof(double));
r[0] = mpcmovedata->signals.ref;
for (kidx = 0; kidx < 9; kidx++) {
r[kidx + 1] = mpcmovedata->signals.ref;
}
xk_idx_0 = mpcmovestate->Plant[0];
xk_idx_1 = mpcmovestate->Plant[1];
xk_idx_2 = mpcmovestate->Disturbance;
y_innov = mpcmovedata->signals.ym - ((0.083037111170812361 * xk_idx_0 +
1.7268816671413876 * xk_idx_1) + xk_idx_2);
x[0] = xk_idx_0 + 0.029525287413391339 * y_innov;
x[1] = xk_idx_1 + -3.0112355717584646E-5 * y_innov;
x[2] = xk_idx_2 + 0.61696029737038871 * y_innov;
Info->Cost = 0.0;
memset(&uopt[0], 0, 11U * sizeof(double));
ymax_incr_flag = false;
ymax_incr = 0.0;
ymin_incr_flag = false;
ymin_incr = 0.0;
umax_incr_flag = false;
umax_incr = 0.0;
umin_incr_flag = false;
umin_incr = 0.0;
d = x[0];
d1 = x[1];
d2 = x[2];
for (kidx = 0; kidx < 24; kidx++) {
d3 = -((((Mx[kidx] * d + Mx[kidx + 24] * d1) + Mx[kidx + 48] * d2) + 1.0) +
Mu1[kidx] * mpcmovestate->LastMove);
Bc[kidx] = d3;
i = Mrows[kidx];
if (i <= 10) {
if (!ymax_incr_flag) {
ymax_incr = -mpcmovedata->limits.ymax - -1.0;
}
ymax_incr_flag = true;
d3 += ymax_incr;
Bc[kidx] = d3;
} else if (i <= 20) {
if (!ymin_incr_flag) {
ymin_incr = mpcmovedata->limits.ymin - -1.0;
}
ymin_incr_flag = true;
d3 += ymin_incr;
Bc[kidx] = d3;
} else if (i <= 30) {
if (!umax_incr_flag) {
umax_incr = -mpcmovedata->limits.umax - -1.0;
}
umax_incr_flag = true;
d3 += umax_incr;
Bc[kidx] = d3;
} else {
if (!umin_incr_flag) {
umin_incr = mpcmovedata->limits.umin - -1.0;
}
umin_incr_flag = true;
d3 += umin_incr;
Bc[kidx] = d3;
}
}
f[0] = 0.0;
f[1] = 0.0;
f[2] = 0.0;
for (kidx = 0; kidx < 2; kidx++) {
ymax_incr = 0.0;
for (b_j1 = 0; b_j1 < 10; b_j1++) {
ymax_incr += Kr[b_j1 + 10 * kidx] * r[b_j1];
}
f[kidx] = (((Kx[3 * kidx] * x[0] + Kx[3 * kidx + 1] * x[1]) + Kx[3 * kidx +
2] * x[2]) + ymax_incr) + (-0.0085459520930950827 * (double)kidx
+ 0.0961948541219643) * mpcmovestate->LastMove;
}
for (kidx = 0; kidx < 24; kidx++) {
iAnew[kidx] = mpcmovestate->iA[kidx];
}
qpkwik(Linv, Hinv, f, Ac, Bc, iAnew, zopt, unusedU0, &ymax_incr);
for (kidx = 0; kidx < 24; kidx++) {
mpcmovestate->iA[kidx] = (iAnew[kidx] != 0);
}
if ((ymax_incr < 0.0) || (ymax_incr == 0.0)) {
zopt[0] = 0.0;
zopt[1] = 0.0;
zopt[2] = 0.0;
}
Info->Iterations = ymax_incr;
Info->Slack = zopt[2];
*u = mpcmovestate->LastMove + zopt[0];
if (ymax_incr > 0.0) {
d = x[0];
d1 = x[1];
d2 = x[2];
for (i1 = 0; i1 < 10; i1++) {
aux2[i1] = (((Sx[i1] * d + Sx[i1 + 10] * d1) + Sx[i1 + 20] * d2) + Su1[i1]
* mpcmovestate->LastMove) - r[i1];
r[i1] = mpcmovestate->LastMove;
}
aux[0] = zopt[0];
aux[1] = zopt[1];
aux[2] = zopt[2];
ymin_incr = 0.0;
umax_incr = 0.0;
for (b_j1 = 0; b_j1 < 10; b_j1++) {
d = r[b_j1];
ymin_incr += d * (0.0 * d);
d = aux2[b_j1];
umax_incr += d * d;
}
ymax_incr = 0.0;
for (b_j1 = 0; b_j1 < 3; b_j1++) {
ymax_incr += aux[b_j1] * (((H[b_j1] * aux[0] + H[b_j1 + 3] * aux[1]) +
H[b_j1 + 6] * aux[2]) + 2.0 * f[b_j1]);
}
Info->Cost = (ymin_incr + umax_incr) + ymax_incr;
}
kidx = -1;
for (b_j1 = 0; b_j1 < 10; b_j1++) {
for (i1 = 0; i1 < 10; i1++) {
kidx++;
a[kidx] = A[i1 + 10 * b_j1];
}
}
for (b_j1 = 0; b_j1 < 10; b_j1++) {
d = 0.0;
for (kidx = 0; kidx < 2; kidx++) {
d1 = 0.0;
for (i1 = 0; i1 < 10; i1++) {
d1 += (double)(a[b_j1 + 10 * i1] * Jm[i1 + 10 * kidx]);
}
d += d1 * zopt[kidx];
}
uopt[b_j1] = d + mpcmovestate->LastMove;
}
uopt[10] = uopt[9];
for (b_j1 = 0; b_j1 < 11; b_j1++) {
Info->Topt[b_j1] = b_j1;
}
memcpy(&r[0], &uopt[0], 10U * sizeof(double));
for (kidx = 0; kidx < 11; kidx++) {
d = x[0];
xopt[kidx] = x[0];
d1 = x[1];
xopt[kidx + 11] = x[1];
d2 = x[2];
xopt[kidx + 22] = x[2];
yopt[kidx] = (0.083037111170812361 * x[0] + 1.7268816671413876 * x[1]) + x[2];
if (kidx < 10) {
for (b_j1 = 0; b_j1 < 3; b_j1++) {
f[b_j1] = ((b_A[b_j1] * d + b_A[b_j1 + 3] * d1) + b_A[b_j1 + 6] * d2) +
(double)b_a[b_j1] * r[kidx];
}
x[0] = f[0];
x[1] = f[1];
x[2] = f[2];
}
}
for (b_j1 = 0; b_j1 < 3; b_j1++) {
memcpy(&Info->Xopt[b_j1 * 11], &xopt[b_j1 * 11], 11U * sizeof(double));
}
memcpy(&Info->Yopt[0], &yopt[0], 11U * sizeof(double));
memcpy(&Info->Uopt[0], &uopt[0], 11U * sizeof(double));
for (b_j1 = 0; b_j1 < 3; b_j1++) {
x[b_j1] = (((b_A[b_j1] * xk_idx_0 + b_A[b_j1 + 3] * xk_idx_1) + b_A[b_j1 + 6]
* xk_idx_2) + (double)b_a[b_j1] * *u) + c_a[b_j1] * y_innov;
}
mpcmovestate->Plant[0] = x[0];
mpcmovestate->Plant[1] = x[1];
mpcmovestate->Disturbance = x[2];
mpcmovestate->LastMove = *u;
}

Answers (1)

Gaurav Garg
Gaurav Garg on 3 Feb 2021
Hi Edward,
Kindly look at the following documentation for understanding of using main function with codegen. Using mpcmoveCodeGeneration shouldn't be any different from the documentation.
Moreover, you can look at the following documentation to specify main function for C/C++ executables.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by