Initial commit: workspace configuration and src
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FORI AGV Control Dashboard</title>
|
||||
<!-- Outfit Google Font -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<!-- ROSlibJS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/roslib@1/build/roslib.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<!-- Header -->
|
||||
<header class="dashboard-header">
|
||||
<div class="logo-area">
|
||||
<h1>FORI <span>AGV</span></h1>
|
||||
<span class="system-status">BLDC & ArUco Parking System</span>
|
||||
</div>
|
||||
<div class="connection-status" id="conn-status">
|
||||
<span id="env-badge" class="env-badge sim">Simulation Mode</span>
|
||||
<span class="pulse-indicator red" id="status-indicator"></span>
|
||||
<span id="status-text">Disconnected</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Dashboard Grid -->
|
||||
<main class="dashboard-grid">
|
||||
|
||||
<!-- Left Side: Map & Configuration -->
|
||||
<section class="grid-card map-card">
|
||||
<div class="card-header">
|
||||
<h2>🗺️ 실시간 2D 맵 시각화</h2>
|
||||
<span class="help-text">지도를 클릭하여 주차 진입점(Waypoint)을 등록하세요.</span>
|
||||
</div>
|
||||
<div class="canvas-container">
|
||||
<canvas id="map-canvas"></canvas>
|
||||
</div>
|
||||
<div class="config-panel">
|
||||
<h3>📍 주차 진입점 (Waypoint) 설정</h3>
|
||||
<div class="coord-inputs">
|
||||
<div class="input-group">
|
||||
<label>X (m)</label>
|
||||
<input type="number" id="wp-x" step="0.1" value="0.0">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>Y (m)</label>
|
||||
<input type="number" id="wp-y" step="0.1" value="0.0">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>Yaw (deg)</label>
|
||||
<input type="number" id="wp-yaw" step="1" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" id="btn-set-wp">진입점 좌표 전송</button>
|
||||
</div>
|
||||
<div class="pose-panel">
|
||||
<h3>📍 로봇 실시간 현재 위치 (Pose)</h3>
|
||||
<div class="pose-value-display" id="val-pose">
|
||||
X: 0.00m | Y: 0.00m | Yaw: 0°
|
||||
</div>
|
||||
</div>
|
||||
<div class="battery-panel" style="margin-top: 15px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); padding: 15px; border-radius: 12px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<h3 style="margin: 0; font-size: 1rem; color: var(--text-heading, #fff);">🔋 FORI 배터리 잔량 (24V 60Ah LiFePO4)</h3>
|
||||
<span id="battery-badge" class="badge badge-normal" style="background: rgba(34, 197, 94, 0.2); color: #4ade80; border: 1px solid rgba(74, 222, 128, 0.4); padding: 4px 10px; border-radius: 20px; font-size: 0.85rem; font-weight: 600;">--% (--.-V)</span>
|
||||
</div>
|
||||
<div style="width: 100%; background: rgba(255,255,255,0.08); height: 12px; border-radius: 6px; margin-top: 10px; overflow: hidden; border: 1px solid rgba(255,255,255,0.1);">
|
||||
<div id="battery-bar" style="width: 0%; height: 100%; background: linear-gradient(90deg, #22c55e, #4ade80); transition: width 0.5s ease, background 0.5s ease; border-radius: 6px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Right Side: Camera View & Telemetry -->
|
||||
<div class="right-column">
|
||||
|
||||
<!-- Camera & ArUco view -->
|
||||
<section class="grid-card camera-card">
|
||||
<div class="card-header">
|
||||
<h2>📷 실시간 아루코 인식 카메라</h2>
|
||||
</div>
|
||||
<div class="camera-container-layout">
|
||||
<div class="camera-stream-container">
|
||||
<img id="camera-stream" src="" alt="카메라 스트림 대기 중..." />
|
||||
</div>
|
||||
<div class="aruco-info-panel">
|
||||
<div class="aruco-status-badge disconnected" id="aruco-status">미인식 (No Marker)</div>
|
||||
<div class="aruco-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">마커 ID</span>
|
||||
<span class="detail-value" id="aruco-id">-</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Z (직선 거리)</span>
|
||||
<span class="detail-value" id="aruco-z">-</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">X (가로 오프셋)</span>
|
||||
<span class="detail-value" id="aruco-x">-</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Y (높이 오프셋)</span>
|
||||
<span class="detail-value" id="aruco-y">-</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Yaw (좌우 회전)</span>
|
||||
<span class="detail-value" id="aruco-yaw">-</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Roll / Pitch</span>
|
||||
<span class="detail-value" id="aruco-rp">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Mode Controls & Telemetry -->
|
||||
<section class="grid-card controls-card">
|
||||
<div class="card-header">
|
||||
<h2>⚙️ 제어 모드 및 텔레메트리</h2>
|
||||
</div>
|
||||
|
||||
<!-- Mode Switch Buttons -->
|
||||
<div class="mode-selector">
|
||||
<button class="btn btn-primary active" id="btn-mode-nav2">자율 주행 (Nav2)</button>
|
||||
<button class="btn btn-primary" id="btn-mode-patrol">자동 순찰 (Patrol)</button>
|
||||
<button class="btn btn-primary" id="btn-mode-parking">자동 주차 (Parking)</button>
|
||||
</div>
|
||||
<button class="btn btn-secondary" id="btn-pose-estimate" style="margin-bottom: 12px; font-size: 13px; font-weight: 700; width: 100%;">
|
||||
📍 로봇 위치 초기화 (Pose Estimate)
|
||||
</button>
|
||||
<button class="btn btn-danger" id="btn-emergency-stop" style="margin-bottom: 20px; font-size: 14px; font-weight: 800; width: 100%;">
|
||||
🛑 긴급 정지 (Emergency Stop)
|
||||
</button>
|
||||
|
||||
<!-- Telemetry Metrics Grid -->
|
||||
<div class="telemetry-grid">
|
||||
<div class="metric-box">
|
||||
<span class="metric-label">현재 시스템 상태</span>
|
||||
<span class="metric-value" id="val-state">IDLE</span>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<span class="metric-label">로봇 선속도 (Linear)</span>
|
||||
<span class="metric-value" id="val-linear">0.00 m/s</span>
|
||||
</div>
|
||||
<div class="metric-box">
|
||||
<span class="metric-label">로봇 각속도 (Angular)</span>
|
||||
<span class="metric-value" id="val-angular">0.00 rad/s</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Wheel Speeds Gauge -->
|
||||
<div class="rpm-panel">
|
||||
<h3>🔄 실시간 바퀴 회전수 (Feedback RPM)</h3>
|
||||
<div class="rpm-bars">
|
||||
<div class="rpm-bar-group">
|
||||
<span class="wheel-name">Front Left</span>
|
||||
<div class="bar-container">
|
||||
<div class="bar" id="bar-fl" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="rpm-val" id="val-fl">0 RPM</span>
|
||||
</div>
|
||||
<div class="rpm-bar-group">
|
||||
<span class="wheel-name">Front Right</span>
|
||||
<div class="bar-container">
|
||||
<div class="bar" id="bar-fr" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="rpm-val" id="val-fr">0 RPM</span>
|
||||
</div>
|
||||
<div class="rpm-bar-group">
|
||||
<span class="wheel-name">Rear Left</span>
|
||||
<div class="bar-container">
|
||||
<div class="bar" id="bar-rl" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="rpm-val" id="val-rl">0 RPM</span>
|
||||
</div>
|
||||
<div class="rpm-bar-group">
|
||||
<span class="wheel-name">Rear Right</span>
|
||||
<div class="bar-container">
|
||||
<div class="bar" id="bar-rr" style="width: 0%"></div>
|
||||
</div>
|
||||
<span class="rpm-val" id="val-rr">0 RPM</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user