AFSim 仿真系统----集成指南

news2024/11/29 23:07:00

引言

本文档描述了将新功能扩展和集成到 AFSIM 中的有限方法。允许并描述多种方法,以及在 AFSIM 社区标准和指南中引入集成作为可共享资源的要求。

概述

核心可执行文件 基于 AFSIM 的可执行文件通常由单个 AFSIM “应用程序” 组成。该应用程序维护脚本类型、扩展和插件管理器以及应用程序配置数据。该应用程序由一个或多个场景组成,这些场景拥有类型工厂和列表、用户输入和脚本。根据应用程序的不同,场景由一个或多个仿真组成。仿真包含类型实例、接口(例如 DIS、XIO、观察者、地形)和运行时数据,包括事件管理和线程处理。

核心架构

AFSIM 的面向对象 C++ 架构提供了一种可扩展和模块化的架构,使许多附加功能能够轻松集成。AFSIM 允许新组件模型(例如传感器、通信、移动器等)以及完全新的组件类型被插入并在框架中使用。扩展和插件是框架扩展的主要机制,旨在集成新的平台组件模型、新的和扩展的平台能力,以及新的和扩展的仿真服务。插件能力是一种扩展形式,允许在不重新编译核心 AFSIM 代码的情况下添加功能。使用插件可以更轻松地分发扩展功能,并提供选择特定分析所需的扩展功能的能力。下图显示了 AFSIM 主要框架组件和提供的服务,这些服务可以被扩展。

注意:Doxygen 软件文档与 AFSIM 发布一起提供,开发人员可以通过 Doxygen 指令构建该文档。

基于组件的架构

AFSIM 的核心架构是基于组件的架构(CBA),允许通过组件包含许多功能,并通过组件列表进行管理。该 CBA 是通过 C++ 的面向对象原则(封装、继承、模板和多态)以及组件列表提供的,如下文进一步描述。

AFSIM 的 CBA 允许在框架的多个层级中使用组件和组件列表,包括应用程序、场景、仿真和平台,同时也包括其他领域如子系统。 在仿真和平台级别,组件类型通过名称或角色进行访问。这种访问使得可以通过组件列表以通用方式从仿真和平台中添加或移除组件类型。

组件(即 WsfComponent)是从层次结构中派生的基本元素,用于创建新类型或类型模板以实现特化。基础的 WsfComponent 不包含任何成员变量,因此任何函数都需要在派生类中通过 Wsf<type-name>Component 实现。

        WsfComponent 定义了以下“主要”框架方法,其中许多是纯虚拟的,需要由派生类实现:CloneComponent、ProcessInput、PreInput、PreInitialize、Initialize、Initialize2、<Get/Set>ComponentName、<Get/Set>ComponentRole、InitializationOrder、QueryInterface 和 GetComponentInitializationOrder。
        QueryInterfaceMethod 是一个必需的虚拟函数,允许查询角色,并要求也定义 GetComponentRoles。角色通常定义仿真组件列表中的服务或其他类型。角色通常定义平台组件列表中的类型,例如传感器、通信、移动器、处理器等。此外,为每个组件和部分类型在全局和有时在本地级别定义组件角色枚举,以支持组件列表中的 FindComponentByRole 功能。每个需要额外角色的项目会在其自己的项目中添加到全局组件角色枚举中。在全局上下文中添加角色确实需要在多个项目之间进行冲突解决,以避免角色的重复定义。

        组件列表以及类型枚举提供了维护和管理组件的方法。WsfComponentList 定义了以下框架方法,其中许多是纯虚拟的,需要由派生类实现。

主要方法可用于添加/删除组件、迭代列表中的组件、按名称或角色查找组件以及与添加/删除相关的回调。

CBA 实现

平台 CBA 实现

WsfPlatform(即平台)本身就是一个组件,并且附带有组件列表,以便通过附加到平台的方式包含传感器、通信、处理器、移动器等组件。

WsfPlatform 从 WsfComponent(模板类)、WsfComponentList(模板类)和 WsfObject/WsfUniqueId 类派生。此派生允许直接访问 WsfComponentList 函数,并使平台能够成为另一个平台的组件,从而实现组合设计模式。

示例组件实现

