999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于S?函數的Simulink與VC++網絡通信研究

2013-04-12 00:00:00周濤
現代電子技術 2013年13期

摘 要: 為了解決Simulink與VC++的數據交互問題,提出了采用C++語言S?函數實現兩種開發環境的網絡通信方法。首先介紹了S?函數以及基于S?函數的編程框架,其次介紹了UDP網絡程序設計模型。最后結合實例說明并驗證了該方法的有效性和實用性。

關鍵詞: S?函數; Simulink; VC++; UDP

中圖分類號: TN711?34 文獻標識碼: A 文章編號: 1004?373X(2013)13?0108?04

Research on network communication between Simulink and VC++ based on S?function

ZHOU Tao

(Xi’an Aircraft Industry (group) Company Ltd., AVIC, Xi’an 710089, China)

Abstract: In order to solve the problem of data interaction between the Simulink and Visual C++, a network communication method utilized the S?function of C++ language to realize the two developing environment. The S?function, the programming framework based on it and the design model of UDP network programming are introduced. the effectiveness and the practicability of this method are proved with examples.

Keywords: S?function; Simulink; VC++; UDP

0 引 言

Simulink是Matlab的重要組件之一,具有強大的系統建模和動態仿真能力,而VC++是Microsoft推出的可視化編程環境,具有豐富的Windows API,可以開發友好的人機界面,而且運行穩定高效。實際應用中經常會結合兩者的優勢,進行聯合仿真,其中必然存在兩種開發環境的網絡通信問題,本文采用S?函數(System Function,系統函數)構建一個單獨的通信模塊,通過C++的Socket通信來實現Simulink與VC++的數據交互,并結合實例對該方法進行了驗證。

1 S?函數簡介

S?函數是Simulink環境下的功能擴展機制,能有效提高和豐富Simulink的功能。S?函數提供了一種用Matlab、C、C++或者FORTRAN等多種計算機語言描述Simulink模塊的方法,將上述計算機編寫的S?函數用MEX工具編譯產生MEX文件。S?函數中用一種特定的回調語法,使用戶可以和Simulink Engine交互,此類交互和Simulink內置模塊與Engine間的交互極為相似。這種回調語法稱為S?函數API。

2 基于S?函數的編程框架

C++語言S?函數采用標準C++語言規范,并且產生可獨立運行的MEX文件。 C++語言的S?函數的編寫采用回調函數的方式, Simulink Engine在不同的仿真階段調用相應的回調函數,執行指定的任務。Matlab提供了S?函數的編程模板,指定了標準的回調方法,只需在其中加入特定的功能代碼即可。其基本框架和對應的回調方法如圖1所示。

<\\192.168.0.25\$d\8月\8-2\補\補!現代電子技術201313\Image\26t1.tif>

圖1 S?函數編程基本框架

3 UDP網絡程序設計模型

本文采用基于UDP的客戶機/服務器通信模式實現Simulink與VC++的數據交互,Simulink的S?函數模塊作為客戶機進行仿真數據的發送,VC++作為服務器接收數據并實時顯示。進行UDP通信時,客戶端與服務器端所使用的函數基本相同,其工作流程如下:

(1)使用WSAStartup ()函數檢查系統協議棧的安裝情況;

(2)使用socket()函數創建套接口;

(3)使用bind()函數將創建的套接口與本地地址綁定;

(4)使用sendto()函數發送數據,也可以使用redvform()函數接收數據;

(5)使用closesocket()函數關閉套接口;

(6)最后調用WSACleanup()函數,結束Windows socket API 的使用。

程序工作流程如圖2所示。

<\\192.168.0.25\$d\8月\8-2\補\補!現代電子技術201313\Image\26t2.tif>

圖2 UDP客戶機/服務器程序工作流程

4 驗證實例

此實例利用Simulink航空模型庫中的HL20自動著陸演示模型作為數據源,用來驗證Simulink和VC++之間的數據收發過程。首先,在Simulink的User? Defined Functions庫中選擇S?Function添加到模型中,將S?Function name 改為UDPclient,然后,新建一個名為UDPclient.cpp的C++文件,在其中利用C++語言按照S?函數編程模板進行UDP客戶端程序設計。將HL20演示模型進行適當的裁剪后,利用其輸出海拔高度,并接入S?函數模塊的輸入端口,再將輸出端口連接到Scope模塊。同時,在VC++中進行服務器端程序設計,并進行數據的實時顯示。最后,將Scope顯示的數據與VC++收到的數據進行對比,以驗證網絡通信的正確性。其模型框圖如圖3所示。

