---
# System prepended metadata

title: X plane 模擬環境
tags: [飛控]

---

# X plane 模擬環境
###### tags: `飛控`

| 月份 | 週次(日期)            | 內容                                                   |
| ---- | --------------------- | ------------------------------------------------------ |
| Oct  | I (Oct.10~OctOct.16) | 建立Xplane的環境  |
|      | II (Oct.17~Oct.23)   | 使用UDP連結Xplane,傳輸數據至matlab|
|      | III (Oct.24~Oct.30)  | 連結外部搖桿數據至matlab                                     |
| Nov  | IV (Oct.31~Nov.6)    |建立PID控制器控制姿態                                         |
|      | V (Nov.7~Nov.13)     |debug                  |
|      | VI (Nov.14~Nov.20)   |debug                                                       |
|      | VII (Nov.21~Nov.27)  |先基於Cessna172調整PID參數使姿態                                                       |
| Dec  | VIII (Nov.28~Dec.4)  |定義新飛機氣動外型(TUNA T)                                     |
|      | IX (Dec.5~Dec.11)    |對自訂飛機調整PID控制器                               |
|      | X (Dec.12~Dec.18)    |收集飛行動態資料                                |
|      | XI (Dec.19~Dec.26)   |debug                                         |
|      | XII (Dec.26~Jan.1)   |debug                                                       | 

>[name=紀中威]
>[name=蕭凡棋]


## 安裝Xplane
去到UAV雲端中-工具程式-Xplane10將所有相關東西下載並依序1~9執行一遍
### 使用軟體
#### Xplane 10
#### Matlab 2022b

## 使用UDP連結Matlab

