<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      前言


        隨著工業(yè)物聯(lián)網(wǎng)和互聯(lián)網(wǎng)技術(shù)的普及和發(fā)展,人工填料的方式已經(jīng)逐漸被機(jī)械設(shè)備取代。工業(yè)廠商減小誤操作、提升設(shè)備安全以及追求高效率等制造特點對設(shè)備的要求愈加高標(biāo)準(zhǔn)、嚴(yán)要求。同時機(jī)械生產(chǎn)以后還需遵從整個項目流程的規(guī)范管理,如何實行管理與交接也是一大嚴(yán)峻的挑戰(zhàn)。因此,整個生產(chǎn)流程中還應(yīng)該制定一套關(guān)于管理流程的可視化界面。

        在工業(yè)過程控制中,按被控對象的實時數(shù)據(jù)采集的信息與給定值比較產(chǎn)生的誤差的比例、積分和微分進(jìn)行控制的控制系統(tǒng),簡稱 PID 控制系統(tǒng)。PID
      控制生產(chǎn)環(huán)境具有適應(yīng)性強(qiáng),魯棒性強(qiáng),使用方便等特點。進(jìn)料系統(tǒng)則涉及到超高壓技術(shù),在流水線系統(tǒng)中廣泛應(yīng)用,能夠?qū)崿F(xiàn)設(shè)備半自動化或自動化送料作業(yè),解決傳統(tǒng)進(jìn)料方式計量不準(zhǔn)、工作環(huán)境污染以及工人勞動強(qiáng)度高等問題,從而實現(xiàn)高效的流水線加工。結(jié)合
      PID 和自動化部署,可以為電力、機(jī)械、冶金、化工、食品、紡織等工業(yè)或者民用行業(yè)供需。本篇文章通過搭建危險廢物進(jìn)料系統(tǒng)的 2D
      場景以及數(shù)據(jù)界面展示,幫助我們了解如何使用 HT 實現(xiàn)一個可視化的 PID 控制進(jìn)料系統(tǒng)。

        項目地址預(yù)覽:?基于 HTML5? 的 PID-進(jìn)料系統(tǒng)可視化界面
      <https://www.cnblogs.com/htdaydayup/p/基于%20HTML5%20%20的%20PID-進(jìn)料系統(tǒng)可視化界面>?
      http://www.hightopo.com/demo/PID-feed-system/
      <http://www.hightopo.com/demo/PID-feed-system/>

      ?

      效果預(yù)覽

        整體協(xié)作場景



        抓斗操作場景



        進(jìn)料場景



      代碼構(gòu)建

        搭建場景

        該文主要實現(xiàn)的是 2D 場景,我們需要用到拓?fù)浣M件的相關(guān) api 搭建基礎(chǔ)場景:
      1 dataModel = new ht.DataModel(); //數(shù)據(jù)容器,用來存取數(shù)據(jù)節(jié)點Node 2 graphView = new
      ht.graph.GraphView(dataModel);//拓?fù)浣M件 3 graphView.addToDOM(); //將組件添加到body中
        上述代碼添加組件到body中所用的是 addToDom 方法,HT
      組件一般會嵌入BorderPane、SplitView和TabView等容器中使用,而最外層的HT組件則需要用戶手工將 getView() 返回的底層 div
      元素添加到頁面的 DOM 元素中,這里需要注意的是,當(dāng)父容器大小變化時,如果父容器是 BorderPane 和 SplitView
      等這些HT預(yù)定義的容器組件,則HT的容器會自動遞歸調(diào)用孩子組件 invalidate 函數(shù)通知更新。但如果父容器是原生的 html 元素, 則 HT
      組件無法獲知需要更新,因此最外層的 HT 組件一般需要監(jiān)聽 window 的窗口大小變化事件,調(diào)用最外層組件 invalidate 函數(shù)進(jìn)行更新。

        為了最外層組件加載填充滿窗口的方便性,HT 的所有組件都有 addToDOM 函數(shù),其實現(xiàn)邏輯如下,其中 iv 是 invalidate 的簡寫:
      1 addToDom = function(){ 2 var self = this, 3 view = self.getView(), //
      獲取組件的底層div 4 style = view.style; 5 document.body.appendChild(view); //
      將組件底層div添加到body中 6 style.left = '0'; //默認(rèn)所有組件的position都設(shè)置為absolute絕對定位 7
      style.right = '0'; 8 style.top = '0'; 9 style.bottom = '0'; 10
      window.addEventListener('resize',function(){ self.iv(); },false); //
      窗口改變大小,調(diào)用刷新函數(shù) 11 }
        將視圖默認(rèn)方法重置:
      1 graphView.setPannable(false); //禁用通過鼠標(biāo)拖拽進(jìn)行平移操作 2 graphView.setRectSelectable(
      false); //禁用拓?fù)渖线M(jìn)行框選操作 3 graphView.setMovableFunc(()=>{false}); //禁用移動過濾器函數(shù)
        在 2D 編輯器上創(chuàng)建 2D 圖形會生成 JSON 文件,引入生成場景需要進(jìn)行反序列化:
      1 ht.Default.xhrLoad('displays/industry/PID-進(jìn)料系統(tǒng).json',function(text){ 2 var
      json = ht.Default.parse(text);//解析為JSON對象 3 dataModel.deserialize(json); //
      反序列化為場景 4 })
        在 HT 中,Data 類型對象構(gòu)造時內(nèi)部會自動被賦予一個 id 屬性,可通過 data.getId() 和 data.setId( id )
      獲取和設(shè)置,Data 對象添加到 DataModel 之后不允許修改 id 值,可通過 dataModel.getDataById (id ) 快速查找
      Data 對象。但是一般建議 id 屬性由 HT 自動分配,用戶業(yè)務(wù)意義的唯一標(biāo)示可存在 tag 屬性上,通過 Data#setTag( tag )
      函數(shù)允許任意動態(tài)改變 tag 值,通過DataModel#getDataByTag(tag) 可查找到對應(yīng)的 Data 對象,并支持通過
      DataModel#removeDataByTag( tag ) 刪除 Data 對象。我們這邊通過在 JSON 中設(shè)置 Data 對象的 tag
      屬性,在代碼中通過 dataModel.getDataByTag( tag ) 函數(shù)來獲取該 Data 對象:
      1 { 2 "c": "ht.Node", 3 "i": 407, 4 "p": { 5 "displayName": "抓手的結(jié)", 6
      "parent": { 7 "__i": 403 8 }, 9 "tag": "gripKnot", 10 "image":
      "symbols/symbol factory/垃圾處理/抓手的結(jié).json", 11 "position": { 12 "x": -569.62125, 13
      "y": -117.0502514 }, 15 "width": 50, 16 "height": 25 17 }, 18 "s": { 19
      "select.width": 020 } 21 }, 1 var gripRightPaw =
      dataModel.getDataByTag('gripRightPaw'); 2 var girpLeftPaw =
      dataModel.getDataByTag('grapLeftPaw'); 3 var gripKnot =
      dataModel.getDataByTag('gripKnot');


        展開動畫

        HT 對動畫封裝了 ht.Default.startAnim 函數(shù),通過設(shè)置 duration 獲取動畫時長, action
      函數(shù)里為執(zhí)行的動畫屬性,以及 finishFunc 動畫執(zhí)行后的回調(diào)函數(shù),該案例共置8個動畫,包含自驅(qū)動以及異步動畫。下面舉第八個動畫(循環(huán)水流動)為例來理解
      ht 內(nèi)置動畫效果:
      1 //循環(huán)水流動 2 function animation() { 3 var lineJson = {}; 4 var name = ''; 5
      var speed = 20, 6 lastTime = Date.now(); 7 //循環(huán)獲取水流 tag,并設(shè)置初始化
      shape.dash.offset 為0 8 for (var i = 1; i <= 9; i++ ) { 9 if (i != 8) { 10
      name = 'line'+i; 11 lineJson[name] = 0; 12 } 13 } 14 ht.Default.startAnim({
      15 duration: 5000, 16 action: function () { 17 var time = Date.now(), 18   
      deltaTime = (time - lastTime) / 1000; 19 for (var tags in lineJson) { 20 if
      (tags.split('e')[1] % 2) { 21 lineJson[tags] += deltaTime * speed; 22 } else {
      23 lineJson[tags] -= deltaTime * speed; 24 } 25 var lines =
      dataModel.getDataByTag(tags);26 lines.setStyle('shape.dash.offset'
      ,lineJson[tags]);27 } 28 lastTime = time 29 }, 30 finishFunc: function () { 31
      animation();32 //TODO... 也可以在這里異步調(diào)用下一個動畫 33 } 34 }) 35 }
        該例首先根據(jù)已創(chuàng)建的循環(huán)水流(已綁定 tag 標(biāo)簽)通過 for 循環(huán)以及 dataModel. getDataByTag 動態(tài)獲取 Data
      節(jié)點,通過標(biāo)簽名攜帶的數(shù)字判斷水流方向,最終使用 Data.setStyle(可以簡寫為 Data.s ) 設(shè)置虛線部分的偏移距離。



        上面的循環(huán)水流為例,如果 lineJson[tags] += value (定值) ,當(dāng)用戶放大視圖時圖元數(shù)量減少,會多調(diào)用幾次 anim 中的
      action 函數(shù),流動速度增快,縮小同理。因此采用 value = speed * deltaTime 的解決方式,解決視圖在不同縮放 zoom
      的情況下播放速度不一致的問題,具體原理如下:
      1 //global 2 var lastTime = Date.now(); 3 var distance = 0; //距離 4 var
      speed = 20;//速度 5 //action 6 ht.Default.startAnim({ 7 duration:5000, 8
      action:function(){ 9 var time = Date.now(); 10 var deltaTime = (time -
      lastTime) / 1000; 11 distance += speed * deltaTime; 12 lastTime = time; 13 },
      14 finishFunc:function(){//TODO} 15 })
          ht 實現(xiàn)動畫不僅可以使用 startAnim 來驅(qū)動,也可以采用按調(diào)度 addScheduleTask 進(jìn)行實現(xiàn),代碼如下:
      1 dataModel.addScheleTask({ 2 interval, //調(diào)度間隔 3 beforeAction(){}, //調(diào)度開始之前的動作
      4 action(){}, //調(diào)度任務(wù) 5 afterAction(){} //調(diào)度結(jié)束之后的動作 6 })
        也可以使用 callLater 進(jìn)行實現(xiàn),ht 內(nèi)置函數(shù)封裝了非常多關(guān)于動畫有趣且實操性強(qiáng)的 api ,有興趣可以進(jìn)入官網(wǎng)?(
      https://www.hightopo.com <http://www.hightopo.com>?)進(jìn)行了解和學(xué)習(xí),也可以線上申請 framework
      的試用包。如果想要了解更多HT封裝的動畫進(jìn)行操作,可以參考?https://www.cnblogs.com/xhload3d/p/9222549.html
      <https://www.cnblogs.com/xhload3d/p/9222549.html>?等其他文章。

        可操作

        當(dāng)然,HT 也汲取了訂閱-發(fā)布模式的天然優(yōu)勢,通過驅(qū)動數(shù)據(jù)更改視圖,更加直觀地感受到數(shù)據(jù)與視圖的綁定過程。以下提供2種 HT
      提供的可操作界面,第一種是通過創(chuàng)建面板組件, HT 內(nèi)部提供了包含 formPane 、borderPane、TablePane
      等一系列通用面板組件,此處我們以? formPane 為例,首先在 index.html 主頁面中引入 ht-form.js ,該文件封裝了 formPane
      面板的 api ,相關(guān)偽代碼如下:
      1 var fp = new ht.widget.FormPane(); //創(chuàng)建面板對象 2 fp.setWidth(200); 3
      fp.setHeight(100);  4 fp.setRowHeight(30); //面板行高 5 fp.setPadding(16);  6
      fp.getView().className ='main'; //節(jié)點設(shè)置類名后可以直接在 style 中設(shè)置屬性,說白了 fp.getView()
      就是一個普通的 DOM 節(jié)點 7 fp.addRow([{ //通過 addRow 方法添加文本以及進(jìn)度條等內(nèi)容 8 id:'text', 9
      element:'Current Speed === 20', 10 align:'center' 11 }],[0.1]); 12 fp.addRow([{
      13 id:'speed', 14 slider:{ //進(jìn)度條 15 min:0, 16 max:100, 17 value:20, //當(dāng)前進(jìn)度值 18
      step:1, 19 onValueChanged(){ value改變時觸發(fā)函數(shù) 20 var speed = fp.v('speed'); 21
      fp.v('text','Current Speed === ' + speed); 22 } 23 } 24 }],[0.1]); 25
      document.body.appendChild(fp.getView());


        此時,我們只要把之前定義的 speed 指向 fp.v('speed') ,就可以簡單地實現(xiàn)數(shù)據(jù)視圖綁定:
      1 function animation(fp){ 2 var lineJson = {}; 3 var name = ''; 4 var
      lastTime = Date.now(); 5 var speed; 6 for (var i = 1; i <= 9; i++ ) { 7 if
      (i != 8) { 8 name = 'line'+i; 9 lineJson[name] = 0; 10 } 11 } 12
      ht.Default.startAnim({13 duration: 5000, 14 action: function () { 15 speed =
      fp.v('speed'); 16 var time = Date.now(), 17 deltaTime = (time - lastTime) / 1000
      ;18 for (var tags in lineJson) { 19 if (tags.split('e')[1] % 2) { 20
      lineJson[tags] += deltaTime * speed; 21 } else { 22 lineJson[tags] -= deltaTime
      * speed; 23 } 24 var lines = dataModel.getDataByTag(tags); 25
      lines.setStyle('shape.dash.offset',lineJson[tags]); 26 } 27 lastTime = time; 28
      },29 finishFunc: function () { 30 animation(fp); 31 } 32 }) 33 }
      ?

        另一種是通過 HT 的矢量圖形庫,矢量圖形采用點、線或多邊形的圖形描述方式,解決了 png 、jpg
      等格式圖片在縮放過程中出現(xiàn)失真現(xiàn)象。創(chuàng)建矢量圖形可以通過常規(guī)編輯器如 webstorm、webstorm 通過代碼編寫,也可以通過 HT-2D
      編輯器直接創(chuàng)建圖形,基本上不需要操作代碼就可以簡單地創(chuàng)建出圖形,有學(xué)過 3dmax 或者 CAD
      制圖的同學(xué)對此應(yīng)該都不陌生。在編輯器的不斷完善下,內(nèi)部已經(jīng)有許多優(yōu)秀的圖標(biāo)和組件案例,這邊就可以直接引用一些小案例,首先需要創(chuàng)建一張圖紙,然后直接拉取一個自制圖標(biāo),類似
      legend 的效果都是繪線畫出來的,更改文字部分就可以直接看到效果了。



        關(guān)鍵的還是功能性組件,圖標(biāo)展示顯示界面,功能性組件支持事件的觸發(fā),首先在控件里面拉取 slider 圖標(biāo),然后到組件欄拉取 slider
      組件,設(shè)置控件的最大值、最小值和默認(rèn)值等一系列參數(shù)。



        可以得知我們即將改變的值有兩個,一個是 slider ,一個是文本的值,默認(rèn)20,我們給這兩個 Data 對象綁定唯一標(biāo)簽,分別為
      sliderValue 以及 textValue,先通過進(jìn)度條的當(dāng)前值改變文本的值:
      1 var sliderValue = dataModel.getDataByTag('sliderValue'); 2 var textValue =
      dataModel.getDataByTag('textValue'); 3 sliderValue.a('ht.onChange',function(){
      //value改變觸發(fā)事件4   textValue.a('textValue',sliderValue.a('ht.value')); 5 })
        然后animation拿到進(jìn)度條的當(dāng)前值,指向speed:
      1 function animation(data) { 2 var lineJson = {}; 3 var name = ''; 4 var
      lastTime = Date.now(); 5 var speed; 6 for (var i = 1; i <= 9; i++ ) { 7 if
      (i != 8) { 8 name = 'line'+i; 9 lineJson[name] = 0; 10 } 11 } 12
      ht.Default.startAnim({13 duration: 5000, 14 action: function () { 15 speed =
      data.a('ht.value'); 16 var time = Date.now(), 17 deltaTime = (time - lastTime)
      / 1000; 18 for (var tags in lineJson) { 19 if (tags.split('e')[1] % 2) { 20
      lineJson[tags] += deltaTime * speed; 21 } else { 22 lineJson[tags] -= deltaTime
      * speed; 23 } 24 var lines = dataModel.getDataByTag(tags); 25
      lines.setStyle('shape.dash.offset',lineJson[tags]); 26 } 27 lastTime = time; 28
      },29 finishFunc: function () { 30 animation(data); 31 } 32 }) 33 }
      ?



        當(dāng)然也可以自定義多個 slider 分別控制不同的動畫,具體如何實現(xiàn)還是全憑需求而定。

        

        不局限于 2D 可視化場景,與 3D 相關(guān)生產(chǎn)環(huán)境的可視化場景模擬也有許多案例,如下:

        3D水泥工廠工藝流程:http://www.hightopo.com/demo/CementFactory/
      <http://www.hightopo.com/demo/CementFactory/>

      ?

        3D高爐煉鐵工業(yè)流程:http://www.hightopo.com/demo/large-screen-puddling/
      <http://www.hightopo.com/demo/large-screen-puddling/>



      ?

      ?

      ?

      ?

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          伸进她的小内裤疯狂揉摸的视频 | 人人看人人做人人做人人 | 高清欧美性猛交XXXX黑人猛交 | 老师的玉臀吞吐着巨龙 | 久久久久久做 | 久久综合国产视频 | 性裸交AAAA片免费看中国影院 | av操逼网 | 欧美一级高潮片免费的 | AV天堂资源成人 |