From 6a5fce819fb505af54dce8d77c40eb1fc662c7d8 Mon Sep 17 00:00:00 2001 From: ywb <347742090@qq.com> Date: Sun, 17 May 2026 09:24:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20map=20rotation=20with=20overlay=20fix?= =?UTF-8?q?=20=E2=80=94=20rotate=20only=20img,=20keep=20overlay=20with=20p?= =?UTF-8?q?oints=20+=20nav=20click?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agv_app/setting.html | 26 +++++++++++++----------- agv_app/setting.js | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/agv_app/setting.html b/agv_app/setting.html index 0bdd838..0e19716 100644 --- a/agv_app/setting.html +++ b/agv_app/setting.html @@ -53,21 +53,23 @@ 旋转: - +
- -
- - -
- -
-
+ +
+ +
+
+ +
diff --git a/agv_app/setting.js b/agv_app/setting.js index 6908f49..e20f9de 100644 --- a/agv_app/setting.js +++ b/agv_app/setting.js @@ -17,6 +17,9 @@ createApp({ mapImageUrl: '', mapMeta: null, mapRotation: 0, + mapVersion: 0, + navCurrentPos: null, + nav2Available: false, // 点位 points: [], newPointName: '', @@ -47,6 +50,7 @@ createApp({ mounted() { this.refresh() this.refreshAngles() + this.nav2Timer = setInterval(this.refreshNavStatus, 3000) }, watch: { tab(val) { @@ -65,6 +69,7 @@ createApp({ beforeUnmount() { Object.values(this.jogIntervals).forEach(i => clearInterval(i)) if (this.agvCameraTimer) clearInterval(this.agvCameraTimer) + if (this.nav2Timer) clearInterval(this.nav2Timer) }, methods: { async refresh() { @@ -114,6 +119,48 @@ createApp({ rotateMap(deg) { this.mapRotation = (this.mapRotation + deg) % 360 }, + resetMapView() { + this.mapRotation = 0 + this.mapVersion++ + }, + async refreshNavStatus() { + try { + const res = await fetch(API + '/api/navigate/status') + if (res.ok) { + const data = await res.json() + this.nav2Available = data.nav2_available + if (data.current_pos) { + this.navCurrentPos = data.current_pos + } + } + } catch (e) {} + }, + async onMapClick(e) { + if (!this.mapMeta || !this.agvConnected) return + const rect = e.target.getBoundingClientRect() + const px = (e.clientX - rect.left) / rect.width + const py = (e.clientY - rect.top) / rect.height + const { resolution, origin } = this.mapMeta + const wx = origin[0] + px * resolution * this.mapMeta.width + const wy = origin[1] + (1 - py) * resolution * this.mapMeta.height + try { + const res = await fetch(API + '/api/navigate/to', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ x: wx, y: wy }) + }) + const data = await res.json() + if (data.ok) { + this.mapMsg = '✅ 导航目标已发送' + this.mapVersion++ + } else { + this.mapMsg = '❌ ' + (data.error || '导航失败') + } + } catch (e) { + this.mapMsg = '❌ 导航请求失败' + } + setTimeout(() => { this.mapMsg = '' }, 3000) + }, getMapX(coords) { if (!coords || !this.mapMeta) return 50 const [x, y, yaw] = coords