1.一种基于XCOS和NS3的协同仿真时间同步方法,含有以下步骤:(1)安装NS3中协同仿真接口;
步骤11:在NS3中安装套接字服务端程序。通过套接字接受SCILAB的同步数据;
步骤12:定义缓冲区,缓存SCILAB同步数据。
(2)安装SCILAB中协同仿真接口;
步骤21:在SCILAB中安装套接字客户端C++程序。利用mexArray指令从SCILAB获取需要发送给服务端的数据,通过套接字发送给NS3;
步骤22:执行命令ilib_mex_build([“接口名”“C++程序文件名”),编译接口程序;
步骤23:执行命令exec loader.sce,链接SCILAB动态库文件,在SCILAB中通过“接口名”即可调用接口程序。
(3)初始化NS3仿真脚本;
新建NS3仿真脚本,在脚本中定义NS3仿真模块,定义初始化函数:节点设置函数、网络拓扑建立函数、信道属性配置函数、网络设备创建函数、网络协议栈安装函数、仿真开始及结束函数,通过NS3协同仿真接口(1)向以上初始化函数传值完成NS3配置;
步骤31:定义并初始化NS3仿真同步周期的步长SimulationStep;
步长在SCILAB中意味着一个采样周期,在一个周期内SCILAB通知NS3运行节点间的收发事件;
步骤32:定义下一个仿真同步时刻TimeLimit,初始值为SimulationStep;
步骤3:定义并初始化仿真时间上限即仿真结束时间SimulationStopTime;
步骤34:定义当前仿真时刻CurrentTime=m_events‑>PeekNext().key.m_ts;
步骤35:定义节点发送时刻SendTime;
在NS3脚本中使用命令GetSendTime()获取节点发送的时刻,赋值给SendTime,并作为数据包内容的第一位发送给SCILAB,使得数据包在整个仿真过程都能携带发送时刻信息。
(4)NS3同步机制设计;
步骤41:定义回跳时间JumpTime=TimeLimit‑SimulationStep‑CurrentTime;
步骤42:寻找可以在当前同步周期内执行完成的最后一个事件的时间。执行命令m_events‑>PeekNext().key.m_ts取下一个事件的结束时刻,判断其是否小于等于TimeLimit。若是,则更新CurrentTime=m_events‑>PeekNext().key.m_ts,执行该事件,并继续取下一个事件,否则,说明当前事件为可以在当前同步周期内执行完成的最后一个事件,此时将TimeLimit移到下一个同步周期点,即TimeLimit+=SimulationStep,并执行步骤23和步骤24与SCILAB同步信息;
步骤43:NS3向SCILAB同步信息。NS3将接受事件中的事件内容,包括时间戳,传感信号,控制量等通过协同仿真接口发给SCILAB;
步骤44:接受SCILAB的同步数据,计算回跳时间,安排新事件。回跳时间JumpTime的计算公式为JumpTime=TimeLimit‑SimulationStep‑CurrentTime,在JumpTime延时之后执行Simulator::Schedule(JumpTime,&UdpEchoClientNew::SendTo,this)更新事件列表,其中&UdpEchoClientNew::SendTo()函数内可自定义一系列发送事件。
步骤45:重复执行步骤22到24,直到TimeLimit>SimulationStopTime,NS3仿真结束。
(5)SCILAB内XCOS控制系统模型搭建;
步骤51:搭建被控对象模型;
在XCOS中使用用户自定义模块scifunc_block_m模块,并在工作区间内新建脚本编写此模块功能。定义此模块的控制量u1,系统输入状态x1,系统输出状态y1,以及系统输出z1。
此模块功能为利用u1和x1,得到离散系统的一步仿真结果y1和z1。模块函数形式为[y1,z1]=plant(x1,u1)。以线性系统为例,函数实现如下:y1=Ax1+Bu1,z1=Cx1+Du1 (1)n*n n*m
其中A、C∈R ,B、D∈R ,为给定矩阵;
步骤52:搭建控制器模型;
使用scifunc_block_m模块创建控制器模块,模块接受NS3仿真输出数据作为输入,数据内容包括时间戳time_stamp,即传感器节点发送时刻,以及传感器信号,记为u2,,控制器模块输出为y2,模块函数形式为[y2]=controller(u2)。函数内容可根据实际控制算法编写,以线性状态反馈为例:
y2=[time_stamp,Ku2] (2)其中K为给定控制增益;
步骤53:搭建执行器模型;
定义变量ut_memory,用来与到达执行器的值比较时间戳(传感器节点发送数据包的时刻),给定初始时间戳为0和初始值的大小,定义变量ut_memory_update,用来更新ut_memory的值。到达执行器的包的内容为控制器处理过的数据包,会先比较含时间戳time_stamp数据包与初始化时存入变量ut_memory的数据大小,选择时间戳大的数据包执行,并将此包保存到ut_memory_update。
(6)协同仿真软件间时间同步机制实现;
步骤61:在SCILAB中给定传感器节点发送给控制器节点的变量C_A_data初值,控制器节点发送给执行器节点的变量S_C_data初值,调用接口程序将变量C_A_data和变量S_C_data的值传递给NS3,NS3会根据接收到的信息安排事件;
步骤62:NS3安排两个发送事件和两个接收事件,完成四个事件后,调用接口程序将仿真结果传送给SCILAB;
步骤63:SCILAB接受NS3的仿真结果,获取仿真结果中当前的仿真时刻,赋值给SCILAB当前时刻变量CurrentTime_SCI;
步骤64:设置状态变量State,将S_C_NS3的值赋给State,完成初始化;
步骤65:获取NS3仿真传感器节点到控制器节点的结果,将包的内容传给变量S_C_SCI,获取NS3仿真控制器节点到执行器节点的结果,将包的内容传给变量C_A_SCI;
步骤66:运行XCOS控制系统模型,获得运行结果即需要NS3下次仿真的安排,即控制器节点发送给执行器节点的包的内容传给变量C_A_NS3,传感器节点发送给控制器节点的内容传给变量S_C_NS3;
步骤67:设置循环体计次变量t,即传感器采样次数;
步骤68:进入循环体,将上次XCOS运行的结果变量C_A_NS3和S_C_NS3传给协同仿真接口程序的接口变量C_A_data和S_C_data,运行接口程序,将SCILAB需要仿真的事件发送给NS3,并接受NS3仿真的结果,存储延迟信息,包的内容更新到变量S_C_SCI和C_A_SCI,在运行XCOS控制系统模型,更新当前仿真时刻CurrentTime_SCI+=SimulationStep,之后将t+=1,进入下次循环,直到达到仿真上限时间;
(7)绘制协同仿真结果图;
步骤72:定义控制系统闭环延时close_loop_delay,数据计算公式如下:close_loop_delay=CurrentTime_SCI‑time_stamp; (3)步骤71:以采样次数t为横坐标,close_loop_delay为纵坐标,使用命令plot(t,close_loop_delay)绘制控制系统传输的延时数据图。