delete homing. Have to redo
This commit is contained in:
+26
-26
@@ -33,11 +33,11 @@
|
||||
|
||||
// ── Exact constants from PositionControl.cpp ─────────────────────
|
||||
const ARM = {
|
||||
d: 25.8, // full motor separation (mm)
|
||||
d: 25.8, // full motor separation (mm)
|
||||
d2: 12.9, // half separation; M1 at (+d2, 0), M2 at (-d2, 0)
|
||||
l1: 85.0, // proximal link length (mm)
|
||||
l1: 85.0, // proximal link length (mm)
|
||||
l2: 110.0, // distal link length (mm)
|
||||
STEPS_PER_REV: 2048,
|
||||
STEPS_PER_REV: 2048,
|
||||
STEP_ANGLE_DEG: 360 / 2048, // ≈ 0.17578125 °/step
|
||||
};
|
||||
|
||||
@@ -48,16 +48,16 @@ const LIMITS = {
|
||||
// ── Outer board boundary ───────────────────────────────────────
|
||||
// The EE cannot be requested outside this rectangle.
|
||||
X_MIN: -150, // ← TUNE: left edge of board
|
||||
X_MAX: 150, // ← TUNE: right edge of board
|
||||
Y_MIN: -30, // ← TUNE: bottom (numbers reach ~44 mm; sign coords go lower)
|
||||
Y_MAX: 145, // ← TUNE: top (highest letter is ~128 mm)
|
||||
X_MAX: 150, // ← TUNE: right edge of board
|
||||
Y_MIN: -30, // ← TUNE: bottom (numbers reach ~44 mm; sign coords go lower)
|
||||
Y_MAX: 145, // ← TUNE: top (highest letter is ~128 mm)
|
||||
|
||||
// ── Centre mechanism exclusion box ────────────────────────────
|
||||
// Rectangular zone centred on (0, 0) where the motor housing sits.
|
||||
// The EE and both elbows must stay outside this area.
|
||||
BOX_HALF_W: 30, // ← TUNE: half-width in X (motors at ±12.9, housing wider)
|
||||
BOX_Y_MIN: -10, // ← TUNE: bottom of housing
|
||||
BOX_Y_MAX: 40, // ← TUNE: top of housing
|
||||
BOX_Y_MAX: 40, // ← TUNE: top of housing
|
||||
|
||||
// ── Elbow exclusion zone (prevents arm crossing near the box) ─
|
||||
// Each elbow has a separate rectangular exclusion box.
|
||||
@@ -66,7 +66,7 @@ const LIMITS = {
|
||||
// If ELBOW_BOX_X_INNER is 5, the left elbow's X must be > +5 mm
|
||||
// (can never cross to the other side of the box mid-point).
|
||||
ELBOW_BOX_X_INNER: 5, // ← TUNE: inner X margin from centre for each elbow
|
||||
ELBOW_BOX_Y_MAX: 50, // ← TUNE: Y below which elbow crossing is forbidden
|
||||
ELBOW_BOX_Y_MAX: 50, // ← TUNE: Y below which elbow crossing is forbidden
|
||||
};
|
||||
|
||||
// ── Letter / number position lookup table ────────────────────────
|
||||
@@ -132,23 +132,23 @@ function solve(x, y) {
|
||||
// ── Motor 1 (pivot at +d2, 0 = +12.9 mm) ─────────────────────
|
||||
// xmd = x - d2 is the X component of (target – M1_pivot).
|
||||
const xmd = x - d2;
|
||||
const s = Math.sqrt(xmd * xmd + y * y);
|
||||
const s = Math.sqrt(xmd * xmd + y * y);
|
||||
if (s < 1e-6) return { theta1: 0, theta2: 0, reachable: false };
|
||||
const cosW1 = (l2 * l2 - s * s - l1 * l1) / (-2 * l1 * s);
|
||||
if (cosW1 < -1 || cosW1 > 1) return { theta1: 0, theta2: 0, reachable: false };
|
||||
const q = Math.atan2(y, xmd);
|
||||
const w1 = Math.acos(cosW1);
|
||||
const q = Math.atan2(y, xmd);
|
||||
const w1 = Math.acos(cosW1);
|
||||
const theta1 = q - w1;
|
||||
|
||||
// ── Motor 2 (pivot at -d2, 0 = -12.9 mm) ─────────────────────
|
||||
// xpd = x + d2 is the X component of (target – M2_pivot).
|
||||
const xpd = x + d2;
|
||||
const t = Math.sqrt(xpd * xpd + y * y);
|
||||
const t = Math.sqrt(xpd * xpd + y * y);
|
||||
if (t < 1e-6) return { theta1: 0, theta2: 0, reachable: false };
|
||||
const cosW2 = (l2 * l2 - t * t - l1 * l1) / (-2 * l1 * t);
|
||||
if (cosW2 < -1 || cosW2 > 1) return { theta1: 0, theta2: 0, reachable: false };
|
||||
const r = Math.atan2(y, xpd);
|
||||
const w2 = Math.acos(cosW2);
|
||||
const r = Math.atan2(y, xpd);
|
||||
const w2 = Math.acos(cosW2);
|
||||
const theta2 = r + w2;
|
||||
|
||||
return { theta1, theta2, reachable: true };
|
||||
@@ -180,16 +180,16 @@ function forward(theta1, theta2) {
|
||||
|
||||
// Elbow 1 — tip of Motor 1 proximal link (motor at +d2)
|
||||
const e1x = +d2 + l1 * Math.cos(theta1);
|
||||
const e1y = l1 * Math.sin(theta1);
|
||||
const e1y = l1 * Math.sin(theta1);
|
||||
|
||||
// Elbow 2 — tip of Motor 2 proximal link (motor at -d2)
|
||||
const e2x = -d2 + l1 * Math.cos(theta2);
|
||||
const e2y = l1 * Math.sin(theta2);
|
||||
const e2y = l1 * Math.sin(theta2);
|
||||
|
||||
// End-effector: intersection of the two distal-link circles
|
||||
// (radius l2, centred on each elbow). Pick the "upward" solution.
|
||||
const dx = e2x - e1x;
|
||||
const dy = e2y - e1y;
|
||||
const dx = e2x - e1x;
|
||||
const dy = e2y - e1y;
|
||||
const dist = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (dist < 1e-6 || dist > 2 * l2) {
|
||||
@@ -203,15 +203,15 @@ function forward(theta1, theta2) {
|
||||
};
|
||||
}
|
||||
|
||||
const a = dist / 2;
|
||||
const h = Math.sqrt(Math.max(0, l2 * l2 - a * a));
|
||||
const a = dist / 2;
|
||||
const h = Math.sqrt(Math.max(0, l2 * l2 - a * a));
|
||||
const mx = (e1x + e2x) / 2;
|
||||
const my = (e1y + e2y) / 2;
|
||||
|
||||
// Two intersection candidates
|
||||
const px1 = mx + h * ( dy / dist);
|
||||
const px1 = mx + h * (dy / dist);
|
||||
const py1 = my + h * (-dx / dist);
|
||||
const px2 = mx - h * ( dy / dist);
|
||||
const px2 = mx - h * (dy / dist);
|
||||
const py2 = my - h * (-dx / dist);
|
||||
|
||||
// Always pick the candidate with higher Y (EE above the elbow line)
|
||||
@@ -247,15 +247,15 @@ function armsCrossed(theta1, theta2) {
|
||||
|
||||
// Elbow positions (same formula as forward())
|
||||
const e1x = +d2 + l1 * Math.cos(theta1);
|
||||
const e1y = l1 * Math.sin(theta1);
|
||||
const e1y = l1 * Math.sin(theta1);
|
||||
const e2x = -d2 + l1 * Math.cos(theta2);
|
||||
const e2y = l1 * Math.sin(theta2);
|
||||
const e2y = l1 * Math.sin(theta2);
|
||||
|
||||
// Elbow1 (from M1 on the RIGHT) must not appear far to the LEFT at low height
|
||||
// Elbow2 (from M2 on the LEFT) must not appear far to the RIGHT at low height
|
||||
// Both conditions together catch the "arms have swapped sides" scenario.
|
||||
const e1_crossed = e1x < -XI && e1y < YM; // M1's elbow went too far left
|
||||
const e2_crossed = e2x > XI && e2y < YM; // M2's elbow went too far right
|
||||
const e2_crossed = e2x > XI && e2y < YM; // M2's elbow went too far right
|
||||
|
||||
return e1_crossed || e2_crossed;
|
||||
}
|
||||
@@ -285,7 +285,7 @@ function checkWorkspace(x, y) {
|
||||
|
||||
// 2. Centre mechanism exclusion box
|
||||
if (x > -L.BOX_HALF_W && x < L.BOX_HALF_W &&
|
||||
y > L.BOX_Y_MIN && y < L.BOX_Y_MAX)
|
||||
y > L.BOX_Y_MIN && y < L.BOX_Y_MAX)
|
||||
return { ok: false, reason: `(${x.toFixed(1)}, ${y.toFixed(1)}) is inside the mechanism housing` };
|
||||
|
||||
// 3. IK geometric reachability
|
||||
|
||||
Reference in New Issue
Block a user