天天看點

智能制造 3D 可視化之 CPU 仿真

科技改變生活,科技的發展帶來了生活方式的巨大改變。随着通信技術的不斷演進,5G 技術應運而生,随時随地萬物互聯的時代已經來臨。5G 技術不僅帶來了更快的連接配接速度和前所未有的使用者體驗,也為制造業,微電子及內建電路發展帶來了巨大的發展機遇和挑戰。5G 技術商業實施過程中,5G 網絡晶片面臨低功耗、低延時、高可靠性和高精度的技術挑戰。本文将以大家熟悉的 CPU 為例,介紹以 HT 為基礎,應用 JavaScript,WebGL 和 HTML5 技術開發的 CPU 監控系統。在大型資料中心,實時監控 CPU 的溫度,使用率等具有重要的意義。在伺服器級别進行 CPU 溫度監控,能夠實時了解伺服器 CPU 的溫度,及時發現能效問題,防止出現服務延遲、伺服器當機,進而節約成本。實時監控 CPU 使用率等,能夠實時檢視伺服器的 CPU 使用情況,合理配置設定伺服器資源。

系統預覽

PC 端

智能制造 3D 可視化之 CPU 仿真

移動端

智能制造 3D 可視化之 CPU 仿真

Demo 中的場景是由 2D 和 3D 結合搭建而成,移動端的左上資料框部分顯示的是手機陀螺儀資料,僅在移動端開啟陀螺儀時顯示。

功能實作

判斷頁面打開裝置

在移動網際網路時代,建設移動端和 PC 端網站具有同等重要的意義。與 PC 端相比,移動端能夠實作随時随地的浏覽,宣傳和移動營銷,是以 HT 設計和開發的系統都能很好地相容移動端的通路和展示。為了帶來更好的使用者體驗,Demo 使用 Navigator 對象的 userAgent 屬性,判斷使用者請求來自于 PC 端還是移動端,做不同的動畫處理和資料展示。Navigator 對象包含了浏覽器的資訊,其 userAgent 屬性則聲明了浏覽器用于 HTTP 請求的使用者代理頭的值。下面分别是在 Windows 端和 Android 端列印出的 userAgent 資訊。

智能制造 3D 可視化之 CPU 仿真
智能制造 3D 可視化之 CPU 仿真

對應到代碼中,基于 userAgent 屬性資訊,使用正規表達式去判斷請求是否來自于移動端(主要考慮了 Android 端 和 IOS 端)。

isMobile() {
    return (/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent));
}      

動畫原理

本 Demo 使用 HT 内置的 ht.Default.startAnim 函數來生成動畫,此函數支援 Frame-Based 和 Time-Based 兩種方式的動畫。我采用的是 Time-Based 方法,即使用者使用 duration 指定動畫周期 (機關為毫秒)。easing 參數是用于讓使用者定義函數,通過數學公式控制動畫,如勻速變化、先慢後快等效果。action 函數的第一個參數 v 代表通過 easing(t) 函數運算後的值, t代表目前動畫進行的進度 [0, 1],一般屬性變化根據 v 參數進行。finishFunc 參數代表動畫結束後的動作。本執行個體中的 startAnim 函數均采用了如下結構的 JSON 參數結構:

ht.Default.startAnim({
    duration: 500, // 動畫周期毫秒數
    easing: function (t) {}, // 動畫緩動函數
    action: function (v, t) {…} // 動畫過程屬性變化
    finishFunc: function () {} // 動畫結束後調用的函數
});      

旋轉 180 度并擡高視角

智能制造 3D 可視化之 CPU 仿真

3D 場景中的視角是由 eye (相機位置) 和 center (目标位置) 決定的,是以視角的變化改變這兩個參數即可,本 Demo 使用 HT 内置的 moveCamera 方法實作。動畫采用圓的參數方程計算 eye 的 x 值和 z 值,完成 180 度的旋轉。在旋轉過程中半徑和角度都随着 t 的變化而變化,通過 ( t – 0.5 ) * Math.PI 使得角度變化範圍為 [ - Math.PI / 2, Math.PI / 2] 。圓的參數方程如下所示:

智能制造 3D 可視化之 CPU 仿真

旋轉過程中,y 值也随 t 變化,完成 3D 場景視角的提升。finishFunc 參數用來定義該動畫結束後繼續調用的下一個動畫,實作多個動畫效果。

// 旋轉 180 度并擡高視角
startRotationAnimation(onFinish) {
    let that = this;
    let r = 849
    ht.Default.startAnim({
        duration: 6000,
        easing: function (t) { return t; },
        action: function (v, t) { // 圓的參數方程 半徑和角度都在變
            let r1 = (1 - t) * r;
            let angle = (t - 0.5) * Math.PI;
            let x = r1 * Math.cos(angle);
            let z = r1 * Math.sin(angle);
            let y = 126 + (1968 - 126) * t * t * t;
            that.g3d.moveCamera([x, y, z]);
        },
        finishFunc: function () {
            if (!onFinish) {
                return;
            }
            onFinish.call(that);
        }
    });
}      

在運作該動畫時,需要延時調用另外兩個動畫完成 CPU 卡扣的擡起及消失,這樣可使得動畫錯開執行,以達到更好的視覺效果。這部分使用 ht.Default.callLater(func, scope, args, delay) 延時調用動畫函數,最後一個參數 delay 定義延遲的時間間隔。

ht.Default.callLater(() => { this.startCap1Animation(); }, this, null, 500);
ht.Default.callLater(() => { this.startCap2Animation(); }, this, null, 1000);      

視角切換

本部分根據頁面在 PC 端還是手機端打開,使用 moveCamera 方法分别切換到不同視角。以 PC 端視角切換為例,通過 getEye() 方法擷取相機所在位置作為起始位置,終止位置為預定義的數值。通過 action 參數定義視角從起始位置到終點位置的切換。

// 視角切換
startMoveAngle3AnimationPC(onFinish) {
    let startPos = this.g3d.getEye();
    let endPos = [0, 728, 661];
    let that = this;
    ht.Default.startAnim({
        duration: 2000,
        easing: function (t) { return t * t; },
        action: function (v, t) {
            let x, y, z;
            x = startPos[0] + (endPos[0] - startPos[0]) * t;
            y = startPos[1] + (endPos[1] - startPos[1]) * t;
            z = startPos[2] + (endPos[2] - startPos[2]) * t;
            that.g3d.moveCamera([x, y, z]);
        },
        finishFunc: function () {…}
    });
}      

CPU 外殼隐藏動畫

智能制造 3D 可視化之 CPU 仿真

為帶來更好的視覺效果,視角切換的同時使用 ht.Default.callLater() 延遲調用 CPU 外殼隐藏動畫。通過 getElevation() 擷取外殼在 3D 坐标系中 y 的初始坐标,動畫過程中使用 setElevation() 方法設定 y 坐标,動畫結束後設定其可見屬性為 false。代碼如下:

easing: function (t) { return t * t; },
action: function (v, t) {
    let val = start + (end - start) * t; // start: 起始 y 坐标;end:終止 y 坐标
    that.hide1.setElevation(val);
}
finishFunc: function () {
    that.hide1.s('3d.visible', false);
}      

晶片冒出及呼吸燈渲染

智能制造 3D 可視化之 CPU 仿真

視角切換完成後,在 CPU 外殼隐藏的同時,CPU 内部結構逐漸冒出。與外殼隐藏相同,該部分也是通過setElevation方法完成。

action: function (v, t) {
    let e = start1Y + (end1Y - start1Y) * t
    that.up1.setElevation(e);
}      

與晶片冒出動畫間隔 1s, 呼吸燈渲染動畫開啟,使用 shape3d.blend 和 shape3d.opacity 分别設定呼吸燈染色和透明度。