WsfSensor 通过 WsfPlatformPart 继承 WsfComponent,WsfPlatformPart 提供成员变量并在 WsfSensor 中实现与组件相关的虚拟函数。WsfProcessor、WsfComm、WsfMover 等的实现类似。

Declarations:

WSF_DECLARE_COMPONENT_ROLE_TYPE(WsfSensor, cWSF_COMPONENT_SENSOR)

Functions:

WsfComponent* CloneComponent()
WsfStringId GetComponentName()
virtual void* QueryInterface(int aRole);
virtual const int* GetComponentRoles();
PreInitialize(...), Initialize(...), Initialize2(...) and ProcessInput(...)

Example Sensor Role Implementation:

// ================================================================================================
const int* WsfSensor::GetComponentRoles() const
{
   static const int roles[] = { cWSF_COMPONENT_SENSOR, cWSF_COMPONENT_ARTICULATED_PART, cWSF_COMPONENT_PLATFORM_PART,
                                cWSF_COMPONENT_NULL
                              };
   return roles;
}

// ================================================================================================
void* WsfSensor::QueryInterface(int aRole)
{
   if (aRole == cWSF_COMPONENT_SENSOR) { return this; }
   if (aRole == cWSF_COMPONENT_ARTICULATED_PART) { return (WsfArticulatedPart*)this; }
   if (aRole == cWSF_COMPONENT_PLATFORM_PART) { return (WsfPlatformPart*)this; }
   return nullptr;
}

插件管理

AFSIM 的插件系统允许通过动态加载插件来实现定制化,提供与源代码修改相似的灵活性。使用插件消除了分发框架源代码以及更新核心可执行文件或库的必要性。此外,插件易于由最终用户共享、加载和卸载。

AFSIM 插件管理提供了通过主要和次要描述符进行版本管理的能力,它搜索由 WSF_PLUGIN_PATH 环境变量定义的路径,或者使用 ../<application>_plugin 或 ../wsf_plugins 目录。插件管理在注册插件之前还会进行操作系统、编译器和构建类型的检查,以确保兼容性。

扩展与扩展类型

应用程序、场景和仿真的扩展为在这些层级中扩展功能提供了灵活性。

应用程序扩展

应用程序的扩展是对应用程序单例或实例的扩展,归应用程序所有。

  • 修改或表示应用程序的可选能力。
  • 维护脚本类型和插件管理。
  • 可用于向场景或仿真添加功能。
场景扩展

场景扩展是对场景的扩展,归场景所有。

  • 拥有类型工厂和列表、用户输入和脚本。
  • 允许读取输入,例如实现 ProcessInput(…)。
仿真扩展

仿真扩展是对仿真的扩展,归仿真所有。

  • 提供特定的能力,例如接口、输出、观察者和其他服务。

AFSIM 构建系统

有关 AFSIM 构建系统的更多信息,请参见《构建 WSF 应用程序》,该系统使用 CMake。

可选项目

《构建 WSF 应用程序》概述了创建可选 AFSIM 项目的设置和必要文件,并让顶层 CMakeLists.txt 文件包含该项目。此外,《集成方法》一节概述了在这些文件中需要的不同文件和设置,以便将该项目纳入开发者选择的适当集成方法中的 AFSIM 构建系统。

集成方法

AFSIM 为任何扩展或模型提供了三种集成方法:直接集成、项目集成和插件集成。每种方法允许:

  • 一个或多个扩展类型的集成。
  • 不同的集成方法和包含方式。
  • 扩展的不同交付方式。

这些方法的具体内容在下面进一步定义,包括其方法、实施、交付和其他独特方面。

直接集成

直接集成使用现有项目或插件通过新的类型定义或额外的扩展类型添加来扩展功能。通常,这些扩展已经存在于项目中,此方法用于添加额外的模型类型定义或进一步扩展现有扩展。

一个主要的例子是将新类型或额外的基本类型添加到现有框架项目中。在这种情况下,新类型将通过项目的接口添加到新的或现有的类型列表中,类似于:

项目集成

项目集成是扩展 AFSIM 功能的最常见方法之一。此方法也可以用来通过下一个部分描述的插件方法集成。这种方法涉及创建一个额外的项目,可以集成到任何扩展类型中,以扩展 AFSIM 的能力。

目录结构

