arbeiten am callibration
This commit is contained in:
@@ -736,6 +736,10 @@ function buildCompareLines() {
|
||||
|
||||
// ── Y-Achsen-Berechnung aus drei Positionen ───────────────────────────────────
|
||||
|
||||
/** Marker, die sich weniger als diesen Wert bewegen, werden ignoriert.
|
||||
* Entspricht dem min_movement_mm-Parameter im Python-Skript. */
|
||||
const Y_AXIS_MIN_MOVEMENT_MM = 10.0;
|
||||
|
||||
function computeAndShowYAxis() {
|
||||
clearGroup(gYAxis);
|
||||
|
||||
@@ -755,6 +759,8 @@ function computeAndShowYAxis() {
|
||||
|
||||
const circumcenters = []; // [{id, C:[x,y,z]}] in mm
|
||||
const normals = []; // [[nx,ny,nz]] – Achsenrichtung je Marker
|
||||
const markerData = []; // [{markerId, posA, posB, posC, circumcenter, normal}] für Speicherung
|
||||
const skipped = []; // [{id, reason, maxMoveMm}]
|
||||
|
||||
for (const [id, ma] of mapA) {
|
||||
const mb = mapB.get(id);
|
||||
@@ -765,6 +771,22 @@ function computeAndShowYAxis() {
|
||||
const P2 = mb.position_mm.map(Number);
|
||||
const P3 = mc.position_mm.map(Number);
|
||||
|
||||
// ── Mindest-Bewegungs-Filter ─────────────────────────────────────────────
|
||||
// Marker, die sich zwischen den drei Positionen kaum bewegen, liefern
|
||||
// degenerate Umkreismittelpunkte und korrumpieren die Achsenschätzung.
|
||||
// Dieselbe Logik wie im Python-Skript (min_movement_mm).
|
||||
const maxMoveMm = Math.max(
|
||||
Math.sqrt(dist2(P1, P2)),
|
||||
Math.sqrt(dist2(P2, P3)),
|
||||
Math.sqrt(dist2(P1, P3)),
|
||||
);
|
||||
if (maxMoveMm < Y_AXIS_MIN_MOVEMENT_MM) {
|
||||
vlog(`Y-Achse: Marker ${id} übersprungen – Bewegung zu gering` +
|
||||
` (${maxMoveMm.toFixed(1)} mm < ${Y_AXIS_MIN_MOVEMENT_MM} mm, kein rotierender Marker)`, 'warn');
|
||||
skipped.push({ id, reason: 'Bewegung zu gering', maxMoveMm: +maxMoveMm.toFixed(2) });
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normalenvektor der Kreisebene = Achsenrichtung
|
||||
const v1 = [P2[0]-P1[0], P2[1]-P1[1], P2[2]-P1[2]];
|
||||
const v2 = [P3[0]-P1[0], P3[1]-P1[1], P3[2]-P1[2]];
|
||||
@@ -795,6 +817,7 @@ function computeAndShowYAxis() {
|
||||
(w1*P1[2] + w2*P2[2] + w3*P3[2]) / wSum,
|
||||
];
|
||||
circumcenters.push({ id, C });
|
||||
markerData.push({ markerId: id, posA: P1, posB: P2, posC: P3, circumcenter: C, normal: n });
|
||||
|
||||
// Kreismittelpunkt (rose)
|
||||
gYAxis.add(makeSphere(r2vArr(C), 0.007, 0xfb7185));
|
||||
@@ -803,8 +826,11 @@ function computeAndShowYAxis() {
|
||||
}
|
||||
|
||||
if (circumcenters.length === 0) {
|
||||
vlog('Y-Achse: Keine gemeinsamen fremd-Marker in Pos A+B+C gefunden', 'warn');
|
||||
window.parent.postMessage({ type: 'yaxis-measurement', axisDir: null }, '*');
|
||||
const why = skipped.length
|
||||
? `Alle ${skipped.length} Marker gefiltert (Bewegung < ${Y_AXIS_MIN_MOVEMENT_MM} mm)`
|
||||
: 'Keine gemeinsamen fremd-Marker in Pos A+B+C gefunden';
|
||||
vlog(`Y-Achse: ${why}`, 'warn');
|
||||
window.parent.postMessage({ type: 'yaxis-measurement', axisDir: null, skipped }, '*');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -837,7 +863,11 @@ function computeAndShowYAxis() {
|
||||
const fmt = v => (v >= 0 ? '+' : '') + v.toFixed(3) + '°';
|
||||
const good = Math.abs(tiltXY) < 0.5 && Math.abs(tiltYZ) < 0.5;
|
||||
|
||||
vlog(`Y-Achse (${circumcenters.length} Marker): dir=[${axisDir.map(v => v.toFixed(4)).join(', ')}]`);
|
||||
const usedIds = circumcenters.map(c => c.id);
|
||||
const skippedIds = skipped.map(s => s.id);
|
||||
vlog(`Y-Achse: ${usedIds.length} Marker genutzt (${usedIds.join(', ')})` +
|
||||
(skippedIds.length ? ` · ${skippedIds.length} gefiltert (${skippedIds.join(', ')})` : ''));
|
||||
vlog(` dir=[${axisDir.map(v => v.toFixed(4)).join(', ')}]`);
|
||||
vlog(` Referenzpunkt: [${axisPoint.map(v => v.toFixed(1)).join(', ')}] mm`);
|
||||
vlog(` Abw. von Y-Achse: XY ${fmt(tiltXY)} YZ ${fmt(tiltYZ)}`, good ? 'ok' : 'warn');
|
||||
|
||||
@@ -847,7 +877,14 @@ function computeAndShowYAxis() {
|
||||
axisPoint,
|
||||
tiltXY,
|
||||
tiltYZ,
|
||||
numMarkers: circumcenters.length,
|
||||
numMarkers: circumcenters.length,
|
||||
numMarkersCommon: circumcenters.length + skipped.length,
|
||||
skipped,
|
||||
// Für rotation_detection.json: Run-Referenzen und Marker-Rohdaten
|
||||
runA: document.getElementById('sel-run-primary')?.value ?? null,
|
||||
runB: document.getElementById('sel-run-compare')?.value ?? null,
|
||||
runC: document.getElementById('sel-run-c')?.value ?? null,
|
||||
markerData,
|
||||
}, '*');
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
padding-top: 4px;
|
||||
flex-shrink: 0;
|
||||
width: 148px;
|
||||
}
|
||||
@@ -92,6 +91,7 @@ body {
|
||||
border-right: none;
|
||||
border-left: 3px solid var(--accent);
|
||||
padding-left: 13px; /* kompensiert den dickeren linken Rand */
|
||||
margin-right: -1px; /* überlappt 1px ins Panel → kein Zoom-Spalt */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -565,6 +565,20 @@ function initArm(tab) {
|
||||
log(`📐 Achse (${msg.numMarkers} Marker): dir=[${msg.axisDir.map(v => v.toFixed(4)).join(', ')}]` +
|
||||
` XY=${fmt(msg.tiltXY)} YZ=${fmt(msg.tiltYZ)}`);
|
||||
log(` Referenzpunkt: [${msg.axisPoint.map(v => v.toFixed(1)).join(', ')}] mm`);
|
||||
|
||||
// In rotation_detection.json speichern (anhängen)
|
||||
fetch('/api/xaxis/save-rotation-detection', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
axis: { dir: msg.axisDir, referencePoint: msg.axisPoint, tiltXY_deg: msg.tiltXY, tiltYZ_deg: msg.tiltYZ },
|
||||
runs: { A: msg.runA ?? null, B: msg.runB ?? null, C: msg.runC ?? null },
|
||||
numMarkers: msg.numMarkers,
|
||||
markers: msg.markerData ?? [],
|
||||
}),
|
||||
}).then(r => r.json())
|
||||
.then(d => log(`💾 Gespeichert: ${d.file} (${d.total} Messungen)`))
|
||||
.catch(e => log(`⚠ Speichern fehlgeschlagen: ${e.message}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,6 +20,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Aktionen ───────────────────────────────────────────────────────────── -->
|
||||
<div class="section full">
|
||||
<h2>Aktionen</h2>
|
||||
<div style="margin-top:14px;display:flex;align-items:center;gap:20px;flex-wrap:wrap">
|
||||
<button id="btn-arm1-ccw" style="font-size:18px;padding:6px 22px" title="Bieps rauf">
|
||||
⤴ Rauf
|
||||
</button>
|
||||
<span style="color:var(--muted);font-size:11px">Roboter-Bieps drehen (Schrittweite folgt)</span>
|
||||
<button id="btn-arm1-cw" style="font-size:18px;padding:6px 22px" title="Bieps runter">
|
||||
Runter ⤵
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section full">
|
||||
<h2>Ausgabe / Log</h2>
|
||||
<textarea id="log-arm1" readonly placeholder="(Ausgabe erscheint hier)"></textarea>
|
||||
|
||||
@@ -20,6 +20,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Aktionen ───────────────────────────────────────────────────────────── -->
|
||||
<div class="section full">
|
||||
<h2>Aktionen</h2>
|
||||
<div style="margin-top:14px;display:flex;align-items:center;gap:20px;flex-wrap:wrap">
|
||||
<button id="btn-arm2-ccw" style="font-size:18px;padding:6px 22px" title="Unterarm rauf">
|
||||
⤴ Rauf
|
||||
</button>
|
||||
<span style="color:var(--muted);font-size:11px">Roboter-Unterarm drehen (Schrittweite folgt)</span>
|
||||
<button id="btn-arm2-cw" style="font-size:18px;padding:6px 22px" title="Unterarm runter">
|
||||
Runter ⤵
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section full">
|
||||
<h2>Ausgabe / Log</h2>
|
||||
<textarea id="log-arm2" readonly placeholder="(Ausgabe erscheint hier)"></textarea>
|
||||
|
||||
Reference in New Issue
Block a user