以下分別說明在S?函數模塊和VC++中如何實現客戶端和服務器端代碼。

<\\192.168.0.25\$d\8月\8-2\補\補!現代電子技術201313\Image\26t3.tif>

圖3 實例模型框圖

4.1 客戶端實現

首先,定義用于數據發送的結構體類型,同時,此結構體將用于服務器端用來接收數據,而且形式要完全一致,其具體格式如下:

typedef struct FlighData_tag{

double longitude; //經度

double latitude; //緯度

double altitude; //海拔高度

double phi; //橫滾

double theta; //俯仰

double psi; //偏航

}FlightData;

然后按照S?函數基本編程框架進行客戶端程序設計,具體步驟如下:

(1)在初始化回調方法中進行尺寸特性信息的設置,如I/O端口數目和端口寬度、采樣時間數目、工作向量數目等,主要代碼如下:

static void mdlInitializeSizes(SimStruct *S)

{

// 指定I/O端口

if (!ssSetNumInputPorts(S, 1)) return;

//設置輸入端口數目

ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED);

//設置輸入端口寬度

ssSetInputPortDirectFeedThrough(S, 0, 1);

//設置是否直接饋通

if (!ssSetNumOutputPorts(S,1)) return;

//設置輸入端口數目

ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED);

//設置輸出端口寬度

ssSetNumSampleTimes(S, 1); //設置采樣時間數目

ssSetNumPWork(S, 2); //設置指針工作向量數目

}

(2)在初始化采樣時間回調方法中設置采樣時間和偏置時間,主要代碼如下:

static void mdlInitializeSampleTimes(SimStruct *S)

{

ssSetSampleTime(S,0,INHERITED_SAMPLE_TIME);

//設置采樣時間

ssSetOffsetTime(S, 0, 0.0); //設置偏移量

}

(3)在仿真啟動回調方法中執行內存分配、設置用戶數據等在仿真開始時S函數需要初始化的相關操作,在仿真整個過程中只執行一次,主要代碼如下:

static void mdlStart(SimStruct *S)