AFSIM 中的项目目录结构由多个目录和文件组成,以支持将该项目作为可选项目添加到 AFSIM 构建系统中。此外,还有必要的 CMake 配置文件用于将项目包含在 AFSIM 构建系统中,这些文件必须被包含。

my_project
  |- doc
  |- grammar
  |- source
      |- CMakeLists.txt
      |- <header-files>
      |- <source-files>
  |- test
  |- test_<application>
  |- CMakeLists.txt
  |- wsf_cmake_extension.cmake
  |- wsf_module

CMake 配置设置

根据目录结构,有四个必需文件,用于通过 CMake 将新项目包含到 AFSIM 构建系统中:

  • wsf_module
  • wsf_cmake_extension.cmake
  • CMakeLists.txt
  • source/CMakeLists.txt
wsf_module

该文件由 AFSIM 的主 CMakeLists.txt 使用。

wsf_cmake_extension.cmake

该文件用于告知 AFSIM 的主 CMakeLists.txt 本项目是一个可选项目,并设置扩展名称、源路径、构建类型和默认包含标志。

例子:

# configuration for automatic inclusion as a WSF extension
set(WSF_EXT_NAME my_project) # Required; Project name, match project name in main CMakeLists.txt
set(WSF_EXT_SOURCE_PATH .)   # Required; Path to the project main CMakeLists.txt
set(WSF_EXT_TYPE lib)        # Optional; default value: lib; available options: lib, plugin, exe
set(WSF_EXT_BUILD TRUE)      # Optional; default value: TRUE; available options: TRUE, FALSE
CMakeLists.txt

该文件是项目的主 CMakeLists.txt 文件,通过 wsf_cmake_extension.cmake 文件包含和设置。它用于设置项目名称、在项目中添加子目录、包含其他必要目录、添加必要的文档和 doxygen 目录,并安装项目中未包含在其他 CMake 配置文件中的必要项目文件。

例子:

# Project Configuration
project(wsf_my_project)
cmake_minimum_required (VERSION 3.2.3)
include(swdev_project)

include_directories(include ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include)
add_subdirectory(source)
add_subdirectory(test)

# Add source directories to doxygen input
add_wsf_doxygen_input(${CMAKE_CURRENT_SOURCE_DIR}/source)

# Add project to Sphinx for documentation
add_wsf_doc_input(${CMAKE_CURRENT_SOURCE_DIR})

install_sources(source wsf_plugins/${PROJECT_NAME})
install_sources_all_files(grammar wsf_plugins/${PROJECT_NAME})
install_sources_all_files(doc wsf_plugins/${PROJECT_NAME})
install_sources_all_files(data wsf_plugins/${PROJECT_NAME})
install_sources_all_files(conversion wsf_plugins/${PROJECT_NAME})
install_tests(test_mission DESTINATION wsf_plugins/${PROJECT_NAME})
install_source_files(CMakeLists.txt
                     wsf_module
                     wsf_cmake_extension.cmake
                     wsf_plugins/${PROJECT_NAME})
install_source_files(FILES wsf_module DESTINATION ${INSTALL_SOURCE_ROOT}/wsf_plugins)

if(WSF_INSTALL_DEMOS)
   # Demo directories included with this projects build
   set(EXAMPLE_DEMO_DIRS
       example_demo
   )
   install_wsf_demo("${EXAMPLE_DEMO_DIRS}" ${WSF_DEMOS_ROOT} demos)
endif()
source/CMakeLists.txt

这是一个通过项目的主 CMakeLists.txt 使用 add_subdirectory 命令调用的二级 CMake 配置文件。它的目的是为所有源文件定义通配符,指定语法文件,设置项目包含、库和链接,并最终安装源文件、演示和场景。

例子:

cmake_minimum_required (VERSION 3.2.3)
include (GenerateExportHeader)
include(swdev_project)

FILE(GLOB SRCS *.cpp *.hpp)

wsf_grammar_file(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../grammar/wsf_my_project.ag")

add_library(${PROJECT_NAME} ${SRCS})
generate_export_header(${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} PUBLIC
                           "${CMAKE_CURRENT_SOURCE_DIR}"
                           "${PROJECT_BINARY_DIR}/source")
target_link_libraries(${PROJECT_NAME} wsf util)
swdev_warning_level(${PROJECT_NAME})
swdev_lib_install(${PROJECT_NAME})

源配置设置

WsfExampleExtension 应用程序扩展的注册函数定义:

WsfExampleExtension.hpp

#ifndef WSFEXAMPLEEXTENSION_HPP
#define WSFEXAMPLEEXTENSION_HPP

#include "wsf_example_export.hpp"

#include "WsfScenarioExtension.hpp"

//! An implementation of WSf Scenario Extension that
//! adds replicated project capability to an application.
//! @see WsfScenarioExtension
class WSF_EXAMPLE_EXPORT WsfExampleExtension : public WsfScenarioExtension
{
   public:
      //! Called when the extension has been added to the scenario
      //! to add script types and wsf_my_project specific types
      virtual void AddedToScenario();
};

#endif

WsfExampleExtension.cpp

#include "WsfExampleExtension.hpp"

#include "UtMemory.hpp"
#include "WsfApplication.hpp"
#include "WsfApplicationExtension.hpp"
#include "WsfExampleProcessor.hpp"
#include "WsfProcessorTypes.hpp"
#include "WsfScenario.hpp"
#include "WsfScriptExampleProcessorClass.hpp"
#include "script/WsfScriptManager.hpp"

using namespace std;

namespace
{
   class ApplicationExtension : public WsfApplicationExtension
   {
      public:
         void AddedToApplication(WsfApplication& aApplication) override
         {
            // Register script classes associated with this extension
            UtScriptTypes* scriptTypesPtr = aApplication.GetScriptTypes();
            scriptTypesPtr->Register(new WsfScriptExampleProcessorClass("WsfExampleProcessor", scriptTypesPtr));
         }

         void ScenarioCreated(WsfScenario& aScenario) override
         {
            aScenario.RegisterExtension(GetExtensionName(), ut::make_unique<WsfExampleExtension>());
         }
   };
}

void WsfExampleExtension::AddedToScenario()
{
   WsfScenario& scenario = GetScenario();
   WsfProcessorTypes::Get(scenario).AddCoreType("WSF_EXAMPLE_PROCESSOR", ut::make_unique<WsfExampleProcessor>(scenario));
}

//! Registers the wsf_example extension with the application
//! so it is available for use.
void WSF_EXAMPLE_EXPORT Register_wsf_example(WsfApplication& aApplication)
{
   if (!aApplication.ExtensionIsRegistered("wsf_example"))
   {
      aApplication.RegisterFeature("example", "wsf_example"); // Indicate the feature is present
      aApplication.RegisterExtension("wsf_example", ut::make_unique<ApplicationExtension>());
   }
}

Registration function definition for WsfExampleExtension Scenario extension:

WsfExampleExtension.hpp

#ifndef WSFEXAMPLEEXTENSION_HPP
#define WSFEXAMPLEEXTENSION_HPP

#endif

WsfExampleExtension.cpp

#include "WsfExampleExtension.hpp"

#include "UtMemory.hpp"
#include "WsfApplication.hpp"
#include "WsfApplicationExtension.hpp"
#include "WsfExampleProcessor.hpp"
#include "WsfProcessorTypes.hpp"
#include "WsfScenario.hpp"
#include "WsfScenarioExtension.hpp"

using namespace std;

namespace
{
   class ScenarioExtension : public WsfScenarioExtension
   {
      public:
         void AddedToScenario() override
         {
            WsfScenario& scenario = GetScenario();
            WsfProcessorTypes::Get(scenario).AddCoreType("WSF_EXAMPLE_PROCESSOR", ut::make_unique<WsfExampleProcessor>(scenario));
         }
   };
}

//! Registers the wsf_example extension with the application
//! so it is available for use.
void WSF_EXAMPLE_EXPORT Register_wsf_example(WsfApplication& aApplication)
{
   if (!aApplication.ExtensionIsRegistered("wsf_example"))
   {
      aApplication.RegisterFeature("example", "wsf_example"); // Indicate the feature is present
      aApplication.RegisterExtension("wsf_example", ut::make_unique<WsfDefaultApplicationExtension<ScenarioExtension>());
   }
}

插件

作为一个插件,与项目相似,并且可以双重使用。本节概述了项目集成方法的修改。

注意:可以通过项目接口设置将项目同时集成为项目和插件。

CMake 配置设置

创建或将项目转换为插件项目需要对以下文件进行修改:

  • wsf_cmake_extension.cmake
  • source/CMakeLists.txt
wsf_cmake_extension.cmake

添加逻辑检查,如果在 CMake 构建配置中选择了 WSF_PLUGIN_BUILD,则将扩展类型设置为插件。

注意:如果将 WSF_PLUGIN_BUILD 设置为 FALSE,则将使用该配置构建项目集成方法,因为默认的 WSF_EXT_TYPE 为 lib。

示例:

# configuration for automatic inclusion as a WSF extension
set(WSF_EXT_NAME my_project)  # 必需;项目名称,匹配主 CMakeLists.txt 中的项目名称
set(WSF_EXT_SOURCE_PATH .)     # 必需;项目主 CMakeLists.txt 的路径
if(WSF_PLUGIN_BUILD)
   set(WSF_EXT_TYPE plugin)    # 可选;默认值:lib;可用选项:lib, plugin, exe
endif()
set(WSF_EXT_BUILD TRUE)        # 可选;默认值:TRUE;可用选项:TRUE, FALSE
source/CMakeLists.txt

这是一个通过项目的主 CMakeLists.txt 使用 add_subdirectory 命令调用的二级 CMake 配置文件。它的目的是收集所有源文件,指定语法文件,设置项目包含、库和链接,最后安装源文件和演示。

示例:

cmake_minimum_required(VERSION 3.2.3)
include(GenerateExportHeader)
include(swdev_project)

FILE(GLOB SRCS *.cpp *.hpp)

wsf_grammar_file(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../grammar/wsf_my_project.ag")

add_library(${PROJECT_NAME} ${SRCS})
generate_export_header(${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} PUBLIC
                           "${CMAKE_CURRENT_SOURCE_DIR}"
                           "${PROJECT_BINARY_DIR}/source")
target_link_libraries(${PROJECT_NAME} wsf util)
swdev_warning_level(${PROJECT_NAME})

if(WSF_PLUGIN_BUILD)
   swdev_plugin_install(${PROJECT_NAME} wsf_plugins)
else()
   swdev_lib_install(${PROJECT_NAME})
endif()

源配置设置

类似于项目源配置设置部分,以下是包含 extern "C" 的附加部分,位于全局 Register_wsf_example 定义下方。插件项目的注册函数示例定义:

//! 注册 wsf_example 扩展到应用程序
//! 使其可供使用。
void WSF_EXAMPLE_EXPORT Register_wsf_example(WsfApplication& aApplication)
{
   if (!aApplication.ExtensionIsRegistered("wsf_example"))
   {
      aApplication.RegisterFeature("example", "wsf_example"); // 指示功能存在
      aApplication.RegisterExtension("wsf_example", ut::make_unique<ApplicationExtension>());
   }
}

extern "C"
{
   //! 此方法在插件加载时调用,以确保插件和加载它的可执行文件使用的是
   //! 相同版本的插件 API。
   UT_PLUGIN_EXPORT void WsfPluginVersion(UtPluginVersion& aVersion)
   {
      aVersion = UtPluginVersion(WSF_PLUGIN_API_MAJOR_VERSION,
                                 WSF_PLUGIN_API_MINOR_VERSION,
                                 WSF_PLUGIN_API_COMPILER_STRING);
   }
   //! 此方法在插件加载时调用。它必须具有完全相同的签名(名称和参数)才能成功。
   //! 由于我们在加载时只有应用程序引用,因此通常在其中注册一个应用程序扩展,
   //! 通过覆盖 ScenarioCreated 方法来获得对场景的访问。如果还需要
   //! 访问模拟,则应通过覆盖
   //! 场景扩展中的 SimulationCreated 方法来实例化和注册模拟扩展。
   UT_PLUGIN_EXPORT void WsfPluginSetup(WsfApplication& aApplication)
   {
      Register_wsf_example(aApplication);
   }
}

其他集成项目和要求

代码标准

所有集成都应遵循《编码标准》中概述的编码标准。与 AFSIM 社区没有直接关联的第三方库和源代码可能无法始终遵循标准,但这并不妨碍 AFSIM 接口与第三方源/库遵循标准。

CMake

所有 CMake 文件应遵循本文件或《构建 WSF 应用程序》中概述的目录结构。存在许多示例,格式应尽量与已发布项目保持一致。

有关 AFSIM 使用 CMake 的构建系统的更多信息,请参见《构建 WSF 应用程序》。

语法

任何集成所需的用户输入应包含在语法文件夹及相应文件中,该项目添加此功能,并应在测试时无错误和警告地执行。语法详细说明在《WSF 语法指南》和《WSF 语法格式》中。

文档

AFSIM 文档通过 Sphinx 和 Doxygen 工具分别提供给用户和开发者。两者在构建时应无错误和警告。

Sphinx

任何用户输入或集成所需的参考材料文档应包含在添加功能的项目的 doc 文件夹中。此包含确保该功能对最终用户可用。Sphinx 用于生成 reStructuredText 格式的 HTML 输出。CMake 提供了一个 DOCUMENTATION 目标,用于构建和安装文档。

要在构建目标中正确包含 doc 文件夹,请在项目的 CMakeLists.txt 文件中添加以下内容:

# 将项目添加到 Sphinx 文档
add_wsf_doc_input(${CMAKE_CURRENT_SOURCE_DIR}/..)

有关文档的更多信息,请参考《AFSIM 文档指南》。

Doxygen

Doxygen 代码文档支持由开发者提供。要将项目的源代码添加到 Doxygen 目标进行解析,请在项目的 CMakeLists.txt 文件中添加以下 CMake 宏:

# 将源目录添加到 Doxygen 输入
add_wsf_doxygen_input(${CMAKE_CURRENT_SOURCE_DIR}/source)

构建

在 AFSIM 生产中使用的每个构建配置和平台应消除所有警告和错误。由 AFSIM 社区或集成者未维护的第三方源和库可能无法满足此准则。

有关文档的更多信息,请参见《构建 WSF 应用程序》。

测试

单元测试

AFSIM 内的单元测试按《构建 AFSIM 应用程序》中概述的方式提供。

要将单元测试添加到您的项目中,您需要提供以下内容:

  • test/CMakeLists.txt
  • test/test_example.cpp
test/CMakeLists.txt

这是一个测试 CMake 配置文件,通过项目的主 CMakeLists.txt 使用 add_subdirectory 命令调用。其目的是收集所有测试源文件,链接测试可执行文件,并将测试注册为 CMake 目标的一部分。

示例:

cmake_minimum_required(VERSION 3.2.3)
file(GLOB SRCS *.cpp *.hpp)

if(GTest_FOUND)
   add_executable(example_test ${SRCS})
   target_include_directories(example_test PUBLIC ${EXAMPLE_PROJECT_INCLUDES})
   target_link_libraries(example_test
      ${WSF_LIBS}
      ${PROJECT_NAME}
      ${SWDEV_THREAD_LIB}
      ${SWDEV_DL_LIB}
      ${GTEST_BOTH_LIBRARIES}
   )
   add_test(NAME "example" COMMAND example_test)
   set_property(TARGET example_test PROPERTY FOLDER UnitTests)
endif()
test/test_example.cpp

这是一个源文件,包含针对特定函数或类的测试。在测试目录中可以创建多个源文件,并将自动包含以进行编译。最佳实践是为每个被测试的类创建一个新的源文件。

示例:

#include <gtest/gtest.h>

// 假设 Example.hpp 声明了一个阶乘函数
#include "Example.hpp"

TEST(Factorial, HandlesZeroInput)
{
   ASSERT_EQ(1, factorial(0));
}

TEST(Factorial, HandlesPositiveInput)
{
   ASSERT_EQ(1, factorial(1));
   ASSERT_EQ(2, factorial(2));
   ASSERT_EQ(6, factorial(3));
   ASSERT_EQ(362880, factorial(9));
}

TEST(Factorial, ThrowsOnNegativeInput)
{
   ASSERT_THROW(factorial(-12), InvalidValueException);
}
系统、集成测试

AFSIM 内的系统或集成测试按《构建 AFSIM 应用程序》中概述的方式提供。

要将系统或集成测试添加到您的项目中,您需要提供以下文件:

  • test_<application>/test_<capability>.txt

该文件包含 AFSIM 测试命令和脚本,用于针对定义的 <application> 测试 AFSIM 和 WSF。该文件应至少包含一个通过/失败标准,并输出一个 -FAIL,如下所示,并提供可选的 -PASS- 输出,以便 run 脚本进行正确解析,并在解析到 -FAIL- 时输出失败。

示例:

# 示例文件:test_mission/test_maketrack.txt
platform test_platform WSF_PLATFORM
   execute at_time 1 s absolute
      WsfTrack track = PLATFORM.MakeTrack();
      if (track.LocationValid())
      {
         writeln("-PASS-");
      }
      else
      {
         writeln("-FAIL-");
      }
   end_execute
end_platform

术语

  • AFSIM - 高级模拟、集成和建模框架
  • WSF - 世界仿真框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2059782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux rocky 9.2 安装mysql-8.0.39-linux-glibc2.28-x86_64.tar.xz

数据库官方下载&#xff1a;MySQL :: Download MySQL Community Server 本文也绑定该资源包&#xff0c;免费提供下载学习。 1.系统版本 2.新建目录&#xff0c;存放数据库安装包&#xff0c;并且上传 需要用到的工具&#xff1a;yum -y install vim lrzsz tar 上传解压&…

SAP EWM 包装

目录 1 简介 2 业务流程 3 主数据 4 后台配置 1 简介 SAP S4 HANA 里 EWM 包装功能使用 PS&#xff08;packaging specification&#xff09;代替原有的包装功能 PM&#xff08;packaging management&#xff09;, PI&#xff08;packaging instruction&#xff09;。PS 生…

UNiapp之微信小程序导出Excel

效果如下 参考小程序&#xff1a;日常记一记 ---账单页面 主要功能是根据筛选条件导出账单明细列表&#xff0c;实现该功能主要借助一个工具(excel.js)&#xff0c;可在文章顶部下载或者一下网盘下载 https://pan.baidu.com/s/1RLisuG4_7FGD0Cnwewyabg?pwdpd2a 提取码: pd2a…

C# 判断

|判断结构要求程序员指定一个或多个要评估或测试的条件&#xff0c;以及条件为真时要执行的语句&#xff08;必需的&#xff09;和条件为假时要执行的语句&#xff08;可选的&#xff09;| | |-------------------------------------------------------------|–| | | | 下面是…

HormonyOS踩坑JSON.stringfy

前两天发现一个问题 就是一个值 用as string就可以打印出来 用JSON.stringfy()就不行 百思不得其解 想破了脑袋&#xff01;&#xff01;&#xff01;终于被我发现了 原因就在于上边那个包&#xff01;&#xff01;&#xff01;&#xff01;把那个包删除了就好了&#xff…

勇闯机器学习(第二关-数据集使用)

以下内容&#xff0c;皆为原创&#xff0c;重在无私分享高质量知识&#xff0c;制作实属不易&#xff0c;请点点关注。 好戏开场了~~~(这关涉及到了加载数据集的代码&#xff0c;下一关&#xff0c;教你们安装机器学习库) 一.数据集 这一关的目标 知道数据集被分为训练集和测…

一款搭载远翔FP5207芯片的大功率音箱,蓝牙音箱的组成和拆解展示

一款搭载远翔FP5207芯片的大功率音箱&#xff0c;蓝牙音箱的组成和拆解展示&#xff1a; 它主要以电池、功放、蓝牙、外壳结构组成。音箱放电需内置升压芯片FP5207或5217进行电池升压给功放供电。 为同时满足便携性需求并提供足够的功率&#xff0c;音箱通常配备了12V铅酸电池…

MySQL中的DML操作()

一、添加数据(INSERT) 1.1 选择插入 INSERT INTO 表名(列名 1 &#xff0c;列名 2 &#xff0c;列名 3.....) VALUES(值 1 &#xff0c;值 2 &#xff0c;值 3......); 1.2 默认值处理(DEFAULT) 在 MySQL 中可以使用 DEFAULT 为列设定一个默认值。如果在插入数据时并未指定该…

【C++】OJ习题(初阶)

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;C 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 &#x1f4a5;1、字符串&#x1f4a5;1.1 字符串相加&#x1f4a5;1.2 验证回文字符串&#x1f4a5;1.3 反转…

单例模式 详解

单例模式 简介: 让类只初始化一次, 然后不同的地方都能获取到同一个实例 这是非常常用的一种模式, 系统稍微大一点基本上都会用到. 在系统中, 不同模块的总管理类都已单例模式居多 这里我们不仅使用c实现单例模式, 也会用python2实现一遍 python代码 想要看更详细的python单…

【Python机器学习】NLP——一个简陋的聊天机器人

目录 正则表达式 一个简答的聊天机器人 另一种方法 正则表达式就是一种FSM&#xff0c;同时它也给出了一种可能的NLP方法&#xff0c;即基于模式的方法。 正则表达式 现实生活中&#xff0c;密码锁其实就是一台简单的语言处理机。密码锁不能阅读和理解课本&#xff0c;但是…

高性能web服务器nginx

目录 nginx简介 服务端 I/O 流程 Nginx 进程结构 Nginx启动流程 nginx的源码编译下载 nginx命令常见参数 nginx的配置文件详解 全局配置优化 nginx的平滑升级和回滚 nginx目录匹配优先级测试&#xff08;因为只支持访问文件&#xff0c;所有不比对匹配目录优先级&…

STM32GPIO引脚八种工作模式

1. GPIO简述 GPIO&#xff08;General-purpose input/output&#xff09;&#xff0c;通用型输入输出。简单理解就是我们可以控制输入输出的STM32引脚&#xff0c;统称为GPIO。 GPIO存在的意义就是用程序控制或读取它们的输出或输入。 2. 功能描述 每个GPI/O端口有两个32位配…

代码随想录算法训练营day50:图论01:图论理论基础;深度优先搜索理论基础;98. 所有可达路径;广度优先搜索理论基础

图论理论基础 分类&#xff1a;有向图&#xff0c;无向图&#xff0c;有无权重 度&#xff1a;【无向图】&#xff1a;有几条边连接该节点&#xff0c;该节点就有几度。 【有向图】&#xff1a;每个节点有出度和入度。出度&#xff1a;从该节点出发的边的个数。入度&#xf…

.net maui安卓开发中适用明文传输(一)

背景:最近在做一个pad上的项目,目的是执行每日点检功能(就是检查设备的各项保养指标);前期用HBuilder做了一个,但是现场的触摸屏选用的是TouchPie 安卓版本是6.0版本,上次开发的软件可以在安卓7.0上完美兼容,但由于触摸屏安卓版本太低不能兼容;询问厂商才知道这款触摸…

前端性能优化的指标

性能优化指标的出现,谷歌在2020年提出的Core Web Vitals 和 Web Vitals 了解谷歌浏览器自带的性能调试工具DCL、L、FP、FCP、LCP,图层(有layout布局就是回流,painting绘制就是重绘) 回流和重绘的理解 页面第一次打开一定回流和重绘,回流一定重绘,回流出现一般是位置改变…

BEV世界:通过统一的BEV潜在空间实现自动驾驶的多模态世界模型

BEVWorld: A Multimodal World Model for Autonomous Driving via Unified BEV Latent Space BEV世界&#xff1a;通过统一的BEV潜在空间实现自动驾驶的多模态世界模型 Abstract World models are receiving increasing attention in autonomous driving for their ability t…

【数据结构】PTA 求链表的倒数第m个元素 C语言

请设计时间和空间上都尽可能高效的算法&#xff0c;在不改变链表的前提下&#xff0c;求链式存储的线性表的倒数第m&#xff08;>0&#xff09;个元素。 函数接口定义&#xff1a; ElementType Find( List L, int m ); 其中List结构定义如下&#xff1a; typedef struct…

什么是机器人快换盘?

机器人快换盘&#xff0c;行业内也称作工具快换盘、换枪盘、快换工具盘、快速更换器、快换器、 快换夹具、治具快换等。是末端执行器快速更换装置&#xff08;End-Of-Arm Tooling&#xff0c;简称EOAT&#xff09;&#xff0c;是工业自动化领域中用于机器人手臂上的一种重要设备…

短视频矩阵工具种类繁多,一招教你轻松做选择!

在当下竞争日益激烈的市场中&#xff0c;选择一个稳定且高效的矩阵营销系统对于企业和实体店来说至关重要&#xff0c;然而众多的工具往往让人难以抉择&#xff0c;今天笔者给大家四个关键筛选点&#xff0c;帮你快速筛选出最合适自己的矩阵营销工具&#xff1a; 1. 功能全面性…