计算机仿真中的HLA技术中的餐馆例子分析 (4) Consumption

本文详细分析了HLA技术在计算机仿真中的应用,以Consumption联邦为例,阐述了其运行流程。主要内容包括设置时间推进、对象类和属性的发布与订阅、事件处理及时间循环等。在时间推进主循环中,通过内部事件队列管理和RTI回调处理外部事件,实现对Serving对象实例的属性更新和所有权转移,从而完成仿真过程。
摘要由CSDN通过智能技术生成

相比起来,Consumption联邦与Production联邦很相似,都采用NER方式推进时间,其lookahead也都是0.01。

 

程序结构也非常相似。

 

Consumption联邦也由多个java文件组成。包括:Consumption.java, ConsumptionFrame.java,ConsumptionInternalError.java,  ConsumptionNames.java, FedAmbImpl.java (consumption)。

其中,frame是GUI类,FedAmbImpl包括所有回调函数。

--------------------------------------------------------------------------------------------------------------------------------------

 

主函数很简单

 

 

  public static void main(String[] args) {

 Properties props = parseArgs(args);

    loadProperties(props);

    Consumption consumption = new Consumption(props);

    consumption.mainThread();

  }

 

主要功能是从命令行或者配置文件中读取相关参数,产生Consumption对象,运行mainThread线程

---------------------------------------------------------------------------------------------------------

 

主要的功能都在mainThread函数中

 

(1)取得相关配置信息,判断是否有federation execution实例运行,没有则创建,然后加入join

 

(2)设置时间受限和时间调节。这里首先设置了时间受限,同时在设置时间受限和时间调节时,使用了barrier机制来协调各个线程(barrier机制在例子中多次使用,这里不讨论其细节)。

 

(3)获取相关对象类,属性,交互类的handle,存储下来以备后续使用。--getHandles();

 

(4)发布对象类及其相关属性,

 

    //publish Serving position because we'll update it

    _rti.publishObjectClass(_ServingClass, _positionAttributeAsSet);

    //publish Diner class because we register them

    _rti.publishObjectClass(_DinerClass, _DinerAttributes);

    //publish the interaction because it's our job to send it

    _rti.publishInteractionClass(_SimulationEndsClass);

 

显然, 发布对象包括Serving类及其position属性,Dinner类及其属性, 发布SimulationEnds交互类。注意,Serving对象类被多个联邦发布,consumption联邦发布Serving对象类,因为该联邦将从Transport联邦获取Serving对象类某实例的position属性的所有权。

 

(5)订阅对象类及其相关属性,

 

 

    _rti.subscribeObjectClassAttributes(_BoatClass, _BoatAttributes);

    _rti.subscribeObjectClassAttributes(_ServingClass, _positionAttributeAsSet);

 

 

订阅包括Boat对象类及其属性,Serving对象类及其属性。

 

(6)处理第一个同步点ReadyToPolulate,发出同步点已经achieved请求。使用barrier机制阻塞线程,结束阻塞后输出已经同步信息。

 

(7)调用makeInitialInstances函数,根据numberofDiner进行循环,循环体如下:

       {

       构造dinername和position,获取dinerHandle(同时注册diner对象类的实例),将diner对象加入local table中

 

       _dinerTable.add(

        dinerHandle,

        dinerName,

        position,

        Diner.LOOKING_FOR_FOOD,

        "",

        0);

 

      更新相应对象类实例的属性值:

 

      LogicalTime sendTime = new LogicalTimeDouble(0.0);

      sendTime.setTo(_logicalTime);

      sendTime.increaseBy(_lookahead);

      EventRetractionHandle erh =

        _rti.updateAttributeValues(dinerHandle, sa, null, sendTime);

 

 

      填充相应的_consumptionTimes[serial]数组元素

     } //循环结束

 

(8)处理第二个同步点ReadyToRun,发出同步点已经achieved请求。使用barrier机制阻塞线程,结束阻塞后输出已经在该同步点同步的信息。

 

(9)调用rti函数enableAsynchronousDelivery,目的是instructs the LRC to begin delivering receive-ordered events to the federate even while no time-advancement service is in progress,其实就是consumption这个时间受限联邦成员要求在时间批准状态下也能接收RO事件。

 

(10)进入时间推进的主循环。循环结束条件是该联邦收到simulationEnds交互。基本的消息循环流程:consumption联邦收到的所有RTI的回调都会进入callbackQueue排队。然后在消息循环里面逐一取出消息来处理。

 

