Web 三维组态的仿真运用案例:民航飞机的数据监控

2024-08-30 10:58

本文主要是介绍Web 三维组态的仿真运用案例:民航飞机的数据监控,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在飞机航行的过程中,客舱里座位上方的荧屏上,除了播放电视剧和广告之外,还会时不时的切换到一个飞机航行的监控系统。这个监控系统的主要目的是,让乘客可以了解到飞机在航行过程中的整体状况、距离目的地的航线进程以及一些有可能出现的突发事件。飞机航行的监控系统在一定程度上,可以使乘客在旅途过程中得到准确的信息源,最重要的是可以使乘客在旅途中得到安心。在保障乘客获取到实际信息源的同时,飞机航行的监控系统也能将采集到的数据及时的反馈给航务人员,而且将数据记录保存下来,在飞机过站或航后供航务和机务人员使用和监测维护。介于 2D 组态和 3D 组态上,Hightopo(以下简称 HT )的 HT for Web 产品上的有着丰富的组态化可供选择,本文将介绍如何运用 HT 丰富的 2/3D 组态搭建出一个飞机航行的监控系统的解决方案。

预览地址:flight-monitor

系统分析

飞机航行监控是一种测量、跟踪飞机性能变化趋势的简单而实用方法。在日常航班飞行中,用机载仪表记录飞机巡航时的有关参数,并将其与原有性能进行比较。监控的主要参数有:飞行单位时间消耗的燃油量、飞机的巡航飞行速度和消耗单位燃油量飞机飞过的水平距离。它们分别表示发动机、飞机及飞机发动机的综合性能。它们分别表示发动机、飞机及飞机发动机的综合性能。性能监控的结果,既可为飞机维修提供可能的故障信息,又为制定飞行计划提供可靠的性能依据。

目前,先进的喷气运输机都已安装飞行状态监控系统,它记录下有关参数值,并存储在数据管理装置中,这些数据可以发送到或在飞机着陆后送到地面站,用专用计算机程序进行计算和修正,使性能监控数据采集、发送、计箅分析工作自动化,节省了人力,提高了精确度。

1、飞行数据记录器:自从飞行数据记录器 FDR(Flight Data Recorder)“俗称黑匣子”诞生以来,其提供的详实准确的飞行数据为事故调查、机务维护保障、安全运营监控提供了重要依据,成为航空安全运营的重要管理手段。

2、ACMS(Aireraft Condition Monitoring System)的系统概述:ACMS 系统是飞机上安装的先进机载数据采集和处理系统,它能以实时方式收集数据,对发动机状态和飞行性能进行监控以及进行特殊的工程调查。由飞机通信寻址与报告系统(ACARS)通过地空数据链发送到地面接收站,最后传送到航空公司的终端,也可通过快速存取记录器(QAR)将数据记录保存下来,在飞机过站或航后供航务和机务人员使用。

而 HT 实现的业务功能可以通过ACMS 系统采集到的数据,对接到显示终端去展示,通过实时监测的数据准确地显示出来,起到对飞机状态的监控功能并即时反馈信息数据的变化。

实现过程

云中穿行效果

为了达到飞机云中穿行的效果,最开始我遇到的问题是飞机飞行的层次感,也就通常所说的透视效果,这里我采用的是云通道和云背景以不同的速度流动,制造一种飞行的透视效果。

云我采用的是贴图的方式呈现的,但是仅仅是贴图会遮挡天空和飞机,非常影响飞机飞行的观感,所以我开启了相应图元的transparentopacity,云背景和云通道设置不同的透明度,不仅增加了层次感,还会让人产生云朵从眼前飘过的错觉。

云通道采用的是ht.Polyline类型,通道缩放拉大了 Y 轴的比例,使云通道有更大的纵向空间,设置reverse.flip背拷贝使云通道内部也显示出贴图,仿佛让飞机置身于云海中穿梭;云背景采用ht.Node类型,只设置一个面显示充当云背景。

整体的云流动效果采用offset偏移实现,改变相应图元或相应图元面的贴图偏移量来达到飞机云中穿行的效果, 代码如下:

var i = 1,p = 0;
setInterval(() => {i -= 0.1; p += 0.005;clouds.s('shape3d.uv.offset', [i, 0]);cloudBackground.s('all.uv.offset', [p, 0]);
}, 100);
升降颠簸效果

虽然达到了飞机云中穿行的效果,但是如果飞机只是直直的飞行,那也会降低飞行的实感,相信坐过飞机的朋友肯定都遇到过因气流产生的颠簸,也经常感受到飞机飞行途中的爬升和下降,这其实是因为飞机的航线并不是一直固定在一个高度上,有时会爬升有时会下降,所以我就用ht-animation.jsHT 动画扩展插件去实现飞机颠簸效果,代码如下:

dm.enableAnimation(20);
plane.setAnimation({back1: {from: 0,to: 160,easing: 'Cubic.easeInOut',duration: 8000,next: "up1",onUpdate: function (value) {value = parseInt(value);var p3 = this.p3();this.p3(value, p3[1], p3[2]);}},//...省略相似start: ["back1"]
});
球扇形视角限制

