Code Generation Tool을 통해 코드를 만들어 주기 위해서는 OCPexport 변수를 선언하고 원하는 솔버 설정을 해주면 된다.
빌드를 하기 전에 ACADO 폴더에 있는 ./external_packages에서 본인이 사용하는 QP_SOLVER를 경로안에 같이 넣어주어야 한다.
빌드 후 생긴 test.cpp를 다시 해당 폴더에서 make를 통해 빌드하고, executable를 실행하였다.
$ ./testACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.Copyright (C) 2008-2015 by Boris Houska, Hans Joachim Ferreau,Milan Vukov and Rien Quirynen, KU Leuven.Developed within the Optimization in Engineering Center (OPTEC) undersupervision of Moritz Diehl. All rights reserved.ACADO Toolkit is distributed under the terms of the GNU LesserGeneral Public License 3 in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU Lesser General Public License for more details. Real-Time Iteration 0: KKT Tolerance = 1.625e+00 Real-Time Iteration 1: KKT Tolerance = 5.895e-07 Real-Time Iteration 2: KKT Tolerance = 1.003e-13 Real-Time Iteration 3: KKT Tolerance = 5.009e-20 Real-Time Iteration 4: KKT Tolerance = 2.630e-26 Real-Time Iteration 5: KKT Tolerance = 3.360e-31 Real-Time Iteration 6: KKT Tolerance = 2.007e-31 Real-Time Iteration 7: KKT Tolerance = 1.480e-31 Real-Time Iteration 8: KKT Tolerance = 3.944e-33 Real-Time Iteration 9: KKT Tolerance = 2.326e-33End of the RTI loop.Differential variables:[ 1.000000e-01 1.000000e-01 1.000000e-01 1.000000e-01 1.233878e-01 5.591860e-02 9.088841e-02 -1.536102e-01 1.294342e-01 -1.560897e-02 2.570073e-02 -2.476023e-01 1.157576e-01 -7.556884e-02 -3.838386e-02 -1.487911e-01 9.011084e-02 -9.540932e-02 -5.748262e-02 2.911045e-02 6.425943e-02 -7.693337e-02 -2.962655e-02 1.415938e-01 4.614686e-02 -4.381710e-02 1.318072e-02 1.226962e-01 3.658784e-02 -1.990970e-02 3.531533e-02 1.497966e-02 3.154798e-02 -1.368941e-02 2.402310e-02 -8.363073e-02 2.668423e-02 -1.873556e-02 -5.864383e-03 -1.005828e-01 2.021838e-02 -2.437011e-02 -2.790116e-02 -3.603973e-02]Control variables:[ -1.469380e-01 -2.384252e-01 -1.998662e-01 -6.613493e-02 6.158650e-02 1.103876e-01 7.969134e-02 2.073429e-02 -1.682051e-02 -1.878184e-02]
Implementation the code generation tool on a quarter car model
앞서서 살펴보았던 quarter car 모델 예제에 code generation tool을 적용해보고자 한다.
앞서 작성한 ocp_mpc_simulation.cpp파일을 수정해보자.
시뮬레이션을 돌리기 위해 작성한 Process, Controller와 그에 필요했던 OutputFcn, DynamicSystem, RealTimeAlgorithm 등등을 모두 주석처리해준다. 그리고 plotting 파트도 주석처리해준 후 Export 옵션만 넣어주면 된다.
Only standard LSQ objective supported for code generation
이렇게 내용만 바꿔서 빌드 후 실행하면 이런 에러가 나타난다.
원인은 LSQ의 EndTerm을 넣어주지 않았기 때문이다.
이 링크에서 저자가 설명한 내용도 참고
그래서 아래와 같이 마지막 T에 대한 LSQ도 정의해주었다.
// Least Square Function Function h h << xB; h << xW; h << vB; h << vW; h << F; Function hN; hN << xB << xW << vB << xW; // LSQ coefficient matrix DMatrix Q(5, 5); Q(0, 0) = 10.0; Q(1, 1) = 10.0; Q(2, 2) = 1.0; Q(3, 3) = 1.0; Q(4, 4) = 1.0e-8; DMatrix P; P = eye<double>(hN.getDim()); P *= 5;
coefficient matrix P의 스케일은 튜토리얼대로 5로 하였다
How to determine coefficient matrix?
LSQ에서 coefficient matrix를 어떤 식으로 설정하는지
전체 time horizon T를 linear하거나 exponential하게도 고려하는 것으로 알고 있는데, 이러한 경우에 scaling을 어떻게 하는지
CGT 예제처럼 필요한 qp solver 폴더를 넣어주고 돌리면 아래와 같이 결과가 나온다.
$ ./testACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.Copyright (C) 2008-2015 by Boris Houska, Hans Joachim Ferreau,Milan Vukov and Rien Quirynen, KU Leuven.Developed within the Optimization in Engineering Center (OPTEC) undersupervision of Moritz Diehl. All rights reserved.ACADO Toolkit is distributed under the terms of the GNU LesserGeneral Public License 3 in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU Lesser General Public License for more details. Real-Time Iteration 0: KKT Tolerance = 5.613e+00 Real-Time Iteration 1: KKT Tolerance = 3.546e-16 Real-Time Iteration 2: KKT Tolerance = 1.068e-32 Real-Time Iteration 3: KKT Tolerance = 4.271e-32 Real-Time Iteration 4: KKT Tolerance = 4.271e-32 Real-Time Iteration 5: KKT Tolerance = 6.674e-32 Real-Time Iteration 6: KKT Tolerance = 2.162e-31 Real-Time Iteration 7: KKT Tolerance = 1.308e-31 Real-Time Iteration 8: KKT Tolerance = 1.068e-32 Real-Time Iteration 9: KKT Tolerance = 5.232e-31End of the RTI loop.Differential variables:[ 1.000000e-01 1.000000e-01 1.000000e-01 1.000000e-01 9.906872e-02 -9.550925e-02 -2.489402e-01 6.966448e-01 7.845589e-02 5.951503e-02 -4.789123e-01 -1.098396e+00 4.918713e-02 -5.475780e-02 -7.406515e-01 1.449904e+00 9.757824e-03 3.565036e-02 -7.697920e-01 -1.386624e+00 -2.796202e-02 -2.609813e-02 -7.530222e-01 1.504686e+00 -6.152661e-02 2.481492e-02 -5.483117e-01 -1.298717e+00 -8.461457e-02 -3.817229e-03 -3.774037e-01 1.247964e+00 -9.527936e-02 1.456852e-02 -3.671509e-02 -1.047424e+00 -9.095846e-02 7.040125e-03 2.058478e-01 8.602483e-01 -7.403694e-02 8.125103e-03 4.615085e-01 -7.652887e-01 -4.696817e-02 6.064396e-03 6.091964e-01 5.277362e-01 -1.391311e-02 5.758481e-04 6.929277e-01 -5.275234e-01 1.992432e-02 1.093240e-03 6.461837e-01 3.018989e-01 4.950961e-02 -5.879842e-03 5.184837e-01 -3.241777e-01 7.007656e-02 -3.343126e-03 2.967101e-01 1.792946e-01 7.867884e-02 -8.473659e-03 3.990362e-02 -1.542275e-01 7.509835e-02 -7.325488e-03 -1.804107e-01 1.354349e-01 6.125961e-02 -7.137871e-03 -3.668478e-01 -5.818779e-02 3.924063e-02 -3.894873e-03 -5.015153e-01 1.160833e-01 1.249268e-02 -2.662037e-03 -5.553479e-01 -5.653247e-04]Control variables:[ 0.000000e+00 -2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 -1.989419e+02 0.000000e+00 2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 -2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 2.000000e+02 0.000000e+00 2.000000e+02]
우리가 Control로 R,F를 넣어주었고 이전에 나온 plotting을 고려해보면 R은 0으로 나오는 것이 타당한데, F는 boundary 안에서만 움직이는 모습을 보였다.
OCP의 시간을 0.0≤t≤1.0로만 하여서 라고 생각하여 0.0≤t≤2.5로 하였는데 아예 0으로 나오고 KKT Tolerance도 0이 되어버림.
또 한가지 의문점은 reference를 선언하지 않고도 어떤 식으로 ocp가 풀리는지도 궁금하였다.
Github Issues에서도 이러한 의문을 제기한 사람이 있음.