下面是主循环代码:

 

 

    timeLoop:

      while (!_simulationEndsReceived) {

        _userInterface.setTimeStateAdvancing();

        LogicalTime timeToMoveTo = _internalQueue.getTimeAtHead();

        //_userInterface.post("NER to " + timeToMoveTo);

        _rti.nextEventRequest(timeToMoveTo);

        //process all the events & callbacks we receive from the RTI

        boolean wasTimeAdvanceGrant;

        do {

          Callback callback = _callbackQueue.dequeue();

          wasTimeAdvanceGrant = callback.dispatch();

          //_userInterface.post("After dispatch " + _logicalTime);

        } while (!wasTimeAdvanceGrant);

        updateInternalStateAtNewTime();

        if (_simulationEndsReceived) break timeLoop;

        //process callbacks not requiring advance while in granted state

        while (!_dinerTable.isTimeAdvanceRequired()) {

          Callback callback = _callbackQueue.dequeue();

          callback.dispatch();

        }

     }

 

 

主循环流程解释如下:

 

while(没有收到simulationEnds交互) 

{

    界面显示联邦开始时间推进;

     从_internalQueue队列中取出队头事件所包含的时间(对consumption联邦而言,只有获得某Serving的所有权之后,才会在_internalQueue中插入一个FinishEatingSushiEvent,这个evnet所附带的时间是_logicalTime+某diner吃完这个sush的平均时间);

     请求时间推进NER到上一条语句所取出的时间上,对consumption联邦而言,其实就是取出某diner吃完一个sushi后的logicTime时间。

     do{

           从callbackQueue中取出一个事件,返回给callback对象;

           调用callback对象的dispatch函数,返回一个布尔量wasTimeAdvanceGrant

           判断是否收到_simulationEnds交互,如果收到,退出循环;

     while (!wasTimeAdvanceGrant);

————————————————————————————————————————————————checkInternalQueue()函数

     从internalQueue中取出(并删除)所有小于等于当前时间的事件处理掉,此例中就是取出可能的FinishEatingSushiEvent,并开始调用RTI函数attributeOwnershipAcquisition请求删除该Serving实例:

      _rti.attributeOwnershipAcquisition(

        _dinerTable.getServing(_diner),

        _privilegeToDeleteObjectAttributeAsSet,

        null);

     后面在AOAN的dispatch函数中,判断ownership是否得到,如果得到,则开始删除该Serving

        else if (_attributes.equals(_privilegeToDeleteObjectAttributeAsSet)) {

          finishDestroyingServing();

        }

 

    并更新某diner的状态;  --checkInternalQueue()函数

————————————————————————————————————————————————checkInternalQueue()函数

    更新_dinerTable中的diner对象类实例信息,并调用rti.updateAttributeValues(diner._handle, sa, null, sendTime);在联邦中更新diner对象实例信息。

    根据当前_servings中所有的sushi信息,发送updateAttributeValues请求或者直接删除对象实例_rti.deleteObjectInstance(serving._handle, null, sendTime);

    判断是否消耗了足够多的sushi,如果足够多,则发出SimulationEnds交互。

}        

 

(11)处理第三个同步点ReadyToResign,发出同步点已经achieved请求。使用barrier机制阻塞线程,结束阻塞后输出已经在该同步点同步的信息。然后结束该联邦的运行。

---------------------------------------------------------------------------------------------------------------------------

下面从consumption运行的log文件来进行动态分析

 

RTIambassador created

Federation execution restaurant_1 already exists.

Joined as federate 5

Enabling time constraint...

...constraint enabled at time<0.0>

Enabling time regulation...

...regulation enabled at time<0.0>

Waiting for ReadyToPopulate...

�5.10)startRegistrationForObjectClass:3

�5.12)turnInteractionsOn:4

�5.10)startRegistrationForObjectClass:7

...federation synchronized.

Waiting for ReadyToRun...

...federation synchronized.

//之前无话,跟前面的联邦运行情况基本相同,尤其跟production基本类似。

 

NER to time<INF> 

// 进入时间推进循环,明显看到刚开始时,_internalQueue中没有事件,因此返回的推进时间是INF,即寻求推进到结束时间

 

This is DiscoverObjectInstanceCallback's dispatch  B_3_0   105

Discovered Boat 105(B_3_0)

This is DiscoverObjectInstanceCallback's dispatch  B_3_1   113

Discovered Boat 113(B_3_1)

This is DiscoverObjectInstanceCallback's dispatch  B_3_2   114

Discovered Boat 114(B_3_2)

This is DiscoverObjectInstanceCallback's dispatch  B_3_3   115

Discovered Boat 115(B_3_3)

This is DiscoverObjectInstanceCallback's dispatch  B_3_4   116

Discovered Boat 116(B_3_4)

This is DiscoverObjectInstanceCallback's dispatch  B_3_5   118

Discovered Boat 118(B_3_5)

This is DiscoverObjectInstanceCallback's dispatch  B_3_6   120

Discovered Boat 120(B_3_6)

This is DiscoverObjectInstanceCallback's dispatch  B_3_7   121

Discovered

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值