easing: easing.easeBothStrong,
action: function (v, t) {
    let val = 255 - (255 - endBlend) * t;
    val = val.toFixed(0);
    let blend = 'rgb(' + val + ',' + val + ',' + val + ')';
    let opacity = startOpa + (endOpa - startOpa) * t
    that.blend.s('shape3d.blend', blend);
    that.opacity.s('shape3d.opacity', opacity);
}      

此部分動畫采用 easeBothStrong 方式,即開始慢且減速, t 的四次方,代碼實作如下:

easeBothStrong: function (t) {
    return (t *= 2) < 1 ?
        .5 * t * t * t * t :
        .5 * (2 - (t -= 2) * t * t * t);
}      

PC 端結束動畫

智能制造 3D 可視化之 CPU 仿真

當動畫結束後,PC 端重置 interactors,并啟動線的流動及點位地面的旋轉動畫。

startAnimation() {
    setInterval(() => {
        this.uvOffset = this.uvOffset + this.uvSpeed;
        this.line.s('top.uv.offset', [-this.uvOffset, 0]); // 線的流動
        this.rotationAngle = this.rotationSpeed + this.rotationAngle;
        this.flagReflection.setRotationY(this.rotationAngle); // 點位地面旋轉
    }, 16.7);
}      

移動端動畫結束後,會讀取手機陀螺儀資料并展示,具體原理及實作在手機傳感器資料部分。

手機傳感器資料

HTML5 提供了幾個 DOM 事件來獲得移動端方向及運動的資訊,deviceorientation 提供裝置的實體方向資訊;devicemotion 提供裝置的加速度資訊。

處理方向 (orientation) 事件

要接收裝置方向變化資訊,需要首先注冊監聽 deviceorientation 事件:

window.addEventListener('deviceorientation', (e) => {
    this.onOrientationEvent(e);
});      

orientation 事件中 3 個重要值:

屬性值   含義
DeviceOrientationEvent.alpha 裝置水準放置時,沿 z 軸的旋轉角度,範圍 [0,360] 。
DeviceOrientationEvent.beta 裝置水準放置時,沿 x 軸的旋轉角度,範圍 [-180, 180] 。
DeviceOrientationEvent.gamma 裝置水準放置時,沿 y 軸的旋轉角度,範圍 [-90, 90] 。

以下是事件處理的簡單代碼:

onOrientationEvent(e) {
    let alpha, beta, gamma, compass;
    let compassFlag = true;
    alpha = e.alpha ? e.alpha : 0;
    beta = e.beta ? e.beta : 0;
    gamma = e.gamma ? e.gamma : 0;
}      

值得注意的是, IOS 和 Android 對手機硬體提供的 alpha 值不完全一樣,是以需要借助 webkitCompassHeading 屬性來判斷是 IOS 還是 Android。當 webkitCompassHeading 不為空時,代表是 IOS 系統。

處理移動 (Motion) 事件

與方向事件處理類似,移動事件的處理也是首先注冊監聽 devicemotion:

window.addEventListener('devicemotion', (e) => {
    this.dataTextarea.s('2d.visible', true);
    this.onMotionEvent(e);


});      

移動事件包含 4 個屬性:

屬性值  含義
DeviceMotionEvent.acceleration 加速度,需要陀螺儀支援。
DeviceMotionEvent.accelerationIncludingGravity 重力加速度。
DeviceMotionEvent.rotationRate 旋轉速度。
DeviceMotionEvent.interval 從裝置擷取資料的頻率,機關為毫秒。

以下是事件的簡單代碼:

onMotionEvent(e) {
    let MAX1 = 2;
    let MAX2 = 5;


    this.acceleration = e.acceleration.x ? e.acceleration : {
        x: 0,
        y: 0,
        z: 0
    };
    this.accGravity = e.accelerationIncludingGravity.x ? e.accelerationIncludingGravity : {
        x: 0,
        y: 0,
        z: 0
    };
    this.rotationRate = e.rotationRate.alpha ? e.rotationRate : {
        alpha: 0,
        beta: 0,
        gamma: 0
    };
    this.interval = e.interval;


}      
總結