![](https://i.imgur.com/riZD1wb.png)

我們將使用 MATLAB 中 Simullink 透過UDP發送及接收Xplane模擬出來的飛行數據，也可以使用外接控制器去發送控制訊號

本次模擬皆是模擬定翼機，如果要試其他類型可以去
http://www.nuclearprojects.com/xplane/info.shtml

## Sending UDP datagrams
![](https://i.imgur.com/mXGRMfs.png)




---

### Input
![](https://i.imgur.com/riHZFQs.png)


輸入訊號可以使用各種的RC控制器，我是使用Logitech 3D extreme pro
透過UDP訊號輸入直接覆蓋在Xplane10中的操縱輸入
如果要使用Logitech 3D extreme pro 去以下網址下載驅動程式

https://support.logi.com/hc/zh-tw/articles/360024843033--%E4%B8%8B%E8%BC%89-Extreme-3D-Pro

![](https://i.imgur.com/bI9WkNg.png)


可以創建一個scope來監測操縱桿的訊號輸入是否正確

使用過程中怕訊號有出錯，所以我們需要創建一個calibrate block 來設定上下限
roll, pitch, yaw : -1 ~ 1
thrust : 0 ~ 1

---

### Encoding and sending

![](https://i.imgur.com/5c5eQJV.png)

再來我們需要將訊號打包成Xplane 看得懂的訊號，來自控制桿的訊號為 double ，需要先使用Data Type Conversion 轉換成 single 在 轉成 8位無符號整數（uint8）。

![](https://i.imgur.com/pr8T0Lw.png)

將Data Type Conversion block 中的 
Output data type : [Inherit: Inherit via back propagation] 改成 Output data type : [single]


使用Byte pack 將單精度訊號打包成unit8
![](https://i.imgur.com/0XKQlLU.png)


---

#### UDP_encode
![](https://i.imgur.com/GGNgPPT.png)
![](https://i.imgur.com/ahmYyje.png)

可以勾選不同的頻道數量來決定我們需要進行人為控制的參數選項，調整右下的UDP rate 越大發送訊號的頻率會越高，下面11 25的部分就是我們介入pitch, roll, yaw, throttle的部分。Xplane10_Settings_Data inputs and outputs 中可以查看對應數字的控制參數頻道，但隨著版本不一樣可能有所不同



```
function UDP = UDP_encode(roll_single, pitch_single, yaw_single, throttle_single)
DATA = [68 65 84 65 48];
NULL = [0 192 121 196];
UDP_flightcon = [11 0 0 0 pitch_single' roll_single' yaw_single' NULL NULL NULL NULL NULL];
UDP_throttle = [25 0 0 0 throttle_single' NULL NULL NULL NULL NULL NULL NULL];
UDP = [DATA UDP_flightcon UDP_throttle]';
end
```


傳送信號的最後一步，就是將訊號傳到Xplane10裡面，我們需要設定相同的IP address 和對應的port 確保有正確接收，在UDP Send Block 設定address & port ，如果是在同一台電腦上使用的話，可以打127.0.0.1就好，意思就是本台主機，X-Plane 默認接收端口是 49000 ，可以去Xplane 10_Net Connection_Data 中下面查看使用的UDP ports

如果使用不同台電腦，可以去cmd 中打ipconfig 中的IPV4 address 即是電腦IP位址

![](https://i.imgur.com/gRllilp.png)
![](https://i.imgur.com/9KvzjEo.png)

發送成功的話會顯示，表示Xplane 10 成功接收來自simulink 中UDP 發送的訊號
![](https://i.imgur.com/CaRstkM.png)


---

## Receiving UDP datagrams
![](https://i.imgur.com/Kr1W8el.png)
由於Xplane10 中49000 49001 49002 已經被定義使用我們可以將發送端口設置成 49003，


---

### UDP recieve
![](https://i.imgur.com/w549Kx5.png)
![](https://i.imgur.com/nz0ATc5.png)
將UDP Recieve Block 接收IP和address 改成 在Xplane10上面設定的一樣(0.0001改成0.1)

#### **發現**
可以更改UDP recieve block 中的maximum length for message 來更改輸出數據的多寡，
heading  data = 5 bytes
資料長度所選
group of 4 bytes each 
8 fields
![](https://i.imgur.com/cwnhDQ9.png)
已這張圖為例
maximum length for message = 8 * 9 * 4 + 5 = 293

---

### UDP decode
UDP decode 接收來自Recieve 的資料加以整理，輸出我們想要觀測的數據
每個頻道有 36bytes ，每個頻道編號分配 4bytes
```
% X-Plane: Channels 11, 17, 20
%--------------------------------------------------------------------------
% flight_con = [elev ailrn ruddr]; 
% flight controls
% attitude = [pitch roll hding_true hding_mag]; 
% pitch, roll, yaw
% location = [lat lon alt_msl alt_agl]; 
% latitude, longitude, altitude [deg],[ftmsl],[ftagl] (mean sea level, actual ground level)
%--------------------------------------------------------------------------
function [elev, ailrn, ruddr, pitch, roll, hding_true, hding_mag, lat, lon, alt_msl, alt_agl] = UDP_decode(UDP)
% We don't need the DATA header, which are the first 5 bytes
UDP = UDP(6:end);
% We cut the datagram in channels, each containing 36 bytes, 4 for the channel number, and 4 for each of the 8 entries.
CH11 = UDP(1:36);
CH17 = UDP(37:72);
CH20 = UDP(73:108);
%-------------------------
% At last we extract each entry from their channel and output them.
elev = Channel_to_single(CH11,1);
ailrn = Channel_to_single(CH11,2);
ruddr = Channel_to_single(CH11,3);
pitch = Channel_to_single(CH17,1);
roll = Channel_to_single(CH17,2);
hding_true = Channel_to_single(CH17,3);
hding_mag = Channel_to_single(CH17,4);
lat = Channel_to_single(CH20,1);
lon = Channel_to_single(CH20,2);
alt_msl = Channel_to_single(CH20,3);
alt_agl = Channel_to_single(CH20,4);
%---------------------------------
end
function [single] = Channel_to_single(CH, data_pos)
start_byte = 1 + 4*data_pos;
stop_byte = start_byte + 3;
single = CH(start_byte:stop_byte);
end
```

傳出的訊號需要拆封成simulink可以讀取的訊號，加上Byte Unpack 並根據UDP decode 訊號輸出訊號調整數量及訊號型態，輸出的訊號可以用scope 來隨時監測

![](https://i.imgur.com/ilCMSgV.png)
![](https://i.imgur.com/5T3uCZk.jpg)


---

### 將機型換成Cessna 172P 並對輸出數值做調整

**輸出訊號名稱**
1. speed
2. elevator
3. aileron
4. rudder
5. latitude
6. longitude
7. altitude

{%youtube 6dRcyO_HCW4 %}


