OPNET学习小记(八)之簇通信
标签:
仿真学习cluster通信 |
分类: OPNET学习笔记【原创】 |
自己搭的一个簇通信模型:http://s12/mw690/78801cf7zx6BhVCNNTJbb&690
网络拓扑
http://s15/mw690/78801cf7tx6BiMlXusmce&690
仿真结果(发送端记录)
http://s14/mw690/78801cf7tx6BiNvAQl79d&690
仿真结果(接收端记录)
第一个图就是仿真的网络拓扑结构,一共就6个节点,3个一组为一个cluster,由node_0先产生数据并通知簇内节点node_1和node_2将通信模式由“禁止通信”调整为“簇内通信”,编码后封装到包格式LT_AODV_DATA_CLUSTER中,然后将包发给node_1和node_2(这个应该算是组播了吧~),node_1和node_2接收数据包后译码,在确认译码成功后,node_1和node_2更改自身通信模式为“簇间通信”,并通知目的节点node_4和node_5将通信模式启动为“簇间通信”(node_1给node_4发包,node_2给node_5发包)。开始发包,这里就要用到路由协议了,我用的是AODV协议,MAC层用的是OPNET自带的wlan_mac协议。node_4和node_5接收数据包并译码成功后,将信息进行存储,然后将通信模式更改为“禁止通信”并通知node_1和node_2将通信模式更改为“禁止通信”以避免无休止的发包造成能量耗损。
小结一下这段时间遇到的问题。
(一)函数op_id_from_name()的使用
关于获取某个指定节点或是进程的id以前觉得用不着就没看,现在用到了才到处search,查来查去发现主要就是函数op_id_from_name()的使用。具体来说,这个函数的格式应该是这样的:op_id_from_name(parent_id,model_type,model_name)。举个例子来说,如果要查找一个名为“4”的节点id,那其父对象id就应该是其所在子网的id,节点类型分好几种:OPC_OBJTYPE_NDFIX(固定节点)、OPC_OBJTYPE_NODE_MOB(移动节点)、OPC_OBJTYPE_NDSAT(卫星节点)等,当然为了防止不必要的错误,有一个笨办法就是用op_id_to_type()这个函数,具体用法为op_id_to_type(op_parent_id(op_id_self()))来获取目标节点的类型,当然,前提是自身节点和目标节点类型是相同的。如果要查找某个进程的id也是一样的道理,下面这个例子就是查找名为“cluster_appl”的进程id,前提是要先找到该进程的父id也就是所属节点的id。
http://s3/mw690/78801cf7tx6BiMpjn0e62&690
对了,关于查找进程id有个小问题需要说明一下:
因为在应用层我用到的进程模型是LT_appl_cluster.pr.m,所以一开始查找某个节点的LT_appl_cluster进程id时,将程序写为:target_proc_id=op_id_from_name (target_node_id, op_id_to_type(my_id),"LT_appl_cluster");这么写是得不到想要的id的,目标进程的名称应该是节点模型中为其所在processor(不知道该怎么描述,先这么叫着吧)标注的名称,如下图所示。
http://s9/mw690/78801cf7tx6BiIW3nLid8&690
(二)关于动态设置模块属性的问题
对于某些需要在整个节点模型内共用的属性,需要在节点的Model
Attributes中进行设置,如下图所示:
http://s8/mw690/78801cf7tx6BiMoTYLt37&690
http://s5/mw690/78801cf7tx6BiMpFUdS84&690
扯远了,现在说一下属性值的动态设置。
如果某个属性值需要动态设置,那就不要将其Add至仿真配置Object Attributes中,可以在Model Attributes先给其预设一个初值,就是所谓的default value,然后就是用op_ima_obj_attr_set()和op_ima_obj_attr_get()这两个函数的问题了。
值得注意的一点是,如果某个属性被动态修改了,下一次需要用到该属性值时,需要通过op_ima_obj_attr_get()对属性值重新读取。
(三)关于ICI的使用
ICI的用法简单来说就以下几步:
发送端:
1)自定义一个ICI格式;
2)在程序中创建ICI:op_ici_create();
3)设置ICI中的属性值:op_ici_attr_set_int32();
4)将ICI绑定至某个中断:op_ici_install();
5)产生仿真中断:op_intrpt_schedule_remote():
接收端:
1)获取ICI:op_intrpt_ici();
2)读取ICI中携带的属性值:op_ici_attr_get();
3)销毁ICI:op_ici_destroy();
以前总觉得ICI跟Packet差不多:都是得先创建自定义的格式、都是用来携带某些信息、用完都得销毁……既然都有Packet了,为什么OPNET还要开发ICI?现在想想,ICI确实具有Packet不具备的优势,举个简单的例子:某个节点想要通知另一个节点开始通信,用数据包通知当然可以,但是比较麻烦,离得近还好,离得远了还得用路由协议,还得考虑信道拥挤、数据包冲突一系列问题,等目标节点收到消息都不知何年何月了。这时ICI就派上用场了,只要知道目标节点应用层的的id,启用一个远程中断发送ICI就行。
(四)几点启示
Point 1.
http://s8/mw690/78801cf7tx6BiLlG65p87&690
http://s6/mw690/78801cf7tx6BiMpf7BH55&690
Point
2.
http://s1/mw690/78801cf7tx6BiLlWVS8a0&690
http://s11/mw690/78801cf7tx6BiMQGW9Q3a&690

加载中…