65.9K
CodeProject 正在变化。 阅读更多。
Home

HLA 监听器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2015年5月25日

CPOL

7分钟阅读

viewsIcon

27927

downloadIcon

371

HLA 仿真和 HLA 监听器简介

下载 MainFOM.zip

引言

仿真是一种试图在虚拟环境中模仿真实世界的流程。它是一种经济的过程,无需实验设置或特殊设备即可用于测试不同的场景。

仿真有许多类型;今天我将讨论“高层体系结构(HLA)”,它是一种通用的仿真,将虚拟环境分解为独立的组件;每个组件负责特定的任务并具有与其他组件通信的接口。

HLA借鉴了面向对象编程(OOP)的概念;它由一个应用程序(称为联邦)组成,该应用程序又由几个对象(称为联邦成员)组成。与OOP中一样,每个联邦成员执行一些任务并与其他联邦成员交互。然而,在分布式仿真中,每个联邦成员可能运行在不同的机器上,并通过一个中央枢纽(称为RTI)相互通信,如下图所示。

图1 联邦成员通过RTI通信

一段历史

HLA在90年代中期出现在军事领域;但现在它是一个由IEEE规范和发布的标准化仿真。该标准有三个版本

HLA组件

RTI

RTI是HLA标准中的关键组件,它创建联邦并提供联邦成员之间相互通信的基础设施。RTI必须通过实现HLA社区提供的Java和/或C++接口中的所有方法(http://standards.ieee.org/downloads/1516/1516.1-2010/IEEE1516-2010_Java_API.zip)来完全符合标准。

不幸的是,没有完全符合标准的开源RTI。但是,您可以获得两个商业RTI(Pitch RTI、MAK RTI)的免费版本,但每个联邦成员的数量限制为2个。

联邦成员

HLA仿真的第二个关键组件是联邦成员。这是一段引用RTI库的代码,用于与其他联邦成员发送/接收消息。因为所有RTI都实现了相同的接口,所以您可以编写引用RTI库的代码,并且只需更改引用的库即可与其他RTI一起工作。

联邦成员不必是全新的代码;可以通过编写一小段在现有软件和RTI之间传输数据的代码,将现有软件用作联邦成员。例如,可以为AutoCAD或Excel等编写插件,以在仿真中利用其功能,如示例部分所示。

FOM

为了发送/接收消息,联邦成员必须就将发送的内容达成一致(例如,消息名称、数据类型等)。这通过一个称为联邦对象模型(FOM)的XML文件完成,该文件可以通过一个名为“simGe”的免费软件生成(http://www.ceng.metu.edu.tr/~otopcu/simge/)。HLA社区为寿司餐厅仿真开发了一个示例FOM(http://standards.ieee.org/downloads/1516/1516.2-2010/RestaurantFOMmodule.xml)。

一个例子:交通仿真

为了阐明HLA仿真概念,让我们想象我们正在尝试开发一个交通系统仿真;该系统将用于调查以下参数的影响

  • 天气
  • 道路宽度
  • 最大速度
  • 驾驶员专业知识

一旦所有目标都定义完毕,我们就可以开始定义联邦成员。定义联邦成员没有硬性规定,但直观地说,我们可以说我们将有以下联邦成员

  • 道路联邦成员:用于规划道路、安排道路维护等。
  • 天气联邦成员:提供天气更新(例如,降水)。
  • 交通控制器联邦成员:如交通灯等人员。
  • 驾驶员联邦成员:模拟汽车运动。
  • 可视化工具:向最终用户直观地显示仿真。

不同的团队可能负责不同的联邦成员。每个团队可以使用不同的编程语言(这是HLA仿真强大的一面)来开发他们的联邦成员。此外,并非所有联邦成员都必须从头开始编写;例如,对于可视化联邦成员,我们可以通过开发插件来可视化RTI的更新,从而调整现有软件(例如,Unity或WPF)。

在开发他们的联邦成员之前,所有团队都必须就联邦FOM达成一致。FOM是一个XML文件,包含两个重要部分:“对象类”和“交互类”;这两个部分指定联邦成员将发布什么。例如,我们可能有一个“HourlyWeather”对象类,其属性如下

<objectClass>

        <name>HourlyWeather</name>

        <sharing>PublishSubscribe</sharing>

        <attribute>

          <name>WindSpeed</name>

          <dataType>HLAfloat64Time</dataType>

          <updateType>Static</updateType>

          <ownership>NoTransfer</ownership>

          <sharing>PublishSubscribe</sharing>

          <transportation>HLAreliable</transportation>

          <order>TimeStamp</order>

        </attribute>

        <attribute>

          <name>Temperature</name>

          <dataType>HLAfloat64Time</dataType>

          <updateType>Static</updateType>

          <ownership>NoTransfer</ownership>

          <sharing>PublishSubscribe</sharing>

          <transportation>HLAreliable</transportation>

          <order>TimeStamp</order>

        </attribute>

</objectClass>

我们还可以有一个“RoadClosure”交互类,其中包含一个属性“RoadID”

<interactionClass>

        <name>RoadClosure</name>

        <sharing>PublishSubscribe</sharing>

        <transportation>HLAreliable</transportation>

        <order>Receive</order>

        <parameter>

          <name>RoadID</name>

          <dataType>HLAunicodeString</dataType>

        </parameter>

</interactionClass>

注意:完整的FOM文件可以从顶部的链接下载。

请注意,FOM文件并未说明哪个联邦成员将发布/订阅对象和交互类;它只是指定将发布/订阅什么,每个联邦成员在加入联邦后应告知RTI将发布/订阅什么。因此,在我们的示例中,在加入联邦后,天气联邦成员应通知RIT它将发布“HourlyWeather”,而驾驶员联邦成员将订阅它。因此;每当天气联邦成员发送“HourlyWeather”更新时,它将由RTI转发给驾驶员联邦成员。我应该在这里提到,每个对象/交互类可能有一个以上的发布者/订阅者。

注意:联邦可能拥有多个FOM,RTI将根据某些规则自动将它们合并为一个文件,但这超出了本文的范围。

HLA 监听器

目标

HLA仿真有一个非常陡峭的学习曲线,需要大量努力才能理解其所有概念。因此,我开发了一个名为“HLA Listener”的小应用程序,用于调试和学习HLA概念。

HLA Listener是一个带有GUI的联邦成员,完成后将实现标准中的所有方法。它可用于在深入研究代码之前消化所有HLA概念。我可以安全地说,即使凭借我在编写联邦成员代码方面的经验,我也从这个工具中学到了很多,因为它使我能够通过几次点击回答任何“如果”问题。

接口

HLA Listener是一个Maven开源项目,托管在GitHub上(https://github.com/EMostafaAli/HlaListener)。

要使用此软件,首先安装任何完全符合标准的RTI(我推荐使用Pitch RTI),然后运行HLA Listener并选择库jar文件(图2)。之后,您将看到主窗口,如图3所示。强烈建议运行两个版本的此工具,以查看通信如何通过RTI发生。

图2 第一步选择HLA库

图3 HLA Listener主窗口

代码

注意:此处的所有示例均摘自GitHub存储库。

在运行时加载jar文件

因为所有完全符合标准的RTI都必须实现完全相同的接口,所以我基于此接口构建了我的应用程序,并且在运行时用户必须提供实际的实现,该实现将添加到类路径中,如下所示

private static int AddtoBuildPath(File f) {

        logger.entry();

        try {

            URI u = f.toURI();

            URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

            Class<URLClassLoader> urlClass = URLClassLoader.class;

            Method method = urlClass.getDeclaredMethod("addURL", new Class[]{URL.class});

            method.setAccessible(true);

            method.invoke(urlClassLoader, new Object[]{u.toURL()});

        } catch (NoSuchMethodException | SecurityException | IllegalArgumentException |

                InvocationTargetException | MalformedURLException | IllegalAccessException ex) {

            logger.log(Level.FATAL, "Error adding the jar file to the class path", ex);

            return 1;

        }

        logger.exit();

        return 0;

    }

之后,我们必须使用“getRtiFactory”方法来获取指向实际RTI实现(称为RTI大使)的指针。

URL[] urls = new URL[]{file.toURI().toURL()};

            URLClassLoader child = new URLClassLoader(urls, this.getClass().getClassLoader());

            Class RtiFactoryFactory = Class.forName("hla.rti1516e.RtiFactoryFactory", true, child);

            Method getRtiFactory = RtiFactoryFactory.getMethod("getRtiFactory");

            rtiFactory = (RtiFactory) getRtiFactory.invoke(null);

            rtiAmb = rtiFactory.getRtiAmbassador();

发送到RTI

一旦我们有了指向RTI大使的指针,我们就可以通过调用相应的方法发送请求;以下代码连接到RTI,创建一个联邦,然后加入联邦

rtiAmb.connect(fedAmb, CallbackModel_choiceBox.getValue());

rtiAmb.createFederationExecution(FederationExecutionName.getText(), foms.toArray(new URL[foms.size()]), LogicalTimeImplementation.getValue());

rtiAmb.joinFederationExecution(FederateType.getText(), FederationExecutionName.getText());

从RTI接收

上面的代码展示了如何向RTI发送请求;为了从RTI接收回调,我们必须扩展“NullFederateAmbassador”抽象类并覆盖其方法。以下代码在连接丢失的情况下向控制台写入消息。

public class ListenerFederateAmb extends NullFederateAmbassador {

//Section 4.4 in standards

    @Override

    public void connectionLost(String faultDescription) throws FederateInternalError {

           System.out.println("Unfortunately, connection to RTI Lost. Try to reconnect");

    }

}

到目前为止的进展

到目前为止,我已实现标准中的以下章节

  1. 第4章:连接到RTI、创建联邦、加入联邦等。
  2. 第5章:发布/订阅属性和交互
  3. 第8章:时间管理。
  4. 其余章节中的零散项目。

接下来是什么?

这是提高对HLA仿真认识的一个初步步骤,希望这将导致开发一个免费的RTI。如果您是HLA仿真新手,请下载代码,构建它,然后自学。如果您熟悉HLA,请随时帮助我实现标准。

结论

我尽力使本文简洁;因此,我没有过多讨论HLA概念(例如,时间管理),也没有彻底审查代码。但是,如果需要,我可以撰写一系列解释HLA概念的文章。我还可以提供使用HLA Listener的分步教程,但我不能确定这是否符合Codeproject的主题。

历史

  • 2015年5月24日:初始版本
  • 2015年5月25日:扩展文章,添加示例代码,并调整图片大小
© . All rights reserved.