x-axis justierung: lines 3
This commit is contained in:
@@ -666,6 +666,54 @@ function buildCompareLines() {
|
||||
if (onlyCompare.length) parts.push(`nur Vergleich: ${onlyCompare.join(' ')}`);
|
||||
if (noMatch.length) parts.push(`nur Basis: ${noMatch.join(' ')}`);
|
||||
vlog(parts.join(' | '), matchedIds.length ? 'ok' : 'warn');
|
||||
|
||||
// ── Bewegungsanalyse: mittlerer Verschiebungsvektor → Abweichung von X-Achse ──
|
||||
if (matchedIds.length > 0) {
|
||||
// Summe aller Verschiebungsvektoren (in Roboter-Koordinaten mm)
|
||||
let sx = 0, sy = 0, sz = 0;
|
||||
for (const cm of _compareFremdMarkers) {
|
||||
const pm = primaryMap.get(cm.marker_id);
|
||||
if (!pm) continue;
|
||||
const [pmx, pmy, pmz] = pm.position_mm.map(Number);
|
||||
const [cmx, cmy, cmz] = cm.position_mm.map(Number);
|
||||
sx += cmx - pmx; sy += cmy - pmy; sz += cmz - pmz;
|
||||
}
|
||||
const n = matchedIds.length;
|
||||
const dx = sx / n, dy = sy / n, dz = sz / n;
|
||||
const dist = Math.sqrt(dx*dx + dy*dy + dz*dz);
|
||||
|
||||
if (dist > 0.01) { // mindestens 0.01 mm Bewegung
|
||||
// Einheitsvektor – immer in Richtung positives X zeigen (konsistente Vorzeichen)
|
||||
let vx = dx/dist, vy = dy/dist, vz = dz/dist;
|
||||
if (vx < 0) { vx = -vx; vy = -vy; vz = -vz; }
|
||||
|
||||
// Abweichungswinkel zur X-Achse [1,0,0] in Roboter-Koordinaten
|
||||
// horizontal (XY-Ebene, Rotation um Z): positiv = nach Y (rückwärts) verschoben
|
||||
// vertikal (XZ-Ebene, Rotation um Y): positiv = nach oben (+Z) verschoben
|
||||
const degXY = Math.atan2(vy, vx) * 180 / Math.PI;
|
||||
const degXZ = Math.atan2(vz, vx) * 180 / Math.PI;
|
||||
|
||||
const fmt = v => (v >= 0 ? '+' : '') + v.toFixed(3) + '°';
|
||||
const good = Math.abs(degXY) < 0.5 && Math.abs(degXZ) < 0.5;
|
||||
|
||||
vlog(`Bewegung: ⌀${dist.toFixed(2)} mm dir=[${vx.toFixed(4)}, ${vy.toFixed(4)}, ${vz.toFixed(4)}] (${n} Marker)`);
|
||||
vlog(`Abw. von X-Achse: horizontal(XY) ${fmt(degXY)} vertikal(XZ) ${fmt(degXZ)}`, good ? 'ok' : 'warn');
|
||||
|
||||
// Parent informieren → aktiviert "X-Achse übernehmen"-Button
|
||||
window.parent.postMessage({
|
||||
type: 'xaxis-measurement',
|
||||
direction: [vx, vy, vz],
|
||||
angleXY: degXY,
|
||||
angleXZ: degXZ,
|
||||
numMarkers: n,
|
||||
distMm: dist,
|
||||
}, '*');
|
||||
} else {
|
||||
vlog(`Bewegung zu klein (${dist.toFixed(3)} mm) – Winkelberechnung übersprungen`, 'warn');
|
||||
// Messung ungültig → Parent mitteilen
|
||||
window.parent.postMessage({ type: 'xaxis-measurement', direction: null }, '*');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Daten laden ───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -420,6 +420,80 @@ function initXAxis() {
|
||||
btn.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
// ── X-Achse übernehmen ────────────────────────────────────────────────────
|
||||
// Empfängt postMessage aus dem eingebetteten boardViewer-iframe.
|
||||
let _xaxisDirection = null; // zuletzt gemessene Richtung [vx,vy,vz]
|
||||
|
||||
const adoptBtn = document.getElementById('btn-xaxis-adopt');
|
||||
|
||||
function onXaxisMessage(e) {
|
||||
// Nachricht muss vom boardViewer-iframe stammen
|
||||
const frame = document.getElementById('xaxis-viewer-frame');
|
||||
if (!frame || e.source !== frame.contentWindow) return;
|
||||
const msg = e.data;
|
||||
if (!msg || msg.type !== 'xaxis-measurement') return;
|
||||
|
||||
if (Array.isArray(msg.direction)) {
|
||||
_xaxisDirection = msg.direction;
|
||||
const fmt = v => (v >= 0 ? '+' : '') + v.toFixed(3) + '°';
|
||||
logX(`📐 Messung empfangen: dir=[${msg.direction.map(v => v.toFixed(4)).join(', ')}]` +
|
||||
` XY=${fmt(msg.angleXY)} XZ=${fmt(msg.angleXZ)}` +
|
||||
` (${msg.numMarkers} Marker, Ø${msg.distMm.toFixed(1)} mm)`);
|
||||
if (adoptBtn) {
|
||||
adoptBtn.disabled = false;
|
||||
adoptBtn.style.opacity = '1';
|
||||
adoptBtn.style.cursor = 'pointer';
|
||||
adoptBtn.title = `X-Achse übernehmen (dir=[${_xaxisDirection.map(v => v.toFixed(4)).join(', ')}])`;
|
||||
}
|
||||
} else {
|
||||
// Ungültige / zu kleine Bewegung → Button sperren
|
||||
_xaxisDirection = null;
|
||||
if (adoptBtn) {
|
||||
adoptBtn.disabled = true;
|
||||
adoptBtn.style.opacity = '.45';
|
||||
adoptBtn.style.cursor = 'not-allowed';
|
||||
adoptBtn.title = 'Noch keine gültige Messung verfügbar';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('message', onXaxisMessage);
|
||||
|
||||
if (adoptBtn) {
|
||||
adoptBtn.addEventListener('click', async () => {
|
||||
if (!_xaxisDirection) return;
|
||||
const fmt = v => (v >= 0 ? '+' : '') + v.toFixed(4);
|
||||
logX(`🔄 Übernehme X-Achse: dir=[${_xaxisDirection.map(fmt).join(', ')}] …`);
|
||||
adoptBtn.disabled = true;
|
||||
adoptBtn.style.opacity = '.45';
|
||||
try {
|
||||
const r = await fetch('/api/robot/adopt-x-axis', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ direction: _xaxisDirection }),
|
||||
});
|
||||
const data = await r.json();
|
||||
if (!r.ok) {
|
||||
logX(`❌ Fehler: ${data.error ?? r.status}`);
|
||||
return;
|
||||
}
|
||||
logX(`✅ X-Achse gespeichert — ${data.numChanged} Marker rotiert`);
|
||||
logX(` Ursprung (A0-Schwerpunkt): [${data.origin.join(', ')}] mm`);
|
||||
logX(` Neue X-Achse: [${data.newXAxis.join(', ')}]` +
|
||||
` Korr. XY=${(data.angleXYdeg >= 0 ? '+' : '') + data.angleXYdeg}°` +
|
||||
` XZ=${(data.angleXZdeg >= 0 ? '+' : '') + data.angleXZdeg}°`);
|
||||
// Viewer neu laden damit die aktualisierten Positionen sichtbar werden
|
||||
const frame = document.getElementById('xaxis-viewer-frame');
|
||||
if (frame?.contentWindow) frame.contentWindow.postMessage({ type: 'reload' }, '*');
|
||||
} catch (err) {
|
||||
logX(`❌ Netzwerkfehler: ${err}`);
|
||||
} finally {
|
||||
adoptBtn.disabled = false;
|
||||
adoptBtn.style.opacity = '1';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ── Tab: Board (shared helpers) ───────────────────────────────────────────────
|
||||
|
||||
@@ -45,6 +45,16 @@
|
||||
Rechts ➡
|
||||
</button>
|
||||
</div>
|
||||
<div style="margin-top:16px;display:flex;align-items:center;gap:14px;flex-wrap:wrap">
|
||||
<button id="btn-xaxis-adopt" disabled
|
||||
style="padding:5px 18px;opacity:.45;cursor:not-allowed;border:1px solid #4a9eff;border-radius:3px;background:#1e293b;color:#c8cdd8;font:inherit;font-size:12px"
|
||||
title="Gemessene X-Achsen-Richtung in robot.json übernehmen – folgt">
|
||||
X-Achse übernehmen
|
||||
</button>
|
||||
<span style="font-size:11px;color:var(--muted)">
|
||||
Übernimmt die gemessene Richtung (aus Basis- und Vergleichs-Run) als X-Achse in robot.json
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Ausgabe / Log ──────────────────────────────────────────────────────── -->
|
||||
|
||||
Reference in New Issue
Block a user