# Controlling Remotely Operated Vehicles with Deterministic Artificial Intelligence
## Appendix B C++ Code
adaptive_control.cpp_  
/**  
* @author [PERSON]
*/  
#include<adaptive_control_version.h>
#include<indirect_self_tuning_regulator.h>
#include<dai.h>
#include<matrix_utils.h>
#include<state_estimator/state_estimator.h>
#include<trajectory.h>
#include<sinusoidal_trajectory.h>
#include<cubic_trajectory.h>
#include<SO_utils.h>  
#include<sno/logger.h>
#include<sno/sno_macros.h>
#include<sno/time_utils.h>  
#include<opencmd_defs.h>
#include<opensea/ops.h>
#include<opensea/gss_types/pcomms.h>
#include<opensea/gss_types/effort.h>
#include<opensea/gss_types/cmd.h>
#include<opensea/gss_types/nav_solution.h>  
#include<lcm/lcm-cpp.hpp>
#include<atomic>
#include<chrono>
#include<thread>  
/**  
* @brief Channel tosubscribet tonavsolutions
*/ std::string m_nav_channel = 'OPENINS_NAV_SOLUTION';  
/**  
* @brief Channel tosubscribet tosetpoints on
*/ std::string m_ctrl_cmd_channel = 'OPENCMD_CMD';  
/**  
* @brief Channel tosubscribet toopencmd efforts on
*/ std::string m_effort_in_channel = 'OPENCMD_EPORT';  
/**  
* @brief Channel topublish effort commands on
*/ std::string m_effort_out_channel = 'ADAPTIVE_CTRL_EFFORT';  
/**  
* @brief Controller status channel
*/ std::string m_status_channel = 'ADAPTIVE_CTRL_STAT';  
/**  
* @brief Command channel
*/ std::string m_cmd_channel = 'ADAPTIVE_CTRL_CMD';  
/**  
* @brief Main thread sleepinterval, ms
*/ const std::chrono:: milliseconds m_main_sleep_ms(50);  
/**  
* @brief Last received efforts
*/ gss::types::Effort m_last_effort_rx;  
/**  
* @brief Last transmitted efforts
*/ gss::types::Effort m_last_effort_tx;  
/**  
* @brief Indirect sleftuning regulator
*/ std::shared_ptr<ISTR> m_istr;  
static ssize_t L = 15; // Number of parameters being estimated
* static ssize_t N = 18; // Number of states
* static ssize_t M = 6; // Controlinputs/**  
* @briefDeterministicartificialintelligencecontroller
*/
*/
* @briefTimewhenthecontrolmoveshouldefinished
*/
*/
* @briefTruefautopilotisenabled
*/
*/
* @brief_Aulatonfilterforestimatingangularaccelerations
*/
*/
* @brief_Aulatonfilterforestimating  
m_setpoint, m_last_effort_tx.effort_psi); {} // If we'reinclosedloopmode,publish if(m_enable_auto && m_enable_istr && m_last_effort_rx.time_unix_sec > 0) { gss::effort_teffort_cmd = m_last_effort_rx; doubleeffort_out = effort; doublemax_effort = 50; doublemin_effort = -max_effort; if(effort_out > max_effort) { effort_out = max_effort; } elseif(effort_out < min_effort) { effort_out = min_effort; } effort_cmd.effort_psi = effort_out; m_plcm->Publish(m_effort_out_channel,&effort_cmd); m_last_effort_tx = effort_cmd; } gss::pcomms_tstat; staticuint32_tcount_publish = 0; stat.time_unix_sec = so::Time_utils::Unix_time(); stat.count_publish = count_publish++; stat.analogs.push_back(('A1',theta_hat[0]]); stat.analogs.push_back(('A2',theta_hat[1]]); stat.analogs.push_back(('B0',theta_hat[2]]); stat.analogs.push_back(('B1',theta_hat[3]]); stat.analogs.push_back(('UC',m_setpoint)); stat.analogs.push_back(('U',effort]); stat.analogs.push_back(('Y',y)); stat.digitals.push_back(('AUTO_DEPTH_ENABLEE',m_enable_auto)); stat.num_analogs = stat.analogs.size(); stat.num_digitals = stat.digitals.size(); stat.num_messages = stat.messages.size(); m_plcm->Publish(m_status_channel,&stat); } /m_last_effort_rx.time_unix_sec = -1; Eigen::Matrix<double, L, l> theta0 = Eigen::Matrix<double, L, l>::Ones(); // theta0(15) = -1; Eigen::Matrix<double, L, L> P0 = Eigen::Matrix<double, L, L>::Identity() * 100; m_dai = std::make_shared<DAI_controller<L, N, M>>(theta0, P0); } ////////////////////////////////////////////////////////////////////////  
void On_ctrl_cmd_received(const gss::OPS::Receive_buffer&, const std::string&, const gss::types::Cmd*msg) { m_enable_auto = msg->enable_state_psi == Opencmd_defs::E Enable_Auto; const double min_change = 1; if(std::fabs(msg->cmd_psi - m_setpoint) > min_change && m_last_soln.unix_time > 0) { m_psi_trajectory = Generate_trajectory(msg->cmd_psi); m_setpoint = msg->cmd_psi; } ////////////////////////////////////////////////////////////////////////////////  
void On_nav_received(const gss::OPS::Receive_buffer&, const std::string&, const gss::types::Nav_solution*msg) { m_last_soln = *msg; // Check thatnav is valid if(!msg->attitude_ok) { return; } if(!m_dai) { return; } // Currents state Eigen::Matrix<double, 18, l> Y = { msg->absolute_position[0], // TODO: what is the correct ''X'' state?