iCub-main
Loading...
Searching...
No Matches
optimalControl.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT)
3 * Copyright (C) 2006-2010 RobotCub Consortium
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD-3-Clause license. See the accompanying LICENSE file for
8 * details.
9*/
10
11#include <cmath>
12
13#include <yarp/os/Log.h>
14#include <yarp/math/Math.h>
15#include <yarp/math/SVD.h>
17
18using namespace std;
19using namespace yarp::os;
20using namespace yarp::sig;
21using namespace yarp::math;
22using namespace iCub::ctrl;
23
24
25//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26Riccati::Riccati(const Matrix &_A, const Matrix &_B, const Matrix &_V,
27 const Matrix &_P, const Matrix &_VN, bool verb)
28{
29 A = _A; At = A.transposed();
30 B = _B; Bt = B.transposed();
31 V = _V;
32 P = _P;
33 VN = _VN;
34
35 Ti = new Matrix[1]; Ti[0].resize(1,1); Ti[0].zero();
36 Li = new Matrix[1]; Li[0].resize(1,1); Li[0].zero();
37
38 n=A.rows();
39 m=B.rows();
40 N=-1;
41
42 verbose=verb;
43 if (verbose)
44 yWarning("Riccati: problem defined, unsolved.");
45}
46
47
48//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49void Riccati::setVerbose(bool verb)
50{
51 verbose=verb;
52}
53
54
55//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56Matrix Riccati::L(int step)
57{
58 if(N<0)
59 {
60 if (verbose)
61 yWarning("Riccati: DARE has not been solved yet.");
62 return Li[0];
63 }
64 if(step>=0 && step>=N)
65 {
66 if (verbose)
67 yWarning("Riccati: Index for gain matrix out of bound.");
68 return Li[0];
69 }
70 return Li[step];
71}
72
73
74//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
75Matrix Riccati::T(int step)
76{
77 if(N<0)
78 {
79 if (verbose)
80 yError("Riccati: DARE has not been solved yet.");
81 return Ti[0];
82 }
83 if(step>=0 && step>N)
84 {
85 if (verbose)
86 yError("Riccati: Index for DARE matrix out of bound.");
87 return Ti[0];
88 }
89 return Ti[step];
90}
91
92
93//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
94void Riccati::setProblemData(const Matrix &_A, const Matrix &_B, const Matrix &_V,
95 const Matrix &_P, const Matrix &_VN)
96{
97 A = _A; At = A.transposed();
98 B = _B; Bt = B.transposed();
99 V = _V;
100 P = _P;
101 VN = _VN;
102
103 n=A.rows();
104 m=B.rows();
105 N=-1;
106
107 if (verbose)
108 yWarning("Riccati: problem defined, unsolved.");
109}
110
111
112//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114{
115 int i;
116 N = steps;
117 delete [] Ti;
118 delete [] Li;
119 Ti = new Matrix[steps+1];
120 Li = new Matrix[steps];
121 for(i=0; i<=steps; i++)
122 Ti[i].resize(VN.rows(),VN.cols());
123 //init TN=VN
124 Ti[steps]=VN;
125 //compute backward all Ti
126 for(i=steps-1; i>=0; i--)
127 {
128 lastT=Ti[i+1];
129 //Ti = V + A' * (Ti+1 - Ti+1 * B * (P + B' * Ti+1 * B)^-1 * B' * Ti+1 )* A;
130 Ti[i] = V + At *(lastT - lastT * B* pinv(P+Bt*lastT*B)*Bt*lastT )* A;
131 }
132 //compute forward all Li
133 for(i=0;i<steps; i++)
134 {
135 //Li = (P + B' * Ti+1 * B)^-1 * B' * Ti+1 * A
136 Li[i] = pinv(P + Bt*Ti[i+1]*B) *Bt * Ti[i+1] * A;
137 }
138
139 if (verbose)
140 yInfo("Riccati: DARE solved, matrices Li and Ti computed and stored.");
141}
142
143
144//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145Vector Riccati::doLQcontrol(int step, const Vector &x)
146{
147 if(N<0)
148 {
149 if (verbose)
150 yError("Riccati: DARE has not been solved yet.");
151 Vector ret(1,0.0);
152 return ret;
153 }
154 if(step>=0 && step>N)
155 {
156 if (verbose)
157 yError("Riccati: Index for DARE matrix out of bound.");
158 Vector ret(1,0.0);
159 return ret;
160 }
161 return (Li[step] * (-1.0*x));
162}
163
164
165//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
166void Riccati::doLQcontrol(int step, const Vector &x, Vector &ret)
167{
168 if(N<0)
169 {
170 if (verbose)
171 yError("Riccati: DARE has not been solved yet.");
172 ret.zero();
173 }
174 else if(step>=0 && step>N)
175 {
176 if (verbose)
177 yError("Riccati: Index for DARE matrix out of bound.");
178 ret.zero();
179 }
180 else
181 {
182 ret.resize(m);
183 ret = Li[step] * (-1.0*x);
184 }
185}
186
187
yarp::sig::Matrix * Li
yarp::sig::Matrix * Ti
yarp::sig::Vector x
yarp::sig::Matrix A
Riccati(const yarp::sig::Matrix &_A, const yarp::sig::Matrix &_B, const yarp::sig::Matrix &_V, const yarp::sig::Matrix &_P, const yarp::sig::Matrix &_VN, bool verb=false)
Constructor, with initialization of algebraic Riccati equation.
yarp::sig::Matrix At
yarp::sig::Matrix VN
yarp::sig::Matrix Bt
yarp::sig::Matrix B
void setVerbose(bool verb=true)
Enable or disable verbose feedback (that is, printing additional information)
yarp::sig::Vector doLQcontrol(int step, const yarp::sig::Vector &x)
Compute the LQ feedback control, in the form: ret= - L(i) * x.
void solveRiccati(int steps)
Solve recursively discrete algebraic Riccati equation (DARE) and stores matrices Ti and Li,...
void setProblemData(const yarp::sig::Matrix &_A, const yarp::sig::Matrix &_B, const yarp::sig::Matrix &_V, const yarp::sig::Matrix &_P, const yarp::sig::Matrix &_VN)
Initialization of algebraic Riccati equation.
yarp::sig::Matrix lastT
yarp::sig::Matrix V
yarp::sig::Matrix P
yarp::sig::Matrix L(int step)
Get stored L_i matrix; call this function only after solveRiccati()
yarp::sig::Matrix T(int step)
Get stored T_i matrix; call this function only after solveRiccati()