{

WSADATA wsaData;

SOCKET *pSendSocket = new SOCKET; //客戶端套接口

*pSendSocket = INVALID_SOCKET;

sockaddr_in *pRecvAddr = new sockaddr_in;

//服務器端地址

unsigned short Port = 27015; //端口號

printf(\"Start socket communication, please wait...\n\");

//初始化套接口

WSAStartup(MAKEWORD(2, 2), wsaData);

//創建客戶端套接口用于發送數據

*pSendSocket = socket(AF_INET, SOCK_DGRAM, IPPRO TO_UDP);

//設置服務器端地址結構,并指定IP地址和端口號,假設遠 程終端地址為“192.168.1.1”

pRecvAddr?>sin_family = AF_INET;

pRecvAddr?>sin_port = htons(Port);

pRecvAddr?>sin_addr.s_addr = inet_addr(\"192.168.1.1\");

//設置指針工作向量數值

ssSetPWorkValue(S, 0, pSendSocket);

//設置指針工作向量的第一個元素為指向客戶端

套接口的指針

ssSetPWorkValue(S, 1, pRecvAddr);

//設置指針工作向量第二個元素為指向服務器端

地址的指針

}

(4)在主輸出回調方法中從輸入端口獲取數據,在此方法中通過指針訪問輸入信號,這樣輸入數組指針可以指向存儲器中的非相鄰單元。Simulink engine周期調用此方法將數據輸出到服務器端。主要代碼如下:

static void mdlOutputs(SimStruct *S, int_T tid)

{

//獲取I/O端口數據地址

InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S,0);

//獲取輸入端口指針向量的指針

real_T *y = ssGetOutputPortRealSignal(S, 0);

//獲取輸出端口向量的指針

int InputNum = ssGetInputPortWidth(S, 0);

//獲取輸入端口的寬度,即指針向量元素個數

for(int i=0;i

{

y[i] = *u[i];

//依據輸入端口寬度,將輸入端口數據輸送到輸出端口

}

FlightData SendBuf; //定義結構體變量

//通過指針工作向量獲取客戶端接口的指針

SOCKET *pSendSocket = static_cast(ssGetPWork(S)[0]);

//通過指針工作向量獲取指向服務器端地址的指針

sockaddr_in *pRecvAddr = static_cast(ssGetPWork(S)[1]);

//發送數據包到服務器端

SendBuf.altitude = y[0]; //作為示例僅發送高度數據

sendto(*pSendSocket,(char*)SendBuf,sizeof(FlightData,(SOCKADDR*)pRecvAddr, sizeof(sockaddr_in));

//向服務器端發送數據包

}

(5)在仿真終止回調方法中,關閉套接口并釋放內存資源,主要代碼如下:

static void mdlTerminate(SimStruct *S)

{

SOCKET *pSendSocket = static_cast(ssGetPWork(S)[0]);

sockaddr_in *pRecvAddr = static_cast(ssGetPWork(S)[1]);

//發送數據結束,關閉套接口

printf(\"Finished socket communication, Closing socket.\n\");

closesocket(*pSendSocket) ;

//釋放資源并退出

WSACleanup();

delete pSendSocket;

pSendSocket=NULL;

delete pRecvAddr;

pRecvAddr=NULL;

}

經過以上步驟就完成了S?函數模塊客戶端程序,然后在Matlab的命令窗口輸入如下命令:MEX UDPclient.cpp, 如果程序沒有編譯錯誤,就會生成擴展名為mexw32的MEX文件,此文件可在Simulink環境中執行,用來將HL20自動著陸模型輸入的高度數據發送到服務器端,Scope模塊顯示輸出的數據,經測試S?函數模塊輸出的高度數據如圖4所示。

<\\192.168.0.25\$d\8月\8-2\補\補!現代電子技術201313\Image\26t4.tif>

圖4 S?函數模塊輸出的高度數據

4.2 服務器端實現

在VC++6.0開發環境下,建立基于對話框的MFC應用程序,在其中添加NTGraph控件用于高度數據的顯示,主要代碼模塊及功能如下:

(1)首先,在類聲明文件中進行用于數據接收的結構體定義,此結構體應與客戶端定義的結構體完全一致,其次,聲明用于UDP服務器端的相關變量,并在構造函數中進行初始化。

(2)在OnInitDialog()函數中進行NTGraph控件的初始化,設置[X]軸和[Y]軸坐標以及其他顯示屬性。

(3)在OnCreate()函數進行定時器的設定和UDP網絡設置,主要代碼如下:

int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

……

SetTimer(0, 1, NULL); //設置定時器,用于數據接收

//初始化套接口

WSAStartup(MAKEWORD(2, 2), wsaData);

//創建套接口用于接收數據報

socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

//指定地址與端口并與套接口綁定

RecvAddr.sin_family=AF_INET;

RecvAddr.sin_port=htons(Port);

RecvAddr.sin_addr.s_addr=htonl(INADDR_ANY);

bind(RecvSocket, (SOCKADDR *) RecvAddr, sizeof (RecvAddr));

return 0;

}

(4)在OnTimer()函數周期接收從Simulink發送的數據報,并解析出高度數據,主要代碼如下:

void CTestDlg::OnTimer(UINT nIDEvent)

{ ……

FlightData RecvBuf; //聲明數據接收結構體變量

memset((char*)RecvBuf,0,sizeof(FlightData));

//重置接收緩沖區

recvfrom(RecvSocket,(char*)RecvBuf, sizeof(FlightData), 0,

(SOCKADDR *) SenderAddr, SenderAddrSize);

//接收數據包

m_Graph.PlotY(RecvBuf.altitude,0);

//在控件中顯示高度數據

……

}

(5)最后在OnDestroy()函數中關閉套接口,并釋放資源,主要代碼如下:

void CTestDlg::OnDestroy()

{

……

//接收完數據包,關閉套接口

closesocket(RecvSocket);

//釋放資源并退出

WSACleanup();

}

經過編譯、鏈接成功后,在Simulink環境下啟動HL20自動著陸演示模型,同時運行VC++生成的EXE可執行文件,NTGraph控件將實時顯示高度數據,展示整個著陸過程,可以看到它與Scope 模塊顯示的數據曲線完全一致,成功實現了Simulink與VC++之間的UPD網絡通信。VC++接收的高度數據如圖5所示。

<\\192.168.0.25\$d\8月\8-2\補\補!現代電子技術201313\Image\26t5.tif>

圖5 VC++接收的高度數據

5 結 語

利用Simulink與VC++各自的優勢進行聯合設計,特別是動態分布式仿真中具有實際意義,兩種開發環境之間的數據通信是必須要解決的問題。本文提出了利用C++語言的S?函數,在仿真模型中連接S?函數模塊,并利用基于Socket的網絡編程模型實現數據通信,簡單而且靈活,對利用Simulink和VC++進行聯合分布式仿真具有一定的借鑒意義。

參考文獻

[1] 劉杰.基于模型的設計及其嵌入式實現[M].北京:北京航空航天大學出版社,2010.

[2] 任泰明.TCP/IP網絡編程[M].北京:人民郵電出版社,2009.

[3] [美]李普曼,[美]拉茹瓦,[美]穆.C++ Primer中文版[M].李師賢,譯.4版.北京:人民郵電出版社,2006.

[4] [美] PROSISE J. MFC Windows程序設計[M].北京博彥科技發展有限公司,譯. 2版. 北京:清華大學出版社,2007.

[5] 侯浩亮,姚新宇,馮曉梅,等.C MEX S函數在Simulink中的應用[J].微計算機信息,2010(19):140?141.

[6] 馬強,岳妍瑛,王歡,等.一種基于模式挖掘的網絡通信安全方法研究[J].現代電子技術,2012,35(17):78?82.

主站蜘蛛池模板: 中文字幕av无码不卡免费| 天天婬欲婬香婬色婬视频播放| 精品视频在线观看你懂的一区 | 青青青国产精品国产精品美女| 久996视频精品免费观看| 国产内射一区亚洲| 久久久受www免费人成| 成人免费视频一区| 中文字幕 欧美日韩| 久久无码高潮喷水| 亚洲无码电影| 国产91色在线| 免费一级全黄少妇性色生活片| 亚洲成A人V欧美综合| 亚洲精品无码不卡在线播放| 亚洲精品国产成人7777| 欧美日在线观看| 1级黄色毛片| 99视频全部免费| 亚洲欧洲国产成人综合不卡| 午夜国产精品视频| 欧美日韩国产在线人| a欧美在线| 欧美午夜视频在线| 看av免费毛片手机播放| 亚洲人成网址| 国产乱子伦手机在线| 久久综合婷婷| 欧美亚洲国产精品第一页| 国产va在线观看| 麻豆国产在线观看一区二区| 激情亚洲天堂| 2021最新国产精品网站| 国产三级国产精品国产普男人| 波多野结衣一二三| 3344在线观看无码| 中文无码日韩精品| 亚洲国产精品成人久久综合影院 | 男女男免费视频网站国产| 欧美日韩中文国产va另类| 欧美中文字幕一区| 在线一级毛片| 亚洲日韩国产精品无码专区| 亚洲国产日韩在线成人蜜芽| 国产免费好大好硬视频| 国产剧情国内精品原创| 青青操国产| 国产精品午夜电影| 日韩高清欧美| 国产精品30p| 亚洲综合狠狠| 自慰高潮喷白浆在线观看| 色噜噜综合网| 亚洲欧美天堂网| 日本精品视频一区二区| 一本久道久久综合多人| 日本欧美视频在线观看| 香蕉在线视频网站| аv天堂最新中文在线| 一级毛片免费观看久| 免费一级毛片| 天天综合色网| 国产在线啪| 青青久久91| 无码AV动漫| 国产人成乱码视频免费观看| 国产SUV精品一区二区6| 欧美啪啪精品| 免费国产无遮挡又黄又爽| 国产成人调教在线视频| 91麻豆精品国产91久久久久| 国产成人免费视频精品一区二区| 欧美午夜在线视频| 幺女国产一级毛片| 激情综合网址| 国产哺乳奶水91在线播放| 人妻21p大胆| 制服无码网站| 久久这里只有精品国产99| 国产精品私拍99pans大尺度| 在线国产你懂的| 日韩成人高清无码|