Telekop rückwärts: Kuppel fängt
This commit is contained in:
@@ -6,11 +6,21 @@ class Dome {
|
|||||||
window.activeDomeInstance.stop();
|
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.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;
|
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)
|
// State Machine für diskrete Bewegung (wie Original)
|
||||||
this.state = "IDLE"; // "IDLE" oder "MOVING"
|
this.state = "IDLE"; // "IDLE" oder "MOVING"
|
||||||
this.targetDomeAngle = this.angle;
|
this.targetDomeAngle = this.angle;
|
||||||
@@ -50,6 +60,43 @@ class Dome {
|
|||||||
}, 100); // 10x pro Sekunde
|
}, 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) {
|
updateTelescopePosition(telescopeAngle) {
|
||||||
this.telescopeAngle = telescopeAngle;
|
this.telescopeAngle = telescopeAngle;
|
||||||
}
|
}
|
||||||
@@ -57,41 +104,81 @@ class Dome {
|
|||||||
updateDomePosition() {
|
updateDomePosition() {
|
||||||
let diff = this.angleDiff(this.telescopeAngle, this.angle);
|
let diff = this.angleDiff(this.telescopeAngle, this.angle);
|
||||||
let halfSlot = this.slotWidth / 2;
|
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";
|
let moveDir = "STOP";
|
||||||
|
|
||||||
if (this.state === "IDLE") {
|
if (this.state === "IDLE") {
|
||||||
// Prüfen, ob Teleskop aus Schlitz läuft - aber früher triggern!
|
// Prüfen, ob Teleskop aus Schlitz läuft
|
||||||
if (diff > triggerPoint) {
|
if (Math.abs(diff) > triggerPoint) {
|
||||||
// CW-Bewegung → Kuppel zentriert sich um das Teleskop
|
// Finde den optimalen Tag für das Teleskop
|
||||||
this.targetDomeAngle = (this.telescopeAngle + 360) % 360;
|
let optimalTag = this.findOptimalTag(this.telescopeAngle);
|
||||||
this.state = "MOVING";
|
this.targetTagIndex = optimalTag;
|
||||||
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) {
|
// Debug für große Sprünge (45° Bewegungen)
|
||||||
// CCW-Bewegung → Kuppel zentriert sich um das Teleskop
|
const absDiff = Math.abs(diff);
|
||||||
this.targetDomeAngle = (this.telescopeAngle + 360) % 360;
|
if (absDiff > 20) {
|
||||||
this.state = "MOVING";
|
console.log(`[Dome] LARGE JUMP DEBUG: Tel=${this.telescopeAngle.toFixed(1)}°, Dome=${this.angle.toFixed(1)}°, Diff=${diff.toFixed(1)}°`);
|
||||||
console.log(`[Dome] START MOVING: Tel out of slot CCW (${diff.toFixed(1)}° < ${-triggerPoint.toFixed(1)}°), target: ${this.targetDomeAngle.toFixed(1)}° (centered on telescope)`);
|
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") {
|
if (this.state === "MOVING") {
|
||||||
|
// Smoothe physische Bewegung zum Ziel-Tag
|
||||||
let delta = this.angleDiff(this.targetDomeAngle, this.angle);
|
let delta = this.angleDiff(this.targetDomeAngle, this.angle);
|
||||||
if (Math.abs(delta) > this.domeSpeed) {
|
if (Math.abs(delta) > this.domeSpeed) {
|
||||||
this.angle = (this.angle + Math.sign(delta) * this.domeSpeed + 360) % 360;
|
this.angle = (this.angle + Math.sign(delta) * this.domeSpeed + 360) % 360;
|
||||||
moveDir = Math.sign(delta) > 0 ? "CW" : "CCW";
|
moveDir = Math.sign(delta) > 0 ? "CW" : "CCW";
|
||||||
|
|
||||||
|
console.log(`[Dome] MOVING: ${this.angle.toFixed(1)}° → ${this.targetDomeAngle.toFixed(1)}°, Dir=${moveDir}`);
|
||||||
} else {
|
} else {
|
||||||
// Ziel erreicht
|
// Ziel erreicht - Kuppel "erkennt" jetzt den neuen Tag
|
||||||
this.angle = this.targetDomeAngle;
|
this.angle = this.targetDomeAngle;
|
||||||
|
this.currentTagIndex = this.targetTagIndex; // Tag-Position aktualisiert!
|
||||||
this.state = "IDLE";
|
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
|
// Winkeldifferenz berechnen - kürzester Weg zwischen zwei Winkeln
|
||||||
|
|||||||
Reference in New Issue
Block a user