独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 智能视觉跑浆监测系统</title>
<style>
:root {
--bg-base: #050810;
--bg-panel: rgba(13, 17, 28, 0.85);
--grid-color: rgba(43, 76, 126, 0.15);
--ai-cyan: #00f3ff;
--ai-cyan-glow: rgba(0, 243, 255, 0.6);
--safe-green: #00ff66;
--danger-red: #ff3333;
--danger-orange: #ff9900;
--metal-dark: #1a202c;
--metal-light: #2d3748;
--text-main: #e2e8f0;
--text-muted: #718096;
--font-mono: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
--font-sans: system-ui, -apple-system, sans-serif;
}
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: var(--bg-base);
font-family: var(--font-sans);
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-main);
}
.container {
position: relative;
width: 100%;
height: 100%;
max-width: 1600px;
max-height: 900px;
display: flex;
justify-content: center;
align-items: center;
box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.8);
}
svg {
width: 100%;
height: 100%;
display: block;
}
/* Peripheral UI Elements - Strict placement rules applied */
.hud-panel {
position: absolute;
background: var(--bg-panel);
border: 1px solid rgba(0, 243, 255, 0.2);
border-radius: 4px;
padding: 12px;
font-size: 11px;
font-family: var(--font-mono);
color: var(--text-muted);
backdrop-filter: blur(4px);
z-index: 10;
pointer-events: none;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
}
.hud-panel::before {
content: '';
position: absolute;
top: 0; left: 0; width: 6px; height: 6px;
border-top: 1px solid var(--ai-cyan);
border-left: 1px solid var(--ai-cyan);
}
.hud-panel::after {
content: '';
position: absolute;
bottom: 0; right: 0; width: 6px; height: 6px;
border-bottom: 1px solid var(--ai-cyan);
border-right: 1px solid var(--ai-cyan);
}
.hud-title {
color: var(--ai-cyan);
font-size: 13px;
font-weight: bold;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 1px;
}
.hud-top-left { top: 20px; left: 20px; width: 220px; }
.hud-top-right { top: 20px; right: 20px; width: 240px; }
.hud-bottom-left { bottom: 20px; left: 20px; width: 260px; }
.hud-bottom-right { bottom: 20px; right: 20px; width: 220px; }
.data-row {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
border-bottom: 1px solid rgba(255,255,255,0.05);
padding-bottom: 2px;
}
.data-label { color: var(--text-muted); }
.data-value { color: var(--text-main); font-weight: bold; }
.val-cyan { color: var(--ai-cyan); }
.val-green { color: var(--safe-green); }
.val-red { color: var(--danger-red); }
.log-container {
height: 80px;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.log-entry { margin-bottom: 2px; opacity: 0.8; }
.log-time { color: var(--text-muted); margin-right: 6px; }
/* SVG Animations */
@keyframes scan-sweep {
0% { transform: translateY(0) scaleY(1); opacity: 0.8; }
50% { transform: translateY(180px) scaleY(0.2); opacity: 0.3; }
100% { transform: translateY(0) scaleY(1); opacity: 0.8; }
}
.anim-scan {
transform-origin: 600px 220px;
animation: scan-sweep 3s ease-in-out infinite;
}
@keyframes flow-move {
0% { stroke-dashoffset: 100; }
100% { stroke-dashoffset: 0; }
}
.anim-flow {
stroke-dasharray: 10 5;
animation: flow-move 1.5s linear infinite;
}
@keyframes pulse-ring {
0% { transform: scale(0.8); opacity: 0.8; }
100% { transform: scale(2); opacity: 0; }
}
@keyframes data-stream {
0% { stroke-dashoffset: 50; }
100% { stroke-dashoffset: 0; }
}
.anim-data {
stroke-dasharray: 4 6;
animation: data-stream 0.8s linear infinite;
}
@keyframes box-flash {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
.anim-flash {
animation: box-flash 0.5s ease-in-out infinite;
}
@keyframes float-foam {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-3px); }
}
</style>
</head>
<body>
<div class="container">
<!-- Overlay UI Panels (Strictly constrained to corners) -->
<div class="hud-panel hud-top-left">
<div class="hud-title">System Status</div>
<div class="data-row"><span class="data-label">MODE</span><span class="data-value val-cyan">AUTO_INFER</span></div>
<div class="data-row"><span class="data-label">CAMERA_FPS</span><span class="data-value">60.00</span></div>
<div class="data-row"><span class="data-label">RESOLUTION</span><span class="data-value">1920x1080</span></div>
<div class="data-row"><span class="data-label">ILLUMINATION</span><span class="data-value">ADAPTIVE_ON</span></div>
</div>
<div class="hud-panel hud-top-right">
<div class="hud-title">AI Edge Compute</div>
<div class="data-row"><span class="data-label">MODEL</span><span class="data-value">DeepSeg_v4.2</span></div>
<div class="data-row"><span class="data-label">INFERENCE_MS</span><span class="data-value val-green" id="infer-time">12.4ms</span></div>
<div class="data-row"><span class="data-label">CONFIDENCE</span><span class="data-value val-cyan" id="avg-conf">0.96</span></div>
<div class="data-row"><span class="data-label">RUN_OFF_PROB</span><span class="data-value" id="danger-prob">0.02</span></div>
</div>
<div class="hud-panel hud-bottom-left">
<div class="hud-title">Semantic Analysis Log</div>
<div class="log-container" id="terminal-log">
<!-- Logs injected via JS -->
</div>
</div>
<div class="hud-panel hud-bottom-right">
<div class="hud-title">PLC Control Output</div>
<div class="data-row"><span class="data-label">CONN_STATE</span><span class="data-value val-green">ESTABLISHED</span></div>
<div class="data-row"><span class="data-label">SHAKER_FREQ</span><span class="data-value" id="plc-freq">45 Hz</span></div>
<div class="data-row"><span class="data-label">SCREEN_ANGLE</span><span class="data-value" id="plc-angle">2.5°</span></div>
<div class="data-row"><span class="data-label">LATEST_CMD</span><span class="data-value val-cyan" id="plc-cmd">KEEP_NORMAL</span></div>
</div>
<!-- Main Animation Area -->
<svg viewBox="0 0 1200 800" preserveAspectRatio="xMidYMid meet" id="main-svg">
<defs>
<!-- Background Grid -->
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="var(--grid-color)" stroke-width="0.5"/>
<circle cx="40" cy="40" r="1" fill="var(--grid-color)"/>
</pattern>
<!-- Filters for Neon Glow -->
<filter id="glow-cyan" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="5" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<filter id="glow-red" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="8" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<filter id="glow-green" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="4" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<!-- Gradients -->
<linearGradient id="cone-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="var(--ai-cyan)" stop-opacity="0.4" />
<stop offset="100%" stop-color="var(--ai-cyan)" stop-opacity="0.05" />
</linearGradient>
<linearGradient id="slurry-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#3d4956" />
<stop offset="50%" stop-color="#2d3748" />
<stop offset="100%" stop-color="#1a202c" />
</linearGradient>
<!-- Screen Mesh Pattern -->
<pattern id="mesh" width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(15)">
<path d="M 8 0 L 0 0 0 8" fill="none" stroke="#4a5568" stroke-width="0.5"/>
</pattern>
</defs>
<!-- 1. Background Layer -->
<rect width="100%" height="100%" fill="url(#grid)" />
<!-- Contextual Technical Lines -->
<path d="M0,400 L1200,400 M600,0 L600,800" stroke="var(--grid-color)" stroke-width="1" stroke-dasharray="2 4"/>
<circle cx="600" cy="400" r="300" fill="none" stroke="var(--grid-color)" stroke-width="0.5" />
<!-- 2. Infrastructure Layer (Shaker & Hardware) -->
<g id="hardware">
<!-- PLC Node (Left) -->
<g transform="translate(150, 550)">
<rect x="-60" y="-80" width="120" height="160" fill="var(--metal-dark)" stroke="#4a5568" stroke-width="2" rx="4"/>
<rect x="-50" y="-70" width="100" height="30" fill="#000" />
<text x="0" y="-50" font-family="var(--font-mono)" font-size="12" fill="var(--safe-green)" text-anchor="middle">PLC_NODE</text>
<!-- Indicators -->
<circle cx="-40" cy="-20" r="4" fill="var(--safe-green)" id="plc-led-1" filter="url(#glow-green)"/>
<circle cx="-20" cy="-20" r="4" fill="var(--ai-cyan)" id="plc-led-2" />
<circle cx="0" cy="-20" r="4" fill="#333" id="plc-led-3" />
<!-- Data Link to Shaker -->
<path d="M60,0 L180,0 L200,50" fill="none" stroke="#4a5568" stroke-width="2" />
<path d="M60,0 L180,0 L200,50" fill="none" stroke="var(--ai-cyan)" stroke-width="2" class="anim-data" id="link-plc-shaker" opacity="0.3"/>
</g>
<!-- Edge AI Box (Right) -->
<g transform="translate(1050, 300)">
<rect x="-70" y="-50" width="140" height="100" fill="var(--metal-dark)" stroke="var(--ai-cyan)" stroke-width="2" rx="4"/>
<rect x="-60" y="-40" width="120" height="80" fill="#000" />
<text x="0" y="-20" font-family="var(--font-mono)" font-size="12" fill="var(--ai-cyan)" text-anchor="middle" font-weight="bold">AI EDGE CORE</text>
<path d="M-40,10 L40,10 M-40,20 L20,20" stroke="var(--ai-cyan)" stroke-width="2" opacity="0.5"/>
<circle cx="45" cy="20" r="3" fill="var(--safe-green)" filter="url(#glow-green)">
<animate attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite"/>
</circle>
<!-- Data Link to PLC -->
<path d="M-70,0 L-750,0 L-850,200 L-900,200" fill="none" stroke="#4a5568" stroke-width="1" stroke-dasharray="4 4"/>
<path d="M-70,0 L-750,0 L-850,200 L-900,200" fill="none" stroke="var(--safe-green)" stroke-width="2" class="anim-data" id="link-ai-plc" opacity="0"/>
</g>
<!-- Shaker Screen Assembly (Center, 2.5D projection) -->
<g transform="translate(600, 500)">
<!-- Base frame -->
<polygon points="-250,150 250,150 280,100 -220,100" fill="var(--metal-dark)" stroke="#333" stroke-width="2"/>
<!-- Springs -->
<path d="M-200,125 Q-210,135 -200,145 Q-190,135 -200,125" fill="none" stroke="var(--metal-light)" stroke-width="4"/>
<path d="M200,125 Q190,135 200,145 Q210,135 200,125" fill="none" stroke="var(--metal-light)" stroke-width="4"/>
<!-- Screen Mesh Surface (Angled) -->
<polygon points="-200,100 200,100 280,-40 -120,-40" fill="url(#mesh)" stroke="#4a5568" stroke-width="2"/>
<polygon points="-200,100 200,100 280,-40 -120,-40" fill="rgba(0,0,0,0.4)"/> <!-- Depth shadow -->
</g>
</g>
<!-- 3. Dynamic Material Layer (Slurry & Foam) -->
<g transform="translate(600, 500)" id="material-group">
<!-- Base slurry flow -->
<path d="M-100,-30 C-40,-20 100,-35 200,0 C230,15 250,60 210,80 C100,100 -100,80 -180,60 C-200,40 -180,-10 -100,-30 Z" fill="url(#slurry-grad)" opacity="0.9"/>
<!-- Flow animation lines to simulate movement -->
<path d="M-80,-20 Q50,-10 180,20" fill="none" stroke="#4a5568" stroke-width="2" class="anim-flow"/>
<path d="M-140,40 Q0,50 160,70" fill="none" stroke="#4a5568" stroke-width="2" class="anim-flow" style="animation-duration: 2s;"/>
<!-- Foam clusters (Normal & Dangerous) -->
<!-- Normal Foam -->
<g id="foam-normal">
<circle cx="-50" cy="10" r="15" fill="#a0aec0" opacity="0.6"/>
<circle cx="-30" cy="5" r="20" fill="#a0aec0" opacity="0.7"/>
<circle cx="-60" cy="25" r="12" fill="#a0aec0" opacity="0.5"/>
<circle cx="50" cy="40" r="18" fill="#a0aec0" opacity="0.6"/>
<circle cx="70" cy="35" r="14" fill="#a0aec0" opacity="0.8"/>
</g>
<!-- Dangerous Foam (Hidden initially, shown by JS) -->
<g id="foam-danger" opacity="0">
<circle cx="120" cy="10" r="25" fill="#f6ad55" opacity="0.8">
<animate attributeName="r" values="25;28;25" dur="1s" repeatCount="indefinite"/>
</circle>
<circle cx="150" cy="25" r="30" fill="#f6ad55" opacity="0.9">
<animate attributeName="r" values="30;35;30" dur="0.8s" repeatCount="indefinite"/>
</circle>
<circle cx="100" cy="30" r="18" fill="#f6ad55" opacity="0.7"/>
<!-- Overflow simulation -->
<path d="M160,50 Q180,80 200,100" fill="none" stroke="#f6ad55" stroke-width="4" opacity="0.8"/>
</g>
</g>
<!-- 4. Top-Down Vision System (Camera & AI Scan) -->
<g id="vision-system">
<!-- Camera Body -->
<g transform="translate(600, 100)">
<rect x="-25" y="-40" width="50" height="60" fill="var(--metal-dark)" stroke="var(--ai-cyan)" stroke-width="1" rx="5"/>
<rect x="-15" y="-30" width="30" height="40" fill="#000" rx="3"/>
<!-- Lens -->
<circle cx="0" cy="20" r="15" fill="var(--metal-light)" stroke="#111" stroke-width="2"/>
<circle cx="0" cy="20" r="10" fill="#000"/>
<circle cx="0" cy="20" r="4" fill="var(--ai-cyan)" filter="url(#glow-cyan)"/>
<!-- Mount -->
<path d="M0,-40 L0,-100 L200,-100" fill="none" stroke="var(--metal-light)" stroke-width="10" stroke-linejoin="round"/>
<!-- Text Label -->
<text x="35" y="0" font-family="var(--font-mono)" font-size="10" fill="var(--ai-cyan)">EXP-CAM_01</text>
<text x="35" y="12" font-family="var(--font-mono)" font-size="8" fill="var(--text-muted)">60FPS/1080P</text>
<!-- Data link to AI -->
<path d="M0,-100 L450,-100 L450,200" fill="none" stroke="#4a5568" stroke-width="1" stroke-dasharray="4 4"/>
<path d="M0,-100 L450,-100 L450,200" fill="none" stroke="var(--ai-cyan)" stroke-width="2" class="anim-data"/>
</g>
<!-- Vision Cone & Scanning Effect -->
<g id="scan-area">
<polygon points="600,135 380,560 820,560" fill="url(#cone-gradient)" />
<!-- Moving scan line -->
<path d="M 400,380 L 800,380" stroke="var(--ai-cyan)" stroke-width="3" filter="url(#glow-cyan)" class="anim-scan"/>
</g>
</g>
<!-- 5. AI Semantic Segmentation Overlays (Controlled by JS) -->
<!-- The TRIZ final ideal result: Direct identification without complex mechanical sensors -->
<g id="ai-overlays" transform="translate(600, 500)">
<!-- Bounding Box 1: Normal Slurry Area -->
<g id="bbox-normal" opacity="0.8">
<rect x="-180" y="-20" width="120" height="90" fill="none" stroke="var(--safe-green)" stroke-width="1.5" stroke-dasharray="4 4" rx="2"/>
<rect x="-180" y="-36" width="90" height="16" fill="rgba(0, 255, 102, 0.2)" stroke="var(--safe-green)" stroke-width="1"/>
<text x="-176" y="-24" font-family="var(--font-mono)" font-size="10" fill="var(--safe-green)">SLURRY: 0.98</text>
<!-- Target crosshair -->
<path d="M-120,25 L-120,15 M-120,35 L-120,45 M-130,25 L-140,25 M-110,25 L-100,25" stroke="var(--safe-green)" stroke-width="1" opacity="0.5"/>
</g>
<!-- Bounding Box 2: Normal Foam -->
<g id="bbox-foam" opacity="0.8">
<polygon points="-80,0 -20,-10 80,40 -20,60" fill="none" stroke="var(--ai-cyan)" stroke-width="1.5" stroke-linejoin="round"/>
<text x="-15" y="-15" font-family="var(--font-mono)" font-size="10" fill="var(--ai-cyan)">FOAM_NORM: 0.92</text>
<!-- Semantic mask points -->
<circle cx="-50" cy="10" r="1.5" fill="var(--ai-cyan)"/>
<circle cx="-30" cy="5" r="1.5" fill="var(--ai-cyan)"/>
<circle cx="50" cy="40" r="1.5" fill="var(--ai-cyan)"/>
</g>
<!-- Bounding Box 3: Dangerous Foam / Run-off (Initially hidden) -->
<g id="bbox-danger" opacity="0">
<rect x="80" y="-10" width="110" height="80" fill="rgba(255, 51, 51, 0.1)" stroke="var(--danger-red)" stroke-width="2" rx="4" filter="url(#glow-red)" class="anim-flash"/>
<rect x="80" y="-28" width="110" height="18" fill="var(--danger-red)"/>
<text x="84" y="-15" font-family="var(--font-mono)" font-size="11" fill="#fff" font-weight="bold">! RUN_OFF_RISK</text>
<text x="84" y="60" font-family="var(--font-mono)" font-size="10" fill="var(--danger-red)">CONF: 0.99</text>
<text x="84" y="75" font-family="var(--font-mono)" font-size="10" fill="var(--danger-red)">VOL: +45%</text>
<!-- Crosshair tracking danger -->
<circle cx="135" cy="20" r="8" fill="none" stroke="var(--danger-red)" stroke-width="1"/>
<circle cx="135" cy="20" r="2" fill="var(--danger-red)"/>
</g>
<!-- Cross Validation Line (Virtual Level Gauge integration) -->
<g id="cross-validation" opacity="0.6">
<path d="M-220,10 L250,10" stroke="var(--ai-cyan)" stroke-width="0.5" stroke-dasharray="2 4"/>
<text x="255" y="13" font-family="var(--font-mono)" font-size="8" fill="var(--ai-cyan)">LVL_BASE</text>
<path d="M-220,50 L250,50" stroke="var(--danger-red)" stroke-width="0.5" stroke-dasharray="2 4"/>
<text x="255" y="53" font-family="var(--font-mono)" font-size="8" fill="var(--danger-red)">LVL_CRIT</text>
</g>
</g>
</svg>
</div>
<!-- Core Simulation Logic -->
<script>
document.addEventListener('DOMContentLoaded', () => {
// DOM Elements
const bboxDanger = document.getElementById('bbox-danger');
const foamDanger = document.getElementById('foam-danger');
const bboxFoam = document.getElementById('bbox-foam');
const linkAiPlc = document.getElementById('link-ai-plc');
const linkPlcShaker = document.getElementById('link-plc-shaker');
// HUD Elements
const dangerProbText = document.getElementById('danger-prob');
const avgConfText = document.getElementById('avg-conf');
const inferTimeText = document.getElementById('infer-time');
const plcCmdText = document.getElementById('plc-cmd');
const plcFreqText = document.getElementById('plc-freq');
const plcLed3 = document.getElementById('plc-led-3');
const terminalLog = document.getElementById('terminal-log');
// Utilities
const getTimestamp = () => {
const now = new Date();
return `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}:${now.getSeconds().toString().padStart(2,'0')}.${now.getMilliseconds().toString().padStart(3,'0')}`;
};
const addLog = (msg, isDanger = false) => {
const p = document.createElement('div');
p.className = 'log-entry';
const color = isDanger ? 'var(--danger-red)' : 'var(--text-main)';
p.innerHTML = `<span class="log-time">[${getTimestamp()}]</span> <span style="color:${color}">${msg}</span>`;
terminalLog.appendChild(p);
if (terminalLog.children.length > 5) {
terminalLog.removeChild(terminalLog.firstChild);
}
};
// Simulation State Machine
// TRIZ Focus: Displaying the transition from ideal normal state to automatic detection of anomaly
// without physical contact sensors.
let phase = 0;
const runSimulationCycle = () => {
// Randomize minor inference fluctuations to look alive
inferTimeText.innerText = (12.0 + Math.random() * 1.5).toFixed(1) + 'ms';
if (phase === 0) {
// Normal Operation Phase
bboxDanger.setAttribute('opacity', '0');
foamDanger.setAttribute('opacity', '0');
bboxFoam.setAttribute('opacity', '0.8');
linkAiPlc.setAttribute('opacity', '0');
linkPlcShaker.setAttribute('stroke', 'var(--ai-cyan)');
dangerProbText.innerText = '0.0' + Math.floor(Math.random() * 5);
dangerProbText.className = 'data-value';
avgConfText.innerText = '0.9' + (4 + Math.floor(Math.random() * 5));
plcCmdText.innerText = 'KEEP_NORMAL';
plcCmdText.className = 'data-value val-cyan';
plcFreqText.innerText = '45 Hz';
plcLed3.setAttribute('fill', '#333');
plcLed3.removeAttribute('filter');
if(Math.random() > 0.6) addLog('Frame infer: Slurry OK, Foam Norm.');
setTimeout(() => { phase = 1; }, 3000); // Stay normal for 3s
}
else if (phase === 1) {
// Anomaly Emerging Phase (Pao Jiang starting)
addLog('WARN: Foam volume increasing...', true);
foamDanger.setAttribute('opacity', '0.5'); // Start showing physical danger
dangerProbText.innerText = '0.45';
dangerProbText.className = 'data-value val-orange';
setTimeout(() => { phase = 2; }, 1500); // 1.5s build up
}
else if (phase === 2) {
// AI Detection & Alert Phase (The Innovation Point)
// High-speed semantic segmentation catches it instantly
addLog('CRITICAL: Run-off (Pao Jiang) detected!', true);
addLog('Semantic Mask conf: 0.99', true);
foamDanger.setAttribute('opacity', '1');
bboxDanger.setAttribute('opacity', '1'); // Red box appears
bboxFoam.setAttribute('opacity', '0.3'); // Dim normal box
dangerProbText.innerText = '0.99';
dangerProbText.className = 'data-value val-red';
// Trigger data flow to PLC
linkAiPlc.setAttribute('opacity', '1');
linkAiPlc.setAttribute('stroke', 'var(--danger-red)');
setTimeout(() => { phase = 3; }, 1500);
}
else if (phase === 3) {
// PLC Action Phase
addLog('Action: Sending control signal to PLC', false);
plcCmdText.innerText = 'REDUCE_FREQ';
plcCmdText.className = 'data-value val-red';
plcFreqText.innerText = '35 Hz';
plcLed3.setAttribute('fill', 'var(--danger-red)');
plcLed3.setAttribute('filter', 'url(#glow-red)');
linkPlcShaker.setAttribute('stroke', 'var(--danger-red)');
setTimeout(() => { phase = 4; }, 2000); // PLC acts for 2s
}
else if (phase === 4) {
// Resolution Phase (Returning to ideal state)
addLog('Status resolving. Foam level nominal.');
foamDanger.setAttribute('opacity', '0.2');
bboxDanger.setAttribute('opacity', '0');
linkAiPlc.setAttribute('opacity', '0');
setTimeout(() => { phase = 0; }, 1000); // Restart loop
}
// Continuous loop
setTimeout(runSimulationCycle, 100);
};
// Initial logs
addLog('[SYSTEM] Booting AI Core...');
addLog('[CAMERA] Exp-Cam 01 Stream Active');
addLog('[MODEL] DeepSeg_v4.2 Loaded');
// Start simulation loop after a slight delay
setTimeout(runSimulationCycle, 1000);
});
</script>
</body>
</html>
积分规则:每轮对话扣10分
等待动画代码生成...
