Based on HTML5 WebGL's 3D sci-fi fans

Foreword
  For many centuries, the wind turbine with the same hydraulic machinery, as a power source alternative to human, animal, for the development of productive forces played an important role. Electrical power is widely used in modern and 1950s found that Middle East oil fields, the development of wind turbine generators slow down.
The early 1970s, due to the "oil crisis", there has been the problem of energy shortage, it was recognized that the instability of conventional fossil energy supply and limited nature, then seek clean and renewable energy became an important issue in the modern world. Wind energy as a renewable, non-polluting natural energy again attracted attention.
Now I hope that through this fan demo so that each function of wind turbines close display for everyone, so that we can better understand wind turbines.
This demo using  HT for Web  product lightweight HTML5 / WebGL modeling program.
 
 
Fan Main Functions
effect:
  
 
Surroundings feature:
  A. Wind speed values.
  A virtual wind speed, wind speed values ​​will affect the efficiency of power generation and change the pitch of wind turbine systems.
 
   II. Statistics .
  

  Ambient temperature, cabin temperature, the temperature of the gearbox, the percentage of wind speed pattern will change over time.

   III. Environmental monitoring .
  
  The left fan individual parameters monitored embodiment, it is the right line graph of wind speed variation.
 
   IV. Monitoring data .  
  

  Fan abnormality occurs in the power generation process, the fault location and the time of failure occurrence. Collect information about the exception in favor of people anomaly analysis, and exception handling.

  V. yaw system .
  
  Yaw system, also known as wind means is part of a wind turbine nacelle, when the effect that changes in the direction of the wind velocity vector, wind direction can be aligned quickly and smoothly, in order to obtain maximum wind power wind turbine.
 
   . 变桨系统
  
  变桨系统作为大型风电机组控制系统的核心部分之一,对机组安全、稳定、高效的运行具有十分重要的作用。稳定的变桨控制已成为当前大型风力发电机组控制技术研究的热点和难点之一。
  变桨控制技术简单来说,就是通过调节桨叶的节距角,改变气流对桨叶的攻角,进而控制风轮捕获的气动转矩和气动功率。
 
按钮控制功能:
 
   风机启停:

  

  线框模式:

  

  机舱视角:

  

  发电工艺:

  

 

整理思路:

    场景部分

  这里把 3D 当做背景嵌套在 2D 场景中。

   这样在初始化图纸的时候,直接反序列化 2D 图纸即可。

 

  事件部分

  2D 图纸中有很多的按钮,通过它们来控制 3D 中的一些动画。

  实现思路是在反序列化图纸的时候把 2D、3D 的 模型和视图对象挂载到 window 上,这样在不同的场景中都可以获取到相应的数据模型。

 

  环境部分:

  风速、风向、变桨角度这些会在 2D、3D 中所表现,所以可以把他们放到数据池里面,方便管理。

 

具体代码实现:

场景搭建:上面说了,我们把 3D 当做背景嵌套在 2D 中,所以只需要序列化 2D 即可,里面需要进行背景判断的部分代码。

相关伪代码

graphView.deserialize('displays/demo/风力发电机/风力发电机结构查看.json', function (json, dm, gv, datas) {
  if (json.title) document.title = json.title
        if (json.a['json.background']) {
            var bgJSON = json.a['json.background']
            if (bgJSON.indexOf('displays') === 0) {
                var bgGv = new ht.graph.GraphView()
                bgGv.deserialize(bgJSON)
                bgGv.addToDOM()
                graphView.addToDOM(bgGv.getView())
            }
            else if (bgJSON.indexOf('scenes') === 0) {
                var bgG3d = new ht.graph3d.Graph3dView()
                bgG3d.deserialize(bgJSON)
                bgG3d.addToDOM()
                graphView.addToDOM(bgG3d.getView())
            }
            graphView.handleScroll = function () { }
        }
 })

 

模拟风速:每隔30s,随机产生一个值,当做风速值。

相关伪代码

// 模拟风速
mockWindSpeed() {
  return 8 + Math.random() * 12
}

 

数据统计:每隔30s,随机变换。

效果:

相关伪代码

// 指针和扇叶旋转的角度 进行变化
var oldPointerValue = pitchSystem.a('pointer') || 0
// 风机扇叶和变桨系统的旋转角度 var newRotateAngular = (this.windSpeed - 8) * 7.5 * translateAngularRadian.radian var addPointerValue = newRotateAngular - oldPointerValue var oldWindSpeedClip = environmentalData.a('windSpeedClip') || 0 var newWindSpeedClip = (this.windSpeed - 8) / 12 var addWindSpeedClip = newWindSpeedClip - oldWindSpeedClip var anim = {   duration: 1e3,   easing: (v) => {     return v * v },   action: (v) => {     var windSpeed = Number(this.windSpeed.toFixed(2))     var Max = Number(MaxValue.toFixed(2))     var average = Number(Aver.toFixed(2))     var windSpeedClip = oldWindSpeedClip + (addWindSpeedClip * v)     // 设置发电参数随机数据   generator.a({ windSpeed })     // 设置环境监测随机数据     environmentalData.a({ windSpeed, windSpeedClip })     // 设置统计参数随机数据     statisticalParam.a({ average, Max, windSpeed })     // 设置变航系统的指针角度     pitchSystem.a('pointer', oldPointerValue + (addPointerValue * v))   } }
ht.Default.startAnim(anim)

这里涉及到角度和弧度的转换。1° = Math.PI / 180°,1rad = 180° / Math.PI,因为场景中使用的是弧度制,所以需要把随机出的角度值转换成弧度。

这里解释下代码,先获取到当前的值。然后在加上 随机值 - 当前值。比如当前值为 16,随机出的数值有两种情况,1:比当前值大。2:比当前值小。

如果比当前值大的话,比如18,那么就是这样 16 + (18 - 16) * v ( easing 函数运算后的值)

如果比当前值小的话,比如13,那么就是这样 16 + (13 - 16) * v ( easing 函数运算后的值)

这样当随机的时候,就会从当前值平滑的改变到目标值。

 

数据统计:每隔30s,监测当前风机的故障信息。

效果: 

 这里使用了 table.json 文件,通过修改 ht.dataSource 属性添加实时信息。

 相关伪代码

var checkInternals = () => {
  /**
   * 故障信息
   * 变桨系统 主轴 偏航系统 齿轮箱 油冷装置 发电机 风冷装置
   */
    var FailureStatus = { // 正常状态 status1: new Map([ [0, ['舱内温度正常,变桨角度正常。', 'i10']], [1, ['舱内温度正常,主轴转速正常。', 'i9']], [2, ['偏航系统精确。', 'i8']], [3, ['齿轮箱温度正常。', 'i1']], [4, ['油冷装置温控表正常。', 'i3']], [5, ['发电机功率正常。', 'i5']], [6, ['风冷装置正常。', 'i2']] ]), // 异常状态 status2: new Map([ [0, ['变桨角度异常。', 'i10']], [1, ['主轴转速偏高。', 'i9']], [2, ['偏航系统出现偏移。', 'i8']], [3, ['齿轮箱温度偏高。', 'i1']], [4, ['油冷装置内积尘过多。', 'i3']], [5, ['发电机电流过大。', 'i5']], [6, ['风冷装置散热不足。', 'i2']] ]), } // 返回设备正常的状况 status 1: 正常 2: 不正常 var mockQquipmentFailure = (status) => { var { rangeRandom } = common var index = rangeRandom(7) // 返回随机出来的设备情况 return FailureStatus[`status${status}`].get(index) } var info = randomInfo[0] var targetTag = randomInfo[1] this.tableArr = table.a('ht.dataSource') var currentTimeFormat = DateUtil.formatHourTime(new Date()) // 默认是正常 如果找到故障关键字的话 赋值为 异常 var status = 'normal' var time = 0  this.tableArr.push({ status, info, time: currentTimeFormat }) }

我们需要两个 Map 数组方便进行取值操作。一个是正常信息数组,一个是异常信息数组。利用随机值当做一个索引,然后取到相对应的状态信息,添加到 table 中。

如果当前的 status 为 normal,说明是正常信息,否则为异常信息。异常信息的话就可以通过 table.json 的渲染回调函数 "drawCell": function(g, text, rect, option) { } 来修改它的颜色,使其高亮。

 

偏航系统:风机转动的过程中,随着风的位置的不同,通过偏航系统改变方向。

 效果:

   

 相关伪代码

/**
  * 随机偏航系统
  * @param { * }
  */
  randomYawSystem() {
    var { dm } = this   var { d2d } = window   var { rangeRandom } = common   var poll = () => {   // 随机数 30 - 50   var random = 30 + rangeRandom(20)   var cabin = dm.getDataByTag('cabin')    // 将角度度换算成弧度 然后乘以随机数 实现随机风向    var randomDegrees = translateAngularRadian.radian * random   var defaultDegress = translateAngularRadian.radian * 180 ht.Default.startAnim({   duration: 1e3,   action: (v) => {     var oldValue = cabin.getRotationY()     var newValue = randomDegrees     var addValue = newValue - oldValue   cabin.setRotationY(oldValue + addValue * v)   }  })  }
 }

 上面讲到过角度弧度转换,这里先将随机出的角度转换成弧度,然后赋值,进行旋转。

 

 变桨系统:风速的变化影响风机扇叶的角度。

 效果:

相关伪代码:

var old3Value = whiteShell3Line.getRotationX()
var old4Value = whiteShell4Line.getRotationX()
var old5Value = whiteShell5Line.getRotationX()

// 指针和扇叶旋转的角度 进行变化
var oldPointerValue = pitchSystem.a('pointer') || 0
// 风机扇叶和变桨系统的旋转角度 var newRotateAngular = (this.windSpeed - 8) * 7.5 * translateAngularRadian.radian var addPointerValue = newRotateAngular - oldPointerValue whiteShell3Line.setRotationX(old3Value + ((newRotateAngular - oldPointerValue))) whiteShell4Line.setRotationX(old4Value + ((newRotateAngular - oldPointerValue))) whiteShell5Line.setRotationX(old5Value + ((newRotateAngular - oldPointerValue)))

 先获取到每个扇叶当前的 X 轴旋转值,再获取到需要旋转的角度值,进行赋值。

 

 风机启停:风机的启动和停止

 相关伪代码:

var fanWireframe = d3d.getDataByTag('fanWireframe')
fanWireframe.setRotationMode('zxy')
this.allAnimManage = new Map([['fanRotate', null]])
var fanRotating = (easeType) => {   anim = ht.Default.startAnim({     duration: 5e3,     easing: (t) => easeIn(t),     action: (v) => {       fanWireframe.setRotationZ(fanWireframe.getRotationZ() + speed)     // 风机轮毂旋转     if (fanWireframe.getRotationZ() <= -6.28) {       fanWireframe.setRotationZ(0)     }     // 风机扇叶 uv 偏移     for (let i = 1; i < 17; i++) {       var node = d3d.getDataByTag(`q${i}`)       node.s('shape3d.uv.offset', fanOffsetData(v)[i - 1])     }     // 暂停命令     if (isStop) {       stopFanRotate(fanWireframe.getRotationZ())       anim.pause()       anim = null     }     },   finishFunc: () => {     fanRotating(false)   } }) this.allAnimManage.set('fanRotate', anim) }

 因为可以启动和停止,那么我们就可以通过控制 ht.Default.startAnim() 的返回对象的 resume 和 pause 来达到效果。

 所以我把风机旋转的动画添加到了全局对象中,方便进行调用。

 setRotationMode('zxy') 方法是设置三维旋转模式,顺序是 z -> x -> y,先进行z轴旋转,再进行x轴旋转,最后进行y轴旋转。设置目的是为了避免坐标轴受外部旋转的影响。

 

 风向: 根据风的角度,判断当前是什么位置的风。

 效果:

 相关伪代码:

// 判断风向
var windDirection = (rotate) => {
    let direction

    switch (true) { case rotate === 0: direction = '南' break case rotate === 90: direction = '东' break case rotate === 180: direction = '北' break case rotate === 240: direction = '西' break case rotate > 0 && rotate < 90: direction = '东南' break case rotate > 90 && rotate < 180: direction = '东北' break case rotate > 180 && rotate < 270: direction = '西北' break case rotate > 270 && rotate < 360: direction = '西南' break default: direction = '没有找到风向' } return direction } // 判断是哪个方向 var angular = randomDegrees * translateAngularRadian.angular var direction = windDirection(angular)

 将罗盘的指针角度放到 switch 进行判断,如果找到对应的风向就返回。

 

总结

风力发电是一个工业互联网的典型例子,我们可以通过对风机模型或者监测数据进行分析,可以减轻我们工作复杂程度,帮助我们快速了解发电内部结构及发电功能。

HT 能做的东西远远不止于此,这需要我们丰富的想象力以及自身过硬的技术。我希望可以通过这篇文章向大家传递一种能量,让大家更有兴趣、迸发更多新鲜的想法,去做更多好玩的东西。

 

Guess you like

Origin www.cnblogs.com/xhload3d/p/12131708.html