---
# System prepended metadata

title: AUV control on stm32
tags: [控制組]

---

# 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)


