# AUV Control on STM32 written by 周文荏 contact: justinimbus.c@nycu.edu.tw --- ### Basic Concept **1. 誤差來源:** - 位置誤差&速度誤差 會從 Rpi 得到 - 深度誤差會由 Bar02 得到 - 姿態誤差會由 IMU & Rpi (yaw angle) 得到 **2. 控制原理:** - 得到誤差後,由 **controller** 乘以調參係數得到 **control input** - 再由 **control input** 透過 **allocation matrix** 得到**每個馬達的推力**完成輸出 --- ### Important Datatype #### Dynamics Dynamics 儲存 AUV 的: - quaternion: 四元素 (w,x,y,z) - position: (x,y,z) 位置 - velocity: 三個方向之速度&角速度 - acceleration: 三方向之家速度&角加速度 @OPhoat6bQ06L3fD9DBb-8Q > I suggest naming this as 'state' here instead of 'dynamics' because 'dynamics' is associated with force input. > [name=eason27271563] ```cpp /*---- in Inc/Datatype/dynamics.h ----*/ struct Dynamics { geometry::Vector position; Quaternion orientation; Kinematics velocity; Kinematics acceleration; } ``` >### Notes: Other Datatypes in Dynamics >#### 1. **geometry::Vector** > cf: [geometry_msgs/Vector3.msg](http://docs.ros.org/en/api/geometry_msgs/html/msg/Vector3.html) > ```cpp > /*---- in Inc/Datatype/vector.h ----*/ > > namespace geometry > { > struct Vector > { > float x; > float y; > float z; > } > } > ``` > >#### 2. Kinematics > ```cpp! > /*--- in Inc/Datatype/dynamics.h ---*/ > > struct Kinematics > { > geometry::Vector linear; > geometry::Vector angular; > } > ``` > >#### 3. Quaternion > ```cpp! > /*--- in Inc/Datatype/quaternion.h ---*/ > > struct Quaternion > { > float x,y,z,w; > > normalize(); > // operator overloading functions > // ....(略) > } > ``` --- ### In main.cpp ```cpp= /*-- parameters --*/ float desired_depth = 0.5; float yaw_sonar = 0; // yaw angle from sonar (from rpi) geometry::Vector ex = {2,0,0}; // position error geometry::Vector ev = {0}; // velocity error // arm motor rotate angle int arm_angle[3] = {0,0,0}; //-90 ~ 90 ``` ```cpp= /*-- in main --*/ //sensors Mpu9250 imu; Bar02 depth_sensor; //Dynamics Dynamics state = {0}; Kinematics control_input = {0}; //x,y,z direction force and moment //Controller Controller controller({1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.5, 1, 1.5}, {1, 1, 0}, 0); // set Kx, Kv, KR value (tuning) and Omega(how much we trust sonar yaw angle) // Motor Propulsion Propulsion_Sys propulsion_sys; // Robot arm Robot_Arm arm; //Sensor imu.set(&hspi2, GPIOB, GPIO_PIN_12); if (!depth_sensor.set(&hi2c1)) return -1; //Controller imu.update(state); controller.set(state.orientation); //Output propulsion_sys.set_timer(&htim2, &htim8); arm.set(&htim4, arm_angle); ``` ```cpp! /*-- in while loop --*/ imu.update(state); //depth sensor depth_sensor.read_value(); ex.z = desired_depth - depth_sensor.depth(); //controller controller.update(state, ex, ev, yaw_sonar, control_input); // allocate and output propulsion_sys.allocate(control_input); ``` in while loop: - imu update 角速度 & orientation(目前姿態 in quaternion) - depth sensor update 深度 (ex.z) - controller update: 更新 state & 計算 control_input - 透過 allocation matrix 將 control input 得出的推力 輸出到馬達 > #### **imu update 角速度** > - use Madgwick filter to filter raw data (get angular velocity) > - use gradient decent to calculate quaternion [Madgwick filter + gradient decent code](https://github.com/NCTU-AUV/SAUVC2022_STM32/blob/db67a90fe94ebd8ff7e9ab33753e01a6a03ac308/Core/Src/Sensor/Adafruit_AHRS_Madgwick.cpp#L190) > > Note: if imu change direction => change q_ItoE in constructor > > #### depth sensor update > - update depth error (desired depth predefined) > [more depth sensor details](https://hackmd.io/HYQ-6N19SjCVHs9AClE5Mw?view) > #### controller update > - Details: [geometry controller](https://hackmd.io/yPEXwDbLRkayKPhvLadm6Q?view) > > Note: ex(位置),ev(速度), eR(姿態), eOmega(角速度) 誤差 > 類似: > ![](https://hackmd.io/_uploads/rkCqZf_dh.png) --- Notes: - ex, ev, yaw from rpi ![](https://hackmd.io/_uploads/B1fF8EuO2.png) Problems: - 目前 state 的即時位置(座標)沒有更新 (因為ex, ev從 Rpi 來) - ev 的來源 (暫無DVL)