Logs & Marker anzeigen
This commit is contained in:
@@ -251,7 +251,15 @@ const gCompareLines = new THREE.Group(); // Verbindungslinien Pos A↔Pos B
|
||||
const gPositionC = new THREE.Group(); // Pos C Marker (nur fremd, cyan)
|
||||
const gYAxis = new THREE.Group(); // Y-Achse Visualisierung (Kreismittelpunkte, Achse)
|
||||
const gSkeleton = new THREE.Group(); // Roboter-Skeleton (FK, nur im Homing-Mode)
|
||||
scene.add(gPaper, gMarkers, gMeasured, gCameras, gCompare, gCompareLines, gPositionC, gYAxis, gSkeleton);
|
||||
const gArmMarkers = new THREE.Group(); // Arm-Marker Modellpositionen + Fehlerlinien (FK)
|
||||
scene.add(gPaper, gMarkers, gMeasured, gCameras, gCompare, gCompareLines, gPositionC, gYAxis, gSkeleton, gArmMarkers);
|
||||
|
||||
const LINK_COLORS = {
|
||||
Board: 0x8b6528, Base: 0x888888,
|
||||
Arm1: 0x3355cc, Ellbow: 0xaaaaaa, Arm2: 0xddcc88,
|
||||
Hand: 0xcc8833, Palm: 0xcc3333,
|
||||
FingerA: 0x33aa33, FingerB: 0x33aa33,
|
||||
};
|
||||
|
||||
// ── Zustand für Positionen ────────────────────────────────────────────────────
|
||||
let _primaryFremdMarkers = []; // Pos A – [{marker_id, position_mm, num_cameras}]
|
||||
@@ -259,8 +267,9 @@ let _compareFremdMarkers = []; // Pos B – [{marker_id, position_mm, num_cam
|
||||
let _positionCFremdMarkers = []; // Pos C – [{marker_id, position_mm, num_cameras}]
|
||||
|
||||
// ── Homing-Mode Zustand ───────────────────────────────────────────────────────
|
||||
let _currentRobot = null; // robot.json nach loadData()
|
||||
let _homingAngles = null; // { x, y, z, a, b, c, e } nach Homing-Run
|
||||
let _currentRobot = null; // robot.json nach loadData()
|
||||
let _homingAngles = null; // { x, y, z, a, b, c, e } nach Homing-Run
|
||||
let _measuredMarkers = null; // measuredMarkers aus letztem buildScene-Aufruf
|
||||
|
||||
// ── Roboter-Skeleton (Forward Kinematics) ─────────────────────────────────────
|
||||
/**
|
||||
@@ -270,6 +279,7 @@ let _homingAngles = null; // { x, y, z, a, b, c, e } nach Homing-Run
|
||||
*/
|
||||
function buildSkeletonFK(robot, angles) {
|
||||
clearGroup(gSkeleton);
|
||||
clearGroup(gArmMarkers);
|
||||
if (!robot?.links) return;
|
||||
|
||||
const links = robot.links;
|
||||
@@ -310,23 +320,54 @@ function buildSkeletonFK(robot, angles) {
|
||||
|
||||
// 3. Skeleton-Segment zeichnen
|
||||
const skel = link.skeleton;
|
||||
if (!skel?.from || !skel?.to) continue;
|
||||
if (skel?.from && skel?.to) {
|
||||
const [fx, fy, fz] = skel.from;
|
||||
const [tx, ty, tz] = skel.to;
|
||||
const fromW = new THREE.Vector3(fx * S, fz * S, -fy * S).applyMatrix4(childFrame);
|
||||
const toW = new THREE.Vector3(tx * S, tz * S, -ty * S).applyMatrix4(childFrame);
|
||||
|
||||
const [fx, fy, fz] = skel.from;
|
||||
const [tx, ty, tz] = skel.to;
|
||||
const fromW = new THREE.Vector3(fx * S, fz * S, -fy * S).applyMatrix4(childFrame);
|
||||
const toW = new THREE.Vector3(tx * S, tz * S, -ty * S).applyMatrix4(childFrame);
|
||||
const [cr, cg, cb] = skel.color ?? [0.8, 0.2, 0.2];
|
||||
const color = new THREE.Color(cr, cg, cb);
|
||||
const rad = Math.max((skel.radius ?? 4) * S, 0.004);
|
||||
|
||||
const [cr, cg, cb] = skel.color ?? [0.8, 0.2, 0.2];
|
||||
const color = new THREE.Color(cr, cg, cb);
|
||||
const rad = Math.max((skel.radius ?? 4) * S, 0.004);
|
||||
gSkeleton.add(makeLine(fromW, toW, color, 0.9));
|
||||
gSkeleton.add(makeSphere(fromW, rad, color));
|
||||
gSkeleton.add(makeSphere(toW, rad, color));
|
||||
// Gelenk-Mittelpunkt (Welt-Ursprung des Link-Frames)
|
||||
const jointW = new THREE.Vector3().applyMatrix4(childFrame);
|
||||
gSkeleton.add(makeSphere(jointW, 0.004, 0xc8cdd8));
|
||||
}
|
||||
|
||||
gSkeleton.add(makeLine(fromW, toW, color, 0.9));
|
||||
gSkeleton.add(makeSphere(fromW, rad, color));
|
||||
gSkeleton.add(makeSphere(toW, rad, color));
|
||||
// Gelenk-Mittelpunkt (Welt-Ursprung des Link-Frames)
|
||||
const jointW = new THREE.Vector3().applyMatrix4(childFrame);
|
||||
gSkeleton.add(makeSphere(jointW, 0.004, 0xc8cdd8));
|
||||
// 4. Arm-Marker zeichnen (Modellposition via FK, als orientiertes Quadrat)
|
||||
if (link.markers?.length > 0) {
|
||||
const col = LINK_COLORS[linkName] ?? 0xffffff;
|
||||
for (const m of link.markers) {
|
||||
if (!m.position) continue;
|
||||
const [lx, ly, lz] = m.position;
|
||||
const posWorld = new THREE.Vector3(lx * S, lz * S, -ly * S).applyMatrix4(childFrame);
|
||||
const markerSizeM = (m.size ?? 25) * S;
|
||||
const [nx, ny, nz] = m.normal ?? [0, 0, 1];
|
||||
const normalWorld = new THREE.Vector3(nx, nz, -ny).transformDirection(childFrame);
|
||||
gArmMarkers.add(makeMarkerSquareOriented(posWorld, normalWorld, markerSizeM, col));
|
||||
gArmMarkers.add(makeSphere(posWorld, 0.003, col));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Fehlerlinien: Modell-Marker → gemessene Position (aus 3b)
|
||||
if (_measuredMarkers?.markers?.length > 0) {
|
||||
for (const obs of _measuredMarkers.markers) {
|
||||
if (obs.link === 'Board' || !obs.link) continue;
|
||||
const ldata = links[obs.link];
|
||||
if (!ldata || !frames[obs.link]) continue;
|
||||
const modelM = ldata.markers?.find(mm => mm.id === obs.marker_id);
|
||||
if (!modelM?.position) continue;
|
||||
const [lx, ly, lz] = modelM.position;
|
||||
const modelPosW = new THREE.Vector3(lx * S, lz * S, -ly * S).applyMatrix4(frames[obs.link]);
|
||||
const obsPosW = r2vArr(obs.position_mm);
|
||||
gArmMarkers.add(makeLine(modelPosW, obsPosW, 0xff8800, 0.85));
|
||||
gArmMarkers.add(makeSphere(obsPosW, 0.007, LINK_COLORS[obs.link] ?? 0x3b82f6));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,6 +403,18 @@ function makeMarkerSquare(pos, size, color) {
|
||||
return m;
|
||||
}
|
||||
|
||||
function makeMarkerSquareOriented(pos, normalVec, size, color) {
|
||||
const geo = new THREE.PlaneGeometry(size, size);
|
||||
const mat = new THREE.MeshPhongMaterial({ color, side: THREE.DoubleSide, transparent: true, opacity: 0.85 });
|
||||
const mesh = new THREE.Mesh(geo, mat);
|
||||
mesh.position.copy(pos);
|
||||
const n = normalVec.clone().normalize();
|
||||
if (n.lengthSq() > 1e-9) {
|
||||
mesh.quaternion.setFromUnitVectors(new THREE.Vector3(0, 0, 1), n);
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
|
||||
function makeEdgeBorder(pos, size, color) {
|
||||
const geo = new THREE.EdgesGeometry(new THREE.PlaneGeometry(size, size));
|
||||
const mat = new THREE.LineBasicMaterial({ color, transparent: true, opacity: 0.75 });
|
||||
@@ -404,6 +457,7 @@ function buildScene(data) {
|
||||
clearGroup(gPaper); clearGroup(gMarkers); clearGroup(gMeasured); clearGroup(gCameras);
|
||||
|
||||
const { robot, detections, cameraPoses, measuredMarkers } = data;
|
||||
_measuredMarkers = measuredMarkers ?? null;
|
||||
|
||||
// Alle erkannten Marker-IDs (über alle Kameras)
|
||||
const detectedIds = new Set();
|
||||
|
||||
@@ -446,6 +446,8 @@ const SCRIPT_4B = path.join(__dirname, '..', 'scripts', '4b_revolute_angle.p
|
||||
*/
|
||||
function runScript(args, send) {
|
||||
return new Promise((resolve) => {
|
||||
const cmd = [PYTHON_BIN, '-u', ...args].join(' ');
|
||||
console.log(`[runScript] ${cmd}`);
|
||||
const proc = spawn(PYTHON_BIN, ['-u', ...args]);
|
||||
|
||||
let outBuf = '';
|
||||
|
||||
Reference in New Issue
Block a user