飞行效果完善之后,这时我就遇到了一个比较棘手的问题,因为实际上虽然看着飞机是在云海中穿梭,但是仅仅是在通道中飞行,背景其实也只是平面贴图,所以当视角到达某种程度的时候就会有强烈的违和感和不真实感,就需要一个视角限制,使视角的调整刚刚好在一个范围内。

视角限制的话一般是限制 g3d 的 eyecenter ,不太了解的朋友可以去看 hightopo 官网中的 3d 手册,里面有详细的说明,这里我就不再赘述了;因为视角范围的关系,所以我决定固定center的位置,代码如下:

g3d.addPropertyChangeListener(e => {// 固定中心点if (e.property === 'center') {e.newValue[0] = center[0];e.newValue[1] = center[1];e.newValue[2] = center[2];}
}

然后再把eye限制在某一个范围内就大功告成了,然而这里却并不是那么简单,最开始我把eye限制在一个立方体的空间内,但交互效果很不理想,考虑到 g3d 默认交互中,鼠标拖拽平移视角变换时,实际上eye是在一个以center为球心的球面上运动的,所以我决定从这个球中挖出来一块作为eye的限制空间,也就是球扇形,不太理解的朋友可以参考这个图:

球扇形视角限制,一共需要三个参数,分别是中心参考轴、中心轴和外边所成角度、所在球限制半径,其中中心参考轴可根据初始eyecenter的连接延长线确定,所在球限制半径又分最大限制和最小限制,代码如下:

function limitEye(g3d, eye, center, options) {var limitMaxL   = options.limitMaxL,limitMinL   = options.limitMinL,limitA      = options.limitA;g3d.addPropertyChangeListener(e => {// 固定中心点if (e.property === 'center') {e.newValue[0] = center[0];e.newValue[1] = center[1];e.newValue[2] = center[2];}// 限制视角if (e.property === 'eye') {var newEyeV = new ht.Math.Vector3(e.newValue),centerV = new ht.Math.Vector3(center),refEyeV = new ht.Math.Vector3(eye),refVector = refEyeV.clone().sub(centerV),newVector = newEyeV.clone().sub(centerV);if (centerV.distanceTo(newEyeV) > limitMaxL) {newVector.setLength(limitMaxL);e.newValue[0] = newVector.x;e.newValue[1] = newVector.y;e.newValue[2] = newVector.z;}if (centerV.distanceTo(newEyeV) < limitMinL) {newVector.setLength(limitMinL);e.newValue[0] = newVector.x;e.newValue[1] = newVector.y;e.newValue[2] = newVector.z;}if (newVector.angleTo(refVector) > limitA) {var oldLength = newVector.length(),oldAngle  = newVector.angleTo(refVector),refLength = oldLength * Math.cos(oldAngle),vertVector,realVector,realEye;refVector.setLength(refLength);newEyeV = newVector.clone().add(centerV);refEyeV = refVector.clone().add(centerV);vertVector = newEyeV.clone().sub(refEyeV);vertLength = refLength * Math.tan(limitA);vertVector.setLength(vertLength);realVector = vertVector.clone().add(refEyeV).sub(centerV);realVector.setLength(oldLength);realEye = realVector.clone().add(centerV);// 防止移动角度大于 180 度,视角反转if (oldAngle > Math.PI / 2) {realEye.negate();}e.newValue[0] = realEye.x;e.newValue[1] = realEye.y;e.newValue[2] = realEye.z;}  }})
}

飞机监控系统

当然作为监控系统,自然要有监控了,增加右下角的小地图,并提供三种模式,分别是聚焦飞机,聚焦飞行轨迹和聚焦地图,并根据飞机的飞行方向控制飞行轨迹的流动效果,其中聚焦飞机会跟随飞机移动进行fitData,使飞机一直处于小地图的中心,代码如下:

var fitFlowP = function (e) {if (e.property === 'position' && e.data === plane) {mapGV.fitData(plane, false);}
};
buttonP.s({'interactive': true,'onClick': function (event, data, view, point, width, height) {map.a('fitDataTag', 'plane2D');mapGV.fitData(plane, false);mapDM.md(fitFlowP);}
});
buttonL.s({'interactive': true,'onClick': function (event, data, view, point, width, height) {mapDM.umd(fitFlowP);map.a('fitDataTag', 'flyLine');mapGV.fitData(flyLine, false);}
});
// ...省略

在这里插入图片描述

增加鼠标移到飞机相应位置进行名称的提示、双击后显示飞机相应位置的信息面板并将视角聚焦到面板上、点击飞机任意地方切换回飞机飞行模式等效果。

左侧增加监控面板替代上面提到的双击相应位置这步操作直接聚焦到相应位置的信息面板上,这里按钮开启了交互并添加了相应的交互逻辑,代码如下:

button_JC.s({'interactive': true,'onClick': function (event, data, view, point, width, height) {event.preventDefault();let g3d = G.g3d,g3dDM = G.g3d.dm();g3d.fireInteractorEvent({kind: 'doubleClickData',data: g3dDM.getDataByTag(data.getTag())})}
});
//...省略

天空渲染效果

既然是监控系统肯定是 24 小时无差别的监控,这就涉及到一个问题,我总不可能半夜的时候飞机也从瓦蓝瓦蓝的天空上飞过,这就很欠缺真实性了,所以要有一个天空从亮到暗再从暗到亮的过程,这个过程我暂定到 06:00-06:30 和19:00-19:30 这两个时间段。

天空采用的是shape3d : 'sphere’球形,包裹整个场景,然后使用reverse.flip背拷贝 和blend染色,之后天空就可以渲染成我想要的颜色,如果按照时间改变天空明暗只要改变染色值就可以了。

但是由于白天和晚上光照情况的不同,云反射光的强度也不同,就导致了白天和晚上云的差异,所以也要调整云道和云背景的贴图的opacity透明度,晚间更为透明度,代码如下:

if ((hour > 6 && hour < 19) || (hour == 6 && minutes >= 30)) {timePane && timePane.a({'morning.visible': false,'day.visible': true,'dusk.visible': false,'night.visible': false,'day.opacity': 1})skyBox.s({"shape3d.blend": 'rgb(127, 200, 240)',})cloudBackground.s({"back.opacity": 0.7,})clouds.s({"shape3d.opacity": 0.7,})
} else if ((hour < 6 || hour > 19) || (hour == 19 && minutes >= 30)) {
//...省略
} else if (hour == 6 && minutes < 15 ) {
//...省略
} else if (hour == 6 && minutes >= 15 && minutes < 30) {
//...省略
} else if (hour == 19 && minutes < 15) {
//...省略
} else if (hour == 19 && minutes >= 15 && minutes < 30) {
//...省略
}


这里我还增加了对右上角时间面板时间状态图标的支持,并增加了图标切换时的渐隐渐显效果,同时给时间面板状态图标位置增加了点击切换到下一时间状态的功能。

为了演示效果我增加了时间倍速按钮,下图是 500 倍时间流速下的变化情况:

总结

身处大数据时代的我们,在网络科技发展越来越快的环境下,迎来了 5G 的新征程和工业4.0的新变革,在信息数据采集传输和数据可视化系统的融合下,可以发掘出许多行业管控可视化系统的解决方案。而 HT 长久以来一直致力于多样化行业系统可视化的搭建,涉猎的技术行业所累积的经验,通过自主创新研发的技术产品,已经打造出许多行业上具有代表性意义的可视化管控系统,例如同样有关于飞机的监控可视化系统:无人机 3D 可视化系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hvYQGzq8-1591092123840)(https://img2020.cnblogs.com/blog/1496396/202006/1496396-20200601185137243-2111613258.gif)]

2019 我们也更新了数百个工业互联网 2D/3D 可视化案例集,在这里你能发现许多新奇的实例,也能发掘出不一样的工业互联网:https://mp.weixin.qq.com/s/ZbhB6LO2kBRPrRIfHlKGQA

同时,你也可以查看更多案例及效果:https://www.hightopo.com/demos/index.html

这篇关于Web 三维组态的仿真运用案例:民航飞机的数据监控的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120624

相关文章

MybatisPlus中几种条件构造器运用方式

《MybatisPlus中几种条件构造器运用方式》QueryWrapper是Mybatis-Plus提供的一个用于构建SQL查询条件的工具类,提供了各种方法如eq、ne、gt、ge、lt、le、lik... 目录版本介绍QueryWrapperLambdaQueryWrapperUpdateWrapperL

Prometheus+cpolar如何在手机上也能监控服务器状态?

《Prometheus+cpolar如何在手机上也能监控服务器状态?》本文强调了通过Cpolar这一内网穿透工具,轻松突破Prometheus仅限于局域网访问的限制,实现外网随时随地访问监控数据,教你... 目录前言1.安装prometheus2.安装cpolar实现随时随地开发3.配置公网地址4.保留固定

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

Springboot3 ResponseEntity 完全使用案例

《Springboot3ResponseEntity完全使用案例》ResponseEntity是SpringBoot中控制HTTP响应的核心工具——它能让你精准定义响应状态码、响应头、响应体,相比... 目录Spring Boot 3 ResponseEntity 完全使用教程前置准备1. 项目基础依赖(M

JavaWeb 中的 Filter组件详解

《JavaWeb中的Filter组件详解》本文详细介绍了JavaWeb中的Filter组件,包括其基本概念、工作原理、核心接口和类、配置方式以及常见应用示例,Filter可以实现请求预处理、响应后... 目录JavaWeb 中的 Filter 详解1. Filter 基本概念1.1 什么是 Filter1.

C++11中的包装器实战案例

《C++11中的包装器实战案例》本文给大家介绍C++11中的包装器实战案例,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录引言1.std::function1.1.什么是std::function1.2.核心用法1.2.1.包装普通函数1.2.

Spring IOC核心原理详解与运用实战教程

《SpringIOC核心原理详解与运用实战教程》本文详细解析了SpringIOC容器的核心原理,包括BeanFactory体系、依赖注入机制、循环依赖解决和三级缓存机制,同时,介绍了SpringBo... 目录1. Spring IOC核心原理深度解析1.1 BeanFactory体系与内部结构1.1.1