# Controlling Remotely Operated Vehicles with Deterministic Artificial Intelligence
## Appendix B C++ Code
dai.h_  
#ifndef DAI_CONTROLLER_H
#define DAI_CONTROLLER_H  
#include <rls.h>
#include <units.h>  
#include <sno/logger.h>
#include <sno/so_exception.h>  
#include <eigen3/Eigen/Dense>
#include <eigen3/unsupported/Eigen/Polynomials>  
#include <tuple>
#include <vector>  
namespace { /* * @briefFindsolutiontopolynomialoftheform * f= a1*u*|u|+a0*u @parama0 Coefficient * @parama1 Coefficient * @paramfDesiredforce * @returnEffortrequiredforthatforce */ // TODO:l'mprettysurethisiswrong //Reliesonsomeassumptionshataren'tnecessarilytrue doubleforce_to_effort(constdoublea0, constdoubleal, constdoublef) { //Trivialcases //Ifforceisapproximately0,effortisapproximately0 if(std::fabs(f)<1e-9) { return0; } //Ifquadraticcoefficientisapproximately0,thenjustigmoreit if(std::fabs(a1)<1e-9){ returnf/a0; } //Solvequadraticw/absolutevalue: doubleu=0; if(a1>0) { if(f>0) {//uwillbepositive //a0^2>0,a1>0,f>0->radicandmustbepositive doubleradicand=a0*a0+4*a1*f; //2 solutions: //u1=(-a0+std::sqrt(radicand))/(2*a1) //u2=(-a0-std::sqrt(radicand))/(2*a1) //radicandwillalwaysbe>a0^2,sosqrt(radicand)willalwaysbegreater //thana0,sofaropositiveinthesolutionwillbe: u=(-a0+std::sqrt(radicand))/(2*a1); else {//uwillbenegative //a0^2>0,a1>0,f<0->radicandmustbepositive doubleradicand=a0*a0-4*a1*f; //2 solutions: //u1=(-a0+std::sqrt(radicand))/(-2*a1) //u2=(-a0-std::sqrt(radicand))/(-2*a1) //radicandwillalwaysbe>a0^2,sosqrt(radicand)willalwaysbegreater //thana0,sofaronegativeinthesolutionwillbe u=(-a0+std::sqrt(radicand))/(-2*a1); } else {//a1<0 if(f>0) {//uwillbenegative //a0^2>0,a1<0,f>0->radicandmustbepositive doubleradicand=a0*a0-4*a1*f; //Asabove,solutionforanegativeuwillbe: u=(-a0+std::sqrt(radicand))/(-2*a1); else {//uwillbepositive //a0^2>0,a1<0,f<0->radicandmustbepositive doubleradicand=a0*a0+4*a1*f; //Asabove,solutionforapositiveuwillbe u=(-a0+std::sqrt(radicand))/(2*a1);} } returnu; } } /** * * @brief The DAI_controllerclass
* @tparamL Number of parametersinthedynamicsmodeltoestimate
* @tparamN Number of systemstates
* @tparamMNumberofcontrolinputs
*/ template<size_tL,size_tN,size_tM=N> classDAI_controller  
public: typedefEigen::Matrix<double,L,1>MatrixL1; typedefEigen::Matrix<double,L,L>MatrixLL; typedefEigen::Matrix<double,N,N>MatrixNN; typedefEigen::Matrix<double,1,N>Matrix1N; typedefEigen::Matrix<double,N,1>MatrixN1; typedefEigen::Matrix<double,N,M>MatrixNM; typedefEigen::Matrix<double,M,1>MatrixM1;  
DAI_controller(constMatrixL1&theta0, constMatrixLL&P0) : m_theta_hat(theta0), m_rls(theta0,P0) { } }  
/** * @briefGetthecontroloutput
* @paramYCurrentsystemstate:
* @zphitheatsgiuvwpqru_dotv_dotw_dotp_dotq_dotr_dotl'
* @paramdCurrentdesiredstates(setpoints):
* @zphitheatsgiuvwpqru_dotv_dotw_dotp_dotq_dotr_dotl'
* @paramu_tCurrenteffortcommands:
* @u_xu_yu_zu_phiu_thetau_psi'
* @returnControloutputandcurrentparameterestimates:
* @u_xu_yu_zu_phiu_thetau_psi'
* THETA ->u = PHI
* THETA / a // Putinto regression form: Y = PHI
* THETA // PHI =... // [-p_dotp_dot-q_dotq_dotr_dotu_dotv_dotw_dot... // (-g*sin(theta) - u_dot) (v_dot - g*cos(theta)*sin(phi)) g*sin(theta) g*cos(theta)*sin(phi)... // -r -abs(r)*r); // THETA =... // [1_zx N_p_dot1_zy N_q_dot1_z N_r_dotN_u_dotN_v_dotN_w_dotg_y*m g_x*m V*b_y*rho V*b_x*rho N_r N_r].