Antar att vi har våran tillståndsmodell som vi har antingen modulerat fram via mätdata eller skrivit den för hand. Det rekommenderas att bygga från mätdata - alla gånger.
. Vi kan sammanfatta hela med.
är den avlånga och smala matrisen. Vårat mål är att hitta
ska vara mellan 0 och 1 för att undvika hård styrning av insignalerna.
för varje iteration. Du ska estimera
från ett kalman filter.
så är det bara sätta en enkel vektor t.ex. rada upp 1,1,1,1,1,1 om
ej får vara över 1 för alla element.
För enkelhetens skull så har jag varit snäll och gjort ett MATLAB-skript till er som är kopatibelt med GNU Octave.
Låt oss säga att jag använder dessa matriser som ska symbolisera ett dynamiskt beteende.
Jag kör en beräkning. Jag väljer att jag vill titta 10 iterationer i framtiden, 0.5 som mitt "börvärde" och jag ska stå på tillståndet
Kod: Markera allt
#include <stdio.h>
#include <stdlib.h>
#include "qpOASES/Header/qpOASES_e.h"
int main() {
/*
* In this example we have selected the following configuration inside Confiugration.h
* NOTICE THAT YOU NEED A CPU that support "double" data type here if you want correct calculations
* SELECTED_CONTROL_STRATEGY MANUAL
* ADIM 2
* YDIM 1
* RDIM 1
* HORIZON 10
*/
/**
* State space model that are being used with sample time 0.5
*
A =
0.69922 0.34629
-1.03887 0.35293
B =
0.20052
0.69258
C =
1 0
*/
// Create the objective function
real_t H[HORIZON*RDIM*HORIZON*RDIM] = {
0.2805315, 0.2018439, 0.0426243, -0.0759651, -0.1036495, -0.0619421, -0.0040178, 0.0286614, 0.0272949, 0.0098612,
0.2018439, 0.2778442, 0.1994990, 0.0429871, -0.0714696, -0.0964493, -0.0568636, -0.0070791, 0.0149778, 0.0086050,
0.0426243, 0.1994990, 0.2757980, 0.1998156, 0.0469099, -0.0651867, -0.0920177, -0.0595349, -0.0190196, -0.0013312,
-0.0759651, 0.0429871, 0.1998156, 0.2757491, 0.1992087, 0.0459379, -0.0658723, -0.0916045, -0.0576876, -0.0164965,
-0.1036495, -0.0714696, 0.0469099, 0.1992087, 0.2682287, 0.1871637, 0.0374421, -0.0607511, -0.0687136, -0.0264218,
-0.0619421, -0.0964493, -0.0651867, 0.0459379, 0.1871637, 0.2489367, 0.1735563, 0.0456445, -0.0240875, -0.0186362,
-0.0040178, -0.0568636, -0.0920177, -0.0658723, 0.0374421, 0.1735563, 0.2393389, 0.1793417, 0.0715045, 0.0112337,
0.0286614, -0.0070791, -0.0595349, -0.0916045, -0.0607511, 0.0456445, 0.1793417, 0.2358515, 0.1637535, 0.0502133,
0.0272949, 0.0149778, -0.0190196, -0.0576876, -0.0687136, -0.0240875, 0.0715045, 0.1637535, 0.1661745, 0.0685843,
0.0098612, 0.0086050, -0.0013312, -0.0164965, -0.0264218, -0.0186362, 0.0112337, 0.0502133, 0.0685843, 0.0361865};
real_t Ay[HORIZON*YDIM*HORIZON*RDIM] = {
0.20052, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.38004, 0.20052, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.27824, 0.38004, 0.20052, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
0.06225, 0.27824, 0.38004, 0.20052, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
-0.10327, 0.06225, 0.27824, 0.38004, 0.20052, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
-0.14641, -0.10327, 0.06225, 0.27824, 0.38004, 0.20052, 0.00000, 0.00000, 0.00000, 0.00000,
-0.09141, -0.14641, -0.10327, 0.06225, 0.27824, 0.38004, 0.20052, 0.00000, 0.00000, 0.00000,
-0.00738, -0.09141, -0.14641, -0.10327, 0.06225, 0.27824, 0.38004, 0.20052, 0.00000, 0.00000,
0.04768, -0.00738, -0.09141, -0.14641, -0.10327, 0.06225, 0.27824, 0.38004, 0.20052, 0.00000,
0.05464, 0.04768, -0.00738, -0.09141, -0.14641, -0.10327, 0.06225, 0.27824, 0.38004, 0.20052};
real_t g0[HORIZON*RDIM*ADIM] = {
0.0895555, 0.2675379,
-0.2126023, 0.1248676,
-0.2760081, -0.0300475,
-0.1621426, -0.1061071,
-0.0076856, -0.0926476,
0.0835982, -0.0338390,
0.0884757, 0.0180790,
0.0461764, 0.0363724,
0.0083306, 0.0259372,
-0.0022316, 0.0080912};
real_t g1[HORIZON*RDIM*HORIZON*YDIM] = {
0.18047, 0.34204, 0.25042, 0.05602, -0.09294, -0.13177, -0.08227, -0.00664, 0.04291, 0.04918,
0.00000, 0.18047, 0.34204, 0.25042, 0.05602, -0.09294, -0.13177, -0.08227, -0.00664, 0.04291,
0.00000, 0.00000, 0.18047, 0.34204, 0.25042, 0.05602, -0.09294, -0.13177, -0.08227, -0.00664,
0.00000, 0.00000, 0.00000, 0.18047, 0.34204, 0.25042, 0.05602, -0.09294, -0.13177, -0.08227,
0.00000, 0.00000, 0.00000, 0.00000, 0.18047, 0.34204, 0.25042, 0.05602, -0.09294, -0.13177,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.18047, 0.34204, 0.25042, 0.05602, -0.09294,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.18047, 0.34204, 0.25042, 0.05602,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.18047, 0.34204, 0.25042,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.18047, 0.34204,
0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.18047};
// Minimum input signal
real_t ulb[HORIZON*RDIM] = {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0};
// Maximum input signal
real_t uub[HORIZON*RDIM] = {
100,
100,
100,
100,
100,
100,
100,
100,
100,
100};
// Minimum output signal
real_t ylb[HORIZON*YDIM] = {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0};
// Maximum output signal
real_t yub[HORIZON*YDIM] = {
0.7,
0.7,
0.7,
0.7,
0.7,
0.7,
0.7,
0.7,
0.7,
0.7};
// Reference
double r = 0.5;
//Initial state vector - Start with zeros. That works. Let kalman filter estimate the states later
double x0[ADIM];
memset(x0, 0, ADIM*sizeof(float));
// Setting up QProblem object
static QProblem objective;
static Options options;
QProblemCON(&objective, HORIZON*RDIM,HORIZON*YDIM, HST_UNKNOWN);
Options_setToDefault(&options);
QProblem_setOptions(&objective, options);
// Declare best input vector
int nWSR;
real_t best_inputs[HORIZON*RDIM];
// g1r = g1*r
real_t g1R[HORIZON*RDIM];
real_t R[HORIZON*RDIM];
for(int i = 0; i < HORIZON*RDIM; i++)
R[i] = r;
dmul(g1, R, g1R, HORIZON*RDIM, HORIZON*YDIM, 1);
// g0x0 = g0*x0
real_t g0x0[HORIZON*RDIM];
dmul(g0, x0, g0x0, HORIZON*RDIM, ADIM, 1);
// Compute g = g0*x0 - g1*r
real_t g[HORIZON*RDIM];
for(int i = 0; i < HORIZON*RDIM; i++){
g[i] = g0x0[i] - g1R[i];
}
// Solve first QP
nWSR = 20;
QProblem_init(&objective, H, g, Ay, ulb, uub, ylb, yub, &nWSR, 0); // This can not be repeated. Need to be called only ONCE!
// Get the best_inputs
QProblem_getPrimalSolution(&objective, best_inputs);
// Print best_inputs
printf("Best inputs that we can implement into the system = \n");
for(int i = 0; i < HORIZON*RDIM; i++)
printf("%f\n", best_inputs[i]);
printf("\n\n");
// Let say that you are going to do another QP
// Update vector g = g0*x0 - g1*r where x0 is the state from kalman filter and r is our reference vector
// Now solve again
nWSR = 20;
QProblem_hotstart(&objective, g, ulb, uub, ylb, yub, &nWSR, 0); // This can be repeated
printf("Best inputs that we can implement into the system = \n");
for(int i = 0; i < HORIZON*RDIM; i++)
printf("%f\n", best_inputs[i]);
return EXIT_SUCCESS;
}
är exakt samam i MATLAB och GNU Octave.
för att simulera. Det går fintrimma mer också om man vill.