Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Latest commit

 

History

History
130 lines (97 loc) · 6.91 KB

README_CN.md

File metadata and controls

130 lines (97 loc) · 6.91 KB

Nebula 简要说明

实体-组件模式

每一种组件(Component)都代表着一类功能, 比如“电机控制组件”,可以用于读取和控制电机的转速;或者“工业相机组件”,可以从某个品牌的工业相机中读取相机画面,或者进行曝光、白平衡等参数调整。

实体是现实中某种实物或概念的抽象,如“电机”实体,“摄像机”实体,或“目标检测器”实体。 根据实体所对应的实物或概念,实体应当具备相应的组件,比如“电机”实体应当具备“电机控制组件”和“三维坐标组件”, 分别用于控制电机的速度,并记录电机当前所处的三维坐标。

实体组件模式具有较高的拓展性,当用户希望拓展某个实体的功能时,只需要将新的组件添加到实体上即可。

目标

Nebula 主要面向以下目标进行设计:

  • 采用实体-组件模式;
  • 支持分布式计算,即多主机协同工作;
  • 支持多语言,即允许多种语言编写的组件协同运作;
  • 支持遥测,即对代码中关键参数的远程读写和监控;
  • 支持热重载,即在代码运行过程中对代码进行替换;
  • 支持脚本化,即允许用户以脚本代码的形式添加逻辑;
  • 提供完整的集中式配置存储服务;
  • 提供完整的日志记录和查询服务;

实现

Nebula 主要采用3个中间件来实现功能:

  • gRPC 通过gRPC来实现多语言、分布式支持。 用户通过定义gRPC的*.proto文件来向其他语言提供访问该组件的功能的方法, 并以gRPC服务器的方式来提供组件功能。
  • MQTT 采用MQTT消息协议来支持数据流。 Nebula的各个组件将通过MQTT来发布和接受全局事件, 被遥测的数据也会以MQTT的消息的形式被发布和订阅, 从而实现对参数的遥测功能。
  • MongoDB 组件的配置数据,和业务需要的大规模数据都会存储在MongoDB数据库中。 例如,实现机器视觉的在线增强学习,需要在平时运行时记录相机画面,并在学习时进行查询, 组件即可将相机画面以Base64的格式,附带其他数据如日期等,存储在MongoDB中。 相较于传统的文件存储,使用MongoDB进行存储具有以下好处: 数据被进行了有效的管理,可以进行非常方便的增删查改,尤其是查找性能更佳; 由于MongoDB本身是网络数据库,故当多台机器人连接至同一个局域网时, 可以实现自动的“数据库集群”,即从其他机器人的MongoDB数据库中获取数据。

模块

  • Nebula Nexus: 提供组件服务器管理、实体管理等服务的服务器,采用ASP.NET Core进行开发。
  • Nebula Core: 给C#用户提供的开发包,提供了接口和工具,用于便捷访问Nebula中的基础设施, 并提供了实体-组件模式的功能,例如查找实体、从实体中获得组件等功能。
  • Nebula Server: 给C#用户提供的托管服务器,可以启动C#用户定义的组件服务,并附加遥测、日志等功能。

后续Nebula将提供C++、Python等语言的支持。

gRPC 协议

这些gRPC协议定义了Nexus和组件服务器应当具备的功能,它们均位于Protocols文件夹内。

Nexus应当实现的服务:

  • DomainService: 提供实体的创建、删除、查找功能,提供名称解析服务(根据服务名称查找服务器地址);
  • EntityService: 提供实体的添加、删除、获取组件、配置实体,和列举所有组件的功能;

组件服务器应当实现的服务:

  • ComponentService: 提供为指定实体创建、删除、查询组件,列举、读写、监控实体的属性的功能。

EntityId、EntitySelector

gRPC是面向过程的,即每个函数可以被视为是静态函数。 为了让组件服务的每个函数都知道自己应该做用在哪个组件实例上, Nebula引入了EntityId。

实体的ID会被记录在gRPC访问的RequestHeader的“eid-bin”字段中, 当组件服务的函数处理请求时,即可从该字段获取实体的ID, 即可从实体ID-组件实例的映射表中获取对应的组件实例, 从而面向过程的gRPC被改造成了面向对象的gRPC。

MongoDB数据格式

在使用的数据库内(默认名称为“Nebula”,用户可以自行指定以实现隔离), 应当具备以下Collection:

  • Entities
  • Servers

Entities

该Collection用于存储实体数据,每个实体对应一个Document。

实体Document应当具有以下结构:

  • ID : uint32 实体的ID,用于唯一地找到该实体
  • Tags : string[] 实体的标签,用于搜索该类实体
  • Components : Document[] 实体的组件数据
    • Name : string 组件名称,可以根据该名称查找到该组件服务器
    • Data : Document 组件的自定义数据,由组件自行读写
    • Settings : Document 组件的配置数据,用于配置该组件
    • Logs : Document[] 由该组件产生的日志数据

Servers

该Collection用于存储组件服务器数据,每一个组件服务器实例对应一个Document。 当Nexus启动时,其将获取该Collection的数据,并启动对应的Server。

组件服务器的Document应当具有以下结构:

  • Name : string 组件名称。
  • Server : string 服务器可执行文件路径。
  • Service : string 服务插件的路径,当组件服务器被要求远程更新或传送时,该文件会被更新或传送。
  • Port : uint32 分配给其的端口。
  • Settings : Document 服务器的配置数据。
  • Logs : Document[] 由该组件服务器产生的日志数。
  • Data : Document 提供给组件服务器自行使用的数据。

MQTT

数据包

MQTT的消息数据包使用Protobuf编码,具有以下结构:

  • Name : string 数据类型名称,一般为Protobuf编解码器的名称;
  • Type : enum {Bytes, JSON} 指定该数据以Protobuf编码的字节的形式传输,还是JSON文本形式传输

频道

目前,预定义以下频道:

  • /log 日志频道,所有被要求开启某些组件的日志遥测的服务器会将日志数据推送至该频道。
  • /status 状态遥测频道,所有被要求开始某些组件的属性遥测的服务区会将属性推送至该频道。
  • /data 外部数据频道,部分设备驱动或外部程序可以通过MQTT协议将数据推送至该频道;Nebula内部数据也可以通过该频道与外部驱动进行通信。

全局事件

全局事件会被广播至所有的组件服务器。 目前,预定义以下全局事件:

  • 数据保存: 要求所有的组件服务器将需要保存的服务器提交至MongoDB,这通常会发生在计算机将要关闭时。
  • 组件客户端更换: 当某个组件服务器被迁移到其他地址(其本身转移或损坏后启动备用服务器)时,对应的服务名称和新的组件服务器的地址会被全局广播。
  • 新主机接入当前域: 当Nexus发现了其他的主机上的Nexus时,会广播该消息。