加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

OPNET学习小记(八)之簇通信

(2013-07-24 08:58:29)
标签:

仿真

学习

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


    属性在节点模型中设置后会被提升到网络层的属性中,如果网络内节点的这些属性值彼此不相同,右击节点选“属性”一项直接分别设置值即可,如果网络内所有节点的某个属性都是同一个值,就不用那么麻烦了,可以在仿真配置中的Object Attributes中统一设置,当然前提是要把设置的属性Add一下。

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


    其实这就是个小错误,就是在定义Packet变量时格式出错了。如下图所示:

http://s6/mw690/78801cf7tx6BiMpf7BH55&690

Point 2.

http://s1/mw690/78801cf7tx6BiLlWVS8a0&690


    虽然出了这么一堆错误,但还是个小问题,就是在状态转移条件中多打了一个空格~~~~~

http://s11/mw690/78801cf7tx6BiMQGW9Q3a&690
    Point 3.这个很有用!如果在仿真初始化阶段就要发送远程终端的话,最好给这个远程中断加一个延时(比如说5s),不然目标进程是结收不到这个远程中断的。具体原因我也不知道,仿真的时候遇到了这个问题,用ODB查看发现对方压根儿就没收到远程中断,猜想可能是初始阶段进程在初始化,还没有到达能够响应中断的idle状态,就给中断加了个延时。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有