S-Function 允許使用自定義C/C++函數作為傳遞函數,具有可移植性。也可以同樣利用MATLAB函數進行相同的運算,看開發者熟悉程度而定。
項目流程
- 由系統串口接收數據包。
- 通過S-Function自定義函數解析數據包,得到數據集合。
- 數據集合總線輸出,分為各部分數據進行可視化顯示。
串口接收
首先需要通過MPU6050數據手冊將其寄存器的各項輸出數據通過UART讀出,並將其處理為我們所需要的7項參數(加速度Accl. [X,Y,Z],角加速度Gyro. [X,Y,Z],溫度Temp)。
但是這不是本文的重點,因此本文假設已經處理好了上述數據,並且以字符打印的形式通過串口穩定輸出,(通過Rasberry Pico PI預處理)如下:
我們需要配置串口接收參數:
COM口以用戶本機分配為准
Serial Configuration配置如圖
Serial Receive配置如圖
注意,由於是以字符char
接收,因此選擇類型為uint8
,Data Size設置緩沖區大小,此處設為128為例。同樣可以設置數據包頭和數據包尾,我們此處不做設置。
當然,在實際項目中會以更高效率的數據包傳輸,此處僅為示例作用,因此選用字符接收。
S-Function函數示例
從Library Browser中找到User-Defined functions(用戶自定義函數),在系統仿真中這部分是較為常用的。
選擇S-Function Builder,雙擊點開面板。由於是面板端編輯,直接面向對象,邏輯更清晰,但是限制也較多。
填寫函數名,選擇語言C++,即可Build編譯。(初次需要按提示安裝MinGW-w64方可編譯,且安裝目錄不能帶空格)
注意到,編輯器里面有三個子函數,分別封裝S-Function的起始方程,輸出方程和終止方程,在本實例中僅用到輸出的封裝,其他功能請自行學習瀏覽官方示例。
void xxx_Start_wrapper(void);
void xxx_Outputs_wrapper(const real_T *u0, real_T *y0);
void xxx_Terminate_wrapper(void);
注意到,輸入輸出參數都是以數組指針的形式傳參的,帶const
表示輸入參數,不可更改,不帶的即表示輸出參數,可更改。函數的目的是按次調用這三個子函數。
我們可以先調試好C++程序再整合。
在本實例中,輸入參數為大小為128*1的字符數組(uint8
),輸出參數為包括三個參數的總線(Bus:gyroData
),以結構體形式調用。
在自己工程文件中定義頭文件(structure.h
),用於類型的轉換和結構體的定義等,這部分內容是為了便於程序能在本地調試成功,而由於在Simulink中這部分內容已有定義,因此在Simulink的S-Function Builder中編譯的時候是需要將其之注釋掉的。
structure.h
:
#ifndef _STRUCTURE_H
#define _STRUCTURE_H
typedef char uint8_T;
typedef short int16;
struct gyroData{
int16_t accl[3], gyro[3];
double temp;
};
#endif //_STRUCTURE_H
如果不注釋掉,在編譯時會由於變量類型沖突而編譯失敗。
在本地C++工程調試成功,即可移植。
調試成功后,將其移植至S-Function Builder中。
注意參數類型、維度都要一一匹配。需要用到的頭文件和引入文件也需要在include部分添加進來。
如果C++工程包含其他文件,將工程文件目錄添加至INC_PATH
,注意文件目錄最好不要含有空格,否則再次打開時可能會產生修正而出錯。
點擊編譯,提示ERROR: Bus object for output port 1 gyroData does not exist in workspace
,即:總線未被添加至工作區導致編譯失敗。
手動添加的辦法,即打開MODELING中的Bus Editor選項進行添加,注意總線名稱Object Name
以及元素名稱,以及其類型、維度,均設置匹配。當然,也有通過代碼區更方便添加的辦法請自動查閱相關文檔。
添加后請將其保存為.mat
文件方便日后直接將設置好的總線導入。
如果沒有問題,會顯示S-Function編譯成功。
這時,我們可以用S-Function模塊直接填寫函數名,直接調用,模塊會自動產生相應數目的輸入輸出端口,可以供檢查。
(雖然S-Function Builder也可直接使用)
這樣,我們的S-Function就編寫完成。
數據可視化
我們利用Bus Selector模塊進行對總線拆分,用Display模塊顯示文本(數組),用Scope模塊進行示波器圖像繪制,這些屬於基本操作,就不詳加敘述了。
這里提到一個調試的方法,即先使用靜態文本(此處用了字符串常量String Constant)進行調試,確認S-Function功能無誤即可接入動態數據進行觀察。
最后
文章末尾,附上相關的工程文件供參考。
bus_gyroData.mat
gyroData總線getGyroData___
由S-Function生成的函數receive_test.slxc
接收端Simulink工作區面板gyroDataProcess
用於產生S-Function的C++文件
請訪問我的Github URL以下載:https://github.com/Chiron19/Simulink
感謝閱讀!歡迎分享。