From 2f4265c4387bf23b34ed31728058516731a103b1 Mon Sep 17 00:00:00 2001 From: rxf Date: Wed, 24 Sep 2025 12:17:32 +0200 Subject: [PATCH] =?UTF-8?q?Telekop=20r=C3=BCckw=C3=A4rts:=20Kuppel=20f?= =?UTF-8?q?=C3=A4ngt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- JS/public/dome.js | 129 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 21 deletions(-) diff --git a/JS/public/dome.js b/JS/public/dome.js index e71817c..5770637 100644 --- a/JS/public/dome.js +++ b/JS/public/dome.js @@ -6,11 +6,21 @@ class Dome { window.activeDomeInstance.stop(); } - this.angle = 0; // Grad (Mitte des Spalts) + this.angle = 0; // Grad (Mitte des Spalts) - immer auf NFC-Tag-Position! this.slotWidth = 20; // Spaltbreite in Grad - this.domeSpeed = 3.0; // Grad pro Frame (für smoothe animation) + this.domeSpeed = 0.5; // Grad pro Frame (für sehr smoothe animation) this.telescopeAngle = 0; + // NFC-Tag System (wie in Original) + this.tagCount = 36; // 36 Tags = alle 10° + this.tagStep = 360 / this.tagCount; // 10° pro Tag + this.currentTagIndex = 0; // Aktueller Tag (0-35) + this.targetTagIndex = 0; // Ziel-Tag während Bewegung + + // Setze initiale Position auf Tag 0 + this.angle = this.tagToAngle(this.currentTagIndex); // 5° (Mitte von Tag 0) + this.targetDomeAngle = this.angle; + // State Machine für diskrete Bewegung (wie Original) this.state = "IDLE"; // "IDLE" oder "MOVING" this.targetDomeAngle = this.angle; @@ -50,6 +60,43 @@ class Dome { }, 100); // 10x pro Sekunde } + // NFC-Tag Hilfsfunktionen (wie im Original script.js) + getTagIndex(angle) { + return Math.floor(((angle % 360) + 360) % 360 / this.tagStep); + } + + tagToAngle(tagIndex) { + return (tagIndex * this.tagStep + this.tagStep / 2) % 360; + } + + findOptimalTag(telescopeAngle) { + // Finde den Tag, der das Teleskop am besten zentriert + const telTagIndex = this.getTagIndex(telescopeAngle); + + // Teste den Tag mit dem Teleskop und die Nachbar-Tags + const candidates = [ + (telTagIndex - 1 + this.tagCount) % this.tagCount, + telTagIndex, + (telTagIndex + 1) % this.tagCount + ]; + + let bestTag = telTagIndex; + let bestDiff = Infinity; + + for (let tagIndex of candidates) { + const tagAngle = this.tagToAngle(tagIndex); + const diff = this.angleDiff(telescopeAngle, tagAngle); + const absDiff = Math.abs(diff); + + if (absDiff < bestDiff) { + bestDiff = absDiff; + bestTag = tagIndex; + } + } + + return bestTag; + } + updateTelescopePosition(telescopeAngle) { this.telescopeAngle = telescopeAngle; } @@ -57,41 +104,81 @@ class Dome { updateDomePosition() { let diff = this.angleDiff(this.telescopeAngle, this.angle); let halfSlot = this.slotWidth / 2; - let triggerPoint = halfSlot - 2.0; // Starte früher! (8° statt 10°) + let triggerPoint = halfSlot - 4.0; // Noch früher triggern! (6° statt 8°) let moveDir = "STOP"; if (this.state === "IDLE") { - // Prüfen, ob Teleskop aus Schlitz läuft - aber früher triggern! - if (diff > triggerPoint) { - // CW-Bewegung → Kuppel zentriert sich um das Teleskop - this.targetDomeAngle = (this.telescopeAngle + 360) % 360; - this.state = "MOVING"; - console.log(`[Dome] START MOVING: Tel out of slot CW (${diff.toFixed(1)}° > ${triggerPoint.toFixed(1)}°), target: ${this.targetDomeAngle.toFixed(1)}° (centered on telescope)`); - } else if (diff < -triggerPoint) { - // CCW-Bewegung → Kuppel zentriert sich um das Teleskop - this.targetDomeAngle = (this.telescopeAngle + 360) % 360; - this.state = "MOVING"; - console.log(`[Dome] START MOVING: Tel out of slot CCW (${diff.toFixed(1)}° < ${-triggerPoint.toFixed(1)}°), target: ${this.targetDomeAngle.toFixed(1)}° (centered on telescope)`); + // Prüfen, ob Teleskop aus Schlitz läuft + if (Math.abs(diff) > triggerPoint) { + // Finde den optimalen Tag für das Teleskop + let optimalTag = this.findOptimalTag(this.telescopeAngle); + this.targetTagIndex = optimalTag; + + // Debug für große Sprünge (45° Bewegungen) + const absDiff = Math.abs(diff); + if (absDiff > 20) { + console.log(`[Dome] LARGE JUMP DEBUG: Tel=${this.telescopeAngle.toFixed(1)}°, Dome=${this.angle.toFixed(1)}°, Diff=${diff.toFixed(1)}°`); + console.log(`[Dome] Current Tag=${this.currentTagIndex}, Optimal Tag=${optimalTag}, Direction=${diff > 0 ? 'CW' : 'CCW'}`); + + // Zeige auch die findOptimalTag Ergebnisse + console.log(`[Dome] Optimal Tag ${optimalTag} = ${this.tagToAngle(optimalTag).toFixed(1)}°`); + } + + // Bei großen Sprüngen (>20°) erweiterten Puffer verwenden + // WICHTIG: Puffer immer in CW-Richtung (Teleskop-Rotationsrichtung!) + if (absDiff > 20) { + // Bei großen Sprüngen: 1 Tag CW-Puffer (Teleskop dreht sich ja CW weiter!) + this.targetTagIndex = (optimalTag + 1) % this.tagCount; + console.log(`[Dome] Large jump: Adding CW buffer, Tag ${optimalTag} → ${this.targetTagIndex}`); + } else if (absDiff > 8.0) { // Normale große Abweichungen + if (diff > 0) { + // Normale CW-Bewegung → 1 Tag weiter CW + this.targetTagIndex = (optimalTag + 1) % this.tagCount; + } else { + // Normale CCW-Bewegung → kein Puffer (Teleskop kommt ja zurück) + this.targetTagIndex = optimalTag; + } + if (diff > 0) { + this.targetTagIndex = (optimalTag + 1) % this.tagCount; + } else { + this.targetTagIndex = (optimalTag - 1 + this.tagCount) % this.tagCount; + } + } + + const targetAngle = this.tagToAngle(this.targetTagIndex); + + if (this.targetTagIndex !== this.currentTagIndex) { + this.targetDomeAngle = targetAngle; // Physisches Ziel + this.state = "MOVING"; + const bufferInfo = this.targetTagIndex !== optimalTag ? " [+buffer]" : ""; + console.log(`[Dome] START MOVING: Tel out of slot (${diff.toFixed(1)}° > ${triggerPoint.toFixed(1)}°)`); + console.log(`[Dome] Tag ${this.currentTagIndex} (${this.angle.toFixed(1)}°) → Tag ${this.targetTagIndex} (${targetAngle.toFixed(1)}°)${bufferInfo}`); + } + } + } else if (this.state === "MOVING") { + // Während der Bewegung: Höhere Trigger-Schwelle, damit keine neuen Bewegungen ausgelöst werden + if (Math.abs(diff) > halfSlot + 2.0) { // 12° statt 6° während Bewegung + console.log(`[Dome] WARNING: Large deviation during movement! Tel=${this.telescopeAngle.toFixed(1)}°, Dome=${this.angle.toFixed(1)}°, Diff=${diff.toFixed(1)}°`); + console.log(`[Dome] Continuing current movement to ${this.targetDomeAngle.toFixed(1)}°`); } } if (this.state === "MOVING") { + // Smoothe physische Bewegung zum Ziel-Tag let delta = this.angleDiff(this.targetDomeAngle, this.angle); if (Math.abs(delta) > this.domeSpeed) { this.angle = (this.angle + Math.sign(delta) * this.domeSpeed + 360) % 360; moveDir = Math.sign(delta) > 0 ? "CW" : "CCW"; + + console.log(`[Dome] MOVING: ${this.angle.toFixed(1)}° → ${this.targetDomeAngle.toFixed(1)}°, Dir=${moveDir}`); } else { - // Ziel erreicht + // Ziel erreicht - Kuppel "erkennt" jetzt den neuen Tag this.angle = this.targetDomeAngle; + this.currentTagIndex = this.targetTagIndex; // Tag-Position aktualisiert! this.state = "IDLE"; - console.log(`[Dome] REACHED TARGET: ${this.angle.toFixed(1)}°, back to IDLE`); + console.log(`[Dome] REACHED TARGET: Tag ${this.currentTagIndex} (${this.angle.toFixed(1)}°), back to IDLE`); } } - - // Debug nur bei Aktivität - if (moveDir !== "STOP") { - console.log(`[Dome] ${this.state}: Tel=${this.telescopeAngle.toFixed(1)}°, Dome=${this.angle.toFixed(1)}° → ${this.targetDomeAngle.toFixed(1)}°, Dir=${moveDir}`); - } } // Winkeldifferenz berechnen - kürzester Weg zwischen zwei Winkeln