\chapter{OneDT主系统设计}
在研究设计三项数字孪生基础技术前，考虑到建设通用数字孪生平台，需要设计一个通用的数字孪生主体系统，命名为OneDT(图\ref{fig-f36})，用于实现数字孪生平台的核心功能及其功能特性。本章将详细介绍数字孪生主体系统的设计，包括系统设计原则、结构设计、数据库设计、系统功能设计、代码组织设计、可视化方案设计等。

\begin{figure}[h!]
    \centering
    \includegraphics[width=1\textwidth]{figure/f36.png}
    \caption{OneDT系统功能图}
    \label{fig-f36}
\end{figure}


\section{设计原则}
在开始具体设计前，需要明确设计的主要原则，根据数字孪生系统的一些特点，为了保障整体系统的可靠性和功能性，在设计每一个功能模块和子系统时需要遵循以下原则：
\begin{enumerate}
    \item 高可用：高可用性是系统设计中的重要目标之一，旨在确保系统在面对故障、错误或意外情况时能够保持正常运行。在系统设计中要注意负载均衡、自动化任务设计、冗余备份、快速恢复、无状态设计等等问题。

\item 高性能：
在本平台设计中，核心性能指标有消息网络的分发能力，硬实时消息的响应速度，主体平台对多种规则模型的处理速度，海量消息的存储能力，用户访问时模型的操作性能、仿真性能等。
\item 可扩展性：
可扩展性是本平台设计中核心设计的一点，不单单指服务的可扩展性，比如服务节点可以水平扩增等，还指集群网络的开放程度，能对接现有消息协议，开放消息网络对接和规则模型设计。

\item 安全性：
在保持消息网络的开发性上去保证整体平台、节点的安全性，在实践中，消息网络如何在开放协议的基础上保证通信安全。

\item 单一职责原则：
任何模块保持职责和功能的最小化，专一化，模块之间不含功能交集，这有助于确保系统的模块化和可维护性，并减少模块之间的依赖性和耦合度

\end{enumerate}

\section{整体结构设计}

\begin{figure}[h!]
    \centering
    \includegraphics[width=0.8\textwidth]{figure/f1.png}
    \caption{系统数据流向图}
    \label{fig-f1}
\end{figure}
在设计整体结构时，需要先考虑整体的数据流向，再根据数据聚合的方式，将系统划分为不同的模块，最后再考虑模块之间的通信方式。在数字孪生平台中，数据流向如图\ref{fig-f1}所示，A代表数字孪生主体系统，它是数字孪生平台的核心组成部分，包括基本的数据存储、数据分析、核心消息节点、用户交互、模型展示和知识存储等功能。所有其他功能都依赖于主体平台进行显示和控制，是实现系统所有功能的基础和载体。BC分别代表不同的孪生场景，每个场景皆有一个核心节点与A集群进行信息交互。用户通过交互前端与A进行数据交互。

\begin{figure}[h!]
    \centering
    \includegraphics[width=0.8\textwidth]{figure/f8.png}
    \caption{平台主体结构}
    \label{fig-f8}
\end{figure}


在设计数字孪生整体结构时，需要综合考虑用户使用、硬件通信、云服务特性，以及平台的通用性、可扩展性、容灾恢复和安全性等多方面因素。图\ref{fig-f8}所示,整体上采用微服务架构，将系统根据业务功能模块拆分成若干个独立的微服务，每个微服务都能独立部署和扩展。微服务架构有助于提高系统的可伸缩性和可用性，同时降低系统的维护成本。在前端，采用前后端分离的架构，使用现代化的前端框架Vue，通过API连接到后端服务，实现前后端分离，以提高系统的可维护性和可伸缩性。后端则采用分布式架构，将不同的业务模块拆分成独立的微服务，通过API或消息队列进行通信，以提高系统的可伸缩性和可用性。同时，利用缓存技术（例如Redis）来提高系统的性能。在数据库方面，采用分布式数据库架构，将不同的数据拆分到不同的数据库实例中，并通过数据分片技术实现分布式存储，从而提高系统的可伸缩性和性能。此外，利用读写分离技术将读操作和写操作分别路由到不同的数据库实例，以提高系统性能。针对不同类型的数据，采用相应的存储方式，例如将主体结构数据存入MySQL，时序数据存入Elasticsearch，非参数化模型存入文本或对象存储服务（OSS）中。在安全设计方面，采用统一的非对称密钥认证机制，对用户访问和节点通信进行私钥本地解密远程密文认证，例如身份验证、访问控制、节点接入和数据加密等，以确保系统安全性。

\section{功能设计}

Schleich等人将数字孪生的愿景总结为物理人工制品与其虚拟模型集之间的双向关系，并提出了其基本能力可伸缩性、互操作性、可扩展性和保真度\cite{ref10}。图\ref{fig-f38}所示，可伸缩性指系统能提供不同尺度的预览能力，互操作性指不同模型转换、组合、表示等价的能力，可扩展性指系统集成、添加或替换模型的能力，保真度指虚拟模型与实物相近的程度。
\begin{figure}[h!]
    \centering
    \includegraphics[width=0.8\textwidth]{figure/f38.png}
    \caption{DT基本能力\cite{ref10}}
    \label{fig-f38}
\end{figure}

Schleich等人总结的基本能力从虚拟模型的层次来说是非常恰当的，但是从发展数字孪生的根本目的和功能来谈，需要更加贴切的功能划分。
在图\ref{fig-f35}中本文根据能力性质将数字孪生基本功能分为描述、诊断、预测、决策，描述是数字孪生系统最基本能力，是对物理对象的虚拟再现;诊断是数字孪生的基本功能，是对复现的虚拟实体的数据进行最基本的功能诊断，判断其物理实体的各项功能是否在正常范围内;预测是数字孪生系统的核心功能，通过收集到的大量历史数据和实体基本信息，对其可能潜在的行为进行推导，并对复杂系统的未来状态进行预测;决策是数字孪生系统的终极功能，它可以摆脱人的操作和监控，直接根据虚拟实体的现状数据和预测数据做出决策，指导现实对象的生产过程。

同时在实际使用阶段时，根据产品的生命周期不同，其功能划分也存在很大不同，但其根本仍是由上述四大基本能力组合而成。如图\ref{fig-f37}所示，产品的基本生命周期包含设计、制造、服务三大阶段，在设计阶段主要根据已有的数据对设计图纸进行真实场景描述和预测，提高设计迭代速度，降低设计阶段成本；在制造阶段主要根据对产线数据和工件数据的采集，可以做到实时生产监控、控制和规划，同时对工件性能结果做出评估，反向优化工艺参数；在服务阶段主要是在运行阶段也可以采集到产品信息，做到产品全寿命结构检测，同时相应在管理和维护上降低很大成本。

\begin{figure}[h!]
    \centering
    \includegraphics[width=0.8\textwidth]{figure/f37.png}
    \caption{数字孪生功能}
    \label{fig-f37}
\end{figure}


除了从产品周期的作用上看待数字孪生功能划分，在设计本平台功能时，重点考虑其通用性和扩展性后，将功能点分为基础功能和拓展功能，拓展功能以本文提供的数据通信方案和规则模型方案为基础构建，由基础功能和额外编写的逻辑规则拓展而成，用户也可以此设计拓展功能。

\begin{enumerate}
    \item 数字孪生建模功能：提供用户友好的建模工具，支持各种模型类型和复杂性。用户可以通过可视化界面创建、编辑和删除模型。同时，平台应该提供模型验证、合法性检查、版本管理等功能。

\item 规则编写：提供多种方式的规则输入体系，使得用户方便的去构建场景和节点交互逻辑和内置规则。

\item 数据采集和集成功能：数字孪生平台需要支持各种数据源的集成，包括传感器、设备、网络、云服务等等，提供丰富的API和数据连接功能，以便数据源的快速接入和管理。

\item 数据分析和可视化功能：数字孪生平台需要提供数据分析和可视化工具，以便用户对数字孪生系统中的数据进行分析和探索。平台提供可视化工具和分析功能，支持数据探索、数据可视化和可视化交互等等。

\item 仿真和预测功能：数字孪生平台需要支持仿真和预测功能，以便用户可以基于数字孪生系统中的数据进行模拟和预测分析。平台应该提供各种仿真和预测工具，包括数据建模、算法开发和模型训练等等。

\item 安全性和可扩展性：数字孪生平台需要具备高可靠性和可扩展性。平台应该提供安全保障机制，包括数据安全、身份认证和访问控制等等。同时，平台应该具备可扩展性，以便用户可以轻松地扩展数字孪生系统的功能和规模。

\item API和开放平台：数字孪生平台需要提供API和开放平台，以便用户可以轻松地开发自己的应用程序和服务。平台应该提供完整的API文档和示例代码，同时支持第三方开发者的集成和扩展。

\end{enumerate}
\section{数据库设计}

在设计该系统数据库时，根据数字孪生场景需要和数据采集的一些特点，数字孪生平台的数据库设计需要考虑多个方面，包括数据库的范围和目的、结构和模式、安全性和可靠性、性能和扩展性以及数据采集和清洗等。在设计过程中需要综合考虑各个方面的需求，灵活应用不同的技术和方法，确保数字孪生平台的高效、安全、可靠运行。

\subsection{设计要点}

\begin{enumerate}

\item 数据库的范围和目的：数字孪生平台通常需要处理大量的数据，包括实时数据、历史数据、静态数据等。因此，需要确定数据库的范围和目的，包括存储数据的类型、数据的来源和流向、数据的格式等。

\item 数据库的结构和模式：为了支持数字孪生平台的多样化需求，数据库需要具有灵活的结构和模式。可以采用关系型数据库或非关系型数据库，或者二者结合使用。同时，需要确定数据库的表结构、字段类型、主键、外键等。

\item 数据库的安全性和可靠性：数字孪生平台通常涉及到重要的实时数据和设备信息，因此需要确保数据库的安全性和可靠性。可以采用多重备份、加密、权限控制等方式来保证数据的完整性和保密性。

\item 数据库的性能和扩展性：数字孪生平台需要支持高效的数据处理和分析，因此需要考虑数据库的性能和扩展性。采用分布式数据库、内存数据库等技术来提高性能，并采用分区、分片等方式来实现扩展性。

\item 数据库的数据采集和清洗：数字孪生平台需要从多个来源获取数据，并进行数据清洗和处理。因此需要设计适合的数据采集和清洗模块，确保数据的准确性和一致性。

\end{enumerate}

\subsection{时序数据库设计}
数字孪生平台除了大量结构化的数据需要使用关系型数据库存储外，还需要存储大量的时序数据，例如200个采集点位每天就可以产生4GB数据，因此需要设计一个专门用于存储时序数据的数据库用以存储和查询。
时序数据有着非常强的特殊性，根据其特点，时序数据库着重优化设计以下几个方面：
\begin{enumerate}
    \item 数据模型\\
确定时序数据结构。时序数据可以表示为一个包含时间戳、度量值和标签（例如设备ID、位置等）的数据点。数据模型需要能够支持对这些数据点的高效插入、查询和删除操作。
\item 数据压缩\\
时序数据库需要处理和存储大量的数据。为了节省存储空间和提高性能，采用Gorilla压缩算法对数据进行编码。
\item 数据分片和分布式存储
根据时序数据弱关系性的特点，非常适合进行数据分片和分布式存储。数据分片是将数据按照一定的规则分成多个子集，每个子集存储在不同的数据库节点上。这样可以将查询和写入操作的负载分散到多个节点，提高性能。
\item 索引和查询优化\\
时序数据索引较为固定，主要查询是根据时间戳和标签进行查询，为了提高数据查询效率，时序数据库需要对这些数据添加索引，以便快速定位数据。同时，时序数据库还需要对查询进行优化，以便提高查询性能。
\item 数据保留策略\\
由于时序数据具有时效性，可能需要根据数据的重要性和时效性来制定数据保留策略。数据保留策略可以按照时间或数据量来设置，例如保留最近一个月的数据或保留最近1000万条数据等。
\item 数据降采样和聚合\\
为了提高查询性能和降低存储需求，时序数据库支持数据降采样（downsampling）和聚合操作。数据降采样是将高频率的数据点合并为低频率的数据点，例如将每秒的数据点合并为每分钟的数据点。数据聚合是对一组数据点进行统计分析，例如计算平均值、最大值和最小值等。通过降采样和聚合，可以极大降低存储需求和提高查询性能。
\end{enumerate}

\section{文件组织结构}
该平台在设计之初就考虑到涉及用户端、后端、数据库、硬件端，编写语言涉及c，c++，python，go，rust，js，matlab等，项目管理和组织也较为复杂，故根据项目各部分特点设计了如下的代码2级目录结构。

\begin{itemize}
    \item /odtc：主要为可视化前端代码
    \item /odtc/Common：核心类
    \item /odtc/Filtering：pipeline中数据过滤器
    \item /odtc/GenericFiltering：连接到外部仿真器的包装器
    \item /odtc/GeoVis：处理地形可视化的类
    \item /odtc/Graphics：处理3D数据的类
    \item /odtc/GUISupport：ui界面依赖库
    \item /odtc/Hybrid：依赖于多个其他目录中的复杂类
    \item /odtc/Image：图像处理过滤器
    \item /odtc/IO：用于读写不同类型文件的类
    \item /odtc/Parallel：并行算法处理，用于支持MPI计算
    \item /odtc/Rendering：渲染类
    \item /odtc/Utilities：工具类
    \item /odtc/VolumeRendering：用于不同类型的mesh数据绘制
    \item /odtc/Wrapping：python接口支持
    \item /webds：为分布式消息网络的代码
    \item /webds/cfg：配置库
    \item /webds/client：不同语言的客户端，如go/js/python/rust/c
    \item /webds/cluster：分布式协议及集群节点管理
    \item /webds/command：命令行支持，如启动集群，启动节点，扫描集群，扫描消息等
    \item /webds/conn：节点链接管理类
    \item /webds/core：核心类
    \item /webds/device：设备依赖库
    \item /webds/doc：文档
    \item /webds/errors：错误处理
    \item /webds/libs：通用依赖库
    \item /webds/message：消息协议
    \item /webds/trie：消息路由算法
    \item /odtlib：OneDT系统节点的依赖库
    \item /odtlib/atom：节点通信依赖
    \item /odtlib/iopack：消息包依赖
    \item /odtlib/command：命令行支持
    \item /odtlib/topic：消息主题管理
    \item /odtlib/status：节点状态管理
    \item /odtb：OneDT系统后端
    \item /odtb/api：后端接口代码
    \item /odtb/auth：权限系统及安全协议
    \item /odtb/cfg：配置库
    \item /odtb/doc：文档库
    \item /odtb/lib：通用依赖库
    \item /odtb/media：媒体库
    \item /odtb/report：自动化报告生成
    \item /odtb/models：数据库模型
    \item /odtb/static：静态文件
    \item /odtb/stage：场景及设备管理
    \item /odtb/utils：工具类
    \item /odtb/ws：websocket支持
\end{itemize}

\section{3d渲染引擎}

3D渲染技术是是计算机图形学的核心技术，也是数字孪生技术用户交互技术中最为重要的一环，将现实世界的设备、系统或过程与虚拟模型相结合，并通过三维图像的形式呈现出来，方便使用者更直观地了解和探索模型的结构、状态和运行情况。现代3d渲染技术已经是一项非常成熟的技术，考虑到数字孪生技术不单纯是对现实世界的视觉数据复刻，在研究数值仿真计算的相关原理后对现有的渲染技术进行优化。

\subsection{渲染技术基本流程}
渲染技术最基本流程包括几何表示、坐标变换、光栅化、着色和后处理。
\begin{enumerate}
    \item 几何表示\\ 渲染引擎首先需要对三维场景中的物体进行几何表示。这通常涉及将物体表面划分为多边形网格（如三角形），并将顶点、法线、纹理坐标等属性数据存储在顶点缓冲区中。为了构建完整的三维场景，还需要添加光源、相机等元素。
    \item 坐标变换\\
坐标变换是将物体从一个坐标系映射到另一个坐标系的过程。这包括：
模型变换：将物体从模型坐标系（Model Space）变换到世界坐标系（World Space）。
观察变换：将物体从世界坐标系变换到视点坐标系（View Space，也称摄像机坐标系）。
投影变换：将物体从视点坐标系变换到投影坐标系（Projection Space），并执行透视除法，将坐标规范化为归一化设备坐标（Normalized Device Coordinates, NDC）。
\item 光栅化\\
光栅化阶段负责将变换后的三维几何数据转换为屏幕上的像素。这包括确定哪些像素位于三角形内部，并计算这些像素的深度值。为了消除隐藏面，渲染引擎通常使用深度缓冲区进行深度测试。
\item 着色\\
在着色阶段，渲染引擎根据物体的表面属性、光源、相机位置等因素计算像素的颜色。光照模型（如Phong模型或Blinn-Phong模型）用于模拟环境光、漫反射光、镜面反射光等效果。现代渲染引擎通常使用可编程着色器（如顶点着色器、片段着色器等）来实现更复杂的着色效果。
\item 后处理\\
在渲染流程结束后，可以对生成的二维图像进行后处理。这包括添加阴影、环境光遮蔽、光泽反射、景深、运动模糊等效果，以增强图像的真实感和视觉质量。
\end{enumerate}

\subsection{存储格式}
三维模型格式是用于存储和表示三维模型数据的文件类型。这些格式包含几何形状、纹理、材质、动画以及其他与3D模型相关的信息。在计算机图形学、游戏开发、电影制作和其他领域，有多种不同的三维模型格式，它们各自具有独特的特点和用途，单基本不包含对于网格和场变量数据的存储支持，常见的模型格式如obj、stl、ply、3mf、dae、fbx、gltf等。而在数值仿真领域，通用的存储格式为vti、vtu等，除了包含基本的三维模型，这些格式还用于存储数值仿真计算结果，如应力场、应变场、温度场等，单不包含纹理、材质、动画、骨骼等信息。因此在应用于数字孪生领域时，这些格式都具有各自的优点和缺点，且都不包含对于实体传感单元的存储构建。\\

数字孪生时代的存储模型不单要包含以上内容，还需包含采集到的真实的物理信息，如多个点的温度、压力、流量等，以及采集单元的位置信息，因此需要自定义存储格式，以便于存储读取和分析，如图\ref{fig-f27}所示，定义了包含更多数据源的存储格式。

\begin{figure}[!ht]
    \centering%
    \includegraphics[width=0.8\textwidth]{figure/f27.png}
    \caption{自定义Mesh存储结构} 
    \label{fig-f27}
\end{figure}

\begin{itemize}
    \item scene：场景结构描述条目。它通过引用node来定义场景图。
    \item node：场景图中的一个结点。它可以包含一个变换(比如旋转或平移)，引用更多的子结点。它可以引用网格和相机，以及描述网格变换的蒙皮。
    \item camera：定义了用于渲染场景的视锥体配置。
    \item mesh：描述了场景中出现的3D对象的网格数据。它引用的accessor对象可以用来访问真实的几何数据。它引用的material对象定义了3D对象的外观。
    \item skin：定义了用于蒙皮的参数，参数的值通过一个accessor对象获得。
    \item animation：描述了一些结点如何随时间进行变换(比如旋转或平移)。
    \item accessor：一个访问任意数据的抽象数据源。被mesh、skin和animation元素使用来提供几何数据，蒙皮参数和基于时间的动画值。它通过引用一个bufferView对象，来引用实际的二进制数据。
    \item material：包含了定义3D对象外观的参数。它通常引用了用于3D对象渲染的texture对象。
    \item texture：定义了一个sampler对象和一个image对象。sampler对象定义了image对象在3D对象上的张贴方式。
    \item image：定义了一个2D图像。它引用了一个bufferView对象，来引用实际的二进制数据。
    \item sampler：定义了一个texture对象的采样器。它定义了纹理的过滤器和张贴方式。 
    \item simulation: 定义了仿真数据，包括仿真数据的类型、仿真数据的维度、仿真数据的大小、仿真数据的范围、仿真数据的分辨率、仿真数据的数据类型、仿真数据的数据等。
    \item physical：定义了物理数据，包括物理数据的类型、物理数据的维度、物理数据的大小、物理数据的范围、物理数据的分辨率、物理数据的数据类型、物理数据的数据等。
\end{itemize}

因为上述格式根据gltf格式进行扩展，因此可以使用gltf格式的解析器进行解析，同时兼容现在主流的三维模型格式，如obj、stl、ply、3mf、dae、fbx、gltf等，但是对于仿真领域的存储格式需要单独开发解析，如vti/vtk/vtr/vtmb/vtmg/bthd等18种格式，该领域格式较为多且比较复杂，因此目前仅适配对于最通用的vti/vtu格式，后续会逐渐增加对于并行仿真计算格式的支持。


\subsection{渲染技术优化}
在现有游戏及相关3d渲染引擎中，由于对于显示细节的追求，对于非规格化平面，经常会采取三角面进行细分，因为三角形可以以任意精度表达任意平面，在计算样条插值、各种复杂的数学变换、等值面等计算代价最小，最简单。

但是在数字孪生系统中，并不单纯的追求对于现实世界的视觉复刻，而是需要对于现实世界的数值计算进行可视化，因此在渲染技术上，需要对于渲染技术进行优化，以减少渲染时间，提高渲染效率，同时与数值仿真计算中单元相对应，实现真实物理采集点-仿真计算单元-渲染单元三者统一。

\begin{figure}[!ht]
    \centering%
    \includegraphics[width=0.8\textwidth]{figure/f20.png}
        \caption{网格计算单元}
        \label{fig-f20}
\end{figure}


如图\ref{fig-f20}所示，图像数据，直线网格，结构化网格，非结构化点，多边形数据，非结构化网格，这些是在数值仿真计算中遇到的网格计算单元，这些数据都可以通过不同的方式进行渲染，在仿真计算中代表一个数据单元，在传感器网络中可能代表一个有效采集点。
在进行同步仿真时，通常需要对模型进行降阶处理，以满足实时仿真需要，如图\ref{fig-f26}所示，从左到右为网格细化过程，这个过程通常对应的是计算精度增加，计算时间极大增加，选择一些合适的模型降阶算法，结合实际采集到的数据信息，可以在保证99精度的情况下有效的降低模型单元数，极大提高计算效率，实现从右向左模型降阶。

\begin{figure}[!ht]
    \centering%
        \includegraphics[height=4cm]{figure/f26.png}
        \caption{非结构化网格优化}
        \label{fig-f26}
\end{figure}

\begin{figure}[!ht]
    \centering%
    \includegraphics[width=0.8\textwidth]{figure/f28.png}
        \caption{数据对象与算法过滤器生成可视化管道Pipeline}
        \label{fig-f28}
\end{figure}
如图\ref{fig-f28}对于孪生数据的最终显示，除了简单的三维结构和贴图外，对于采集到的信息和仿真得到的信息以及根据历史数据预测的信息等多个数据源，选择合适的过滤算法，去显示最终的场变量信息，实现更有价值信息的实时显示，


