Upgrade pathing

This commit is contained in:
osiu97
2026-07-08 17:52:38 +02:00
parent a912d23b7c
commit e1416f6979
6 changed files with 52 additions and 16 deletions
+11 -7
View File
@@ -327,12 +327,16 @@ function radToSteps(rad) {
return Math.round(-(rad / (2 * Math.PI)) * ARM.STEPS_PER_REV);
}
function radToStepsClosest(rad, currentSteps) {
let target = radToSteps(rad);
// Ensure we take the shortest path instead of winding up the motors
while (target - currentSteps > 1024) target -= 2048;
while (target - currentSteps < -1024) target += 2048;
return target;
function radToStepsAbsolute(rad, motor) {
let steps = radToSteps(rad);
// Motor 1 (Left) is constrained near 1536 steps (90 deg, UP)
// Motor 2 (Right) is constrained near -512 steps (90 deg, UP)
const center = motor === 1 ? 1536 : -512;
// Snap the step position to the closest equivalent angle around the center.
// This guarantees we always take the "top" physical path and never wrap through the bottom.
while (steps - center > 1024) steps -= 2048;
while (steps - center < -1024) steps += 2048;
return steps;
}
function stepsToDeg(steps) {
return steps * ARM.STEP_ANGLE_DEG;
@@ -344,5 +348,5 @@ function radToDeg(rad) {
export default {
ARM, LIMITS, LOOKUP_TABLE,
solve, forward, armsCrossed, checkWorkspace, lookup,
stepsToRad, radToSteps, radToStepsClosest, stepsToDeg, radToDeg,
stepsToRad, radToSteps, radToStepsAbsolute, stepsToDeg, radToDeg,
};
+2 -2
View File
@@ -277,8 +277,8 @@ async function executeMove(spot) {
return;
}
const newSteps1 = IK.radToStepsClosest(res.theta1, steps1);
const newSteps2 = IK.radToStepsClosest(res.theta2, steps2);
const newSteps1 = IK.radToStepsAbsolute(res.theta1, 1);
const newSteps2 = IK.radToStepsAbsolute(res.theta2, 2);
const delta1 = newSteps1 - steps1;
const delta2 = newSteps2 - steps2;
+2 -2
View File
@@ -275,8 +275,8 @@ async function executeMove(spot) {
return false;
}
const newSteps1 = IK.radToStepsClosest(res.theta1, steps1);
const newSteps2 = IK.radToStepsClosest(res.theta2, steps2);
const newSteps1 = IK.radToStepsAbsolute(res.theta1, 1);
const newSteps2 = IK.radToStepsAbsolute(res.theta2, 2);
const delta1 = newSteps1 - steps1;
const delta2 = newSteps2 - steps2;
+27 -3
View File
@@ -195,8 +195,8 @@ async function moveToXY(targetX, targetY) {
const { theta1, theta2 } = IK.solve(targetX, targetY);
const newSteps1 = IK.radToStepsClosest(theta1, steps1);
const newSteps2 = IK.radToStepsClosest(theta2, steps2);
const newSteps1 = IK.radToStepsAbsolute(theta1, 1);
const newSteps2 = IK.radToStepsAbsolute(theta2, 2);
const cmd = `X:${newSteps1},${newSteps2}`;
@@ -252,6 +252,9 @@ async function zeroMotor(motor) {
renderArmFromSteps();
console.log(`[sim] ${cmd}`);
UI.log(`[sim] ${cmd}`, 'info');
const warningEl = document.getElementById('home-warning');
if (warningEl) warningEl.style.display = localStorage.getItem('wiji_homed') === 'true' ? 'none' : 'block';
}
}
@@ -498,7 +501,10 @@ function buildHTML() {
<!-- Current position -->
<div class="card">
<div class="card-header"><span class="card-title">Current Position</span></div>
<div class="card-header">
<span class="card-title">Current Position</span>
<span id="home-warning" style="font-size:0.75rem;color:var(--accent-amber);font-weight:600;display:none;">⚠️ Not Homed</span>
</div>
<div class="pos-grid">
<div class="pos-box">
<div class="pos-val xy" id="curr-x">0.0</div>
@@ -622,6 +628,7 @@ function buildHTML() {
</div>
<div style="margin-top: 12px;">
<button class="btn btn-danger btn-full" id="sall-zero" style="padding: 10px; font-weight: bold; font-size: 0.9rem;">HOME BOTH MOTORS</button>
<button class="btn btn-warning btn-full" id="fake-home" style="padding: 8px; margin-top: 8px; font-weight: bold; font-size: 0.8rem; background-color: transparent; border: 1px solid var(--accent-amber); color: var(--accent-amber);">Reset Position</button>
</div>
</div>
@@ -736,6 +743,20 @@ const StepperTestSection = {
document.getElementById('s1-zero').addEventListener('click', () => zeroMotor(1));
document.getElementById('s2-zero').addEventListener('click', () => zeroMotor(2));
document.getElementById('sall-zero').addEventListener('click', () => zeroMotor('ALL'));
document.getElementById('fake-home').addEventListener('click', async () => {
localStorage.setItem('wiji_homed', 'false');
const warningEl = document.getElementById('home-warning');
if (warningEl) warningEl.style.display = 'block';
if (BLE.isConnected()) {
await BLE.write('ZEROALL').catch(e => UI.log(e.message, 'error'));
} else {
steps1 = IK.ARM.HOME_STEPS.m1;
steps2 = IK.ARM.HOME_STEPS.m2;
renderArmFromSteps();
console.log(`[sim] ZEROALL`);
UI.log(`[sim] ZEROALL (Reset Position)`, 'info');
}
});
// ── Quick-step buttons ────────────────────────────────────────
container.querySelectorAll('[data-motor][data-steps]').forEach(btn => {
@@ -796,6 +817,9 @@ const StepperTestSection = {
];
// ── Initial render ─────────────────────────────────────────────
const warningEl = document.getElementById('home-warning');
if (warningEl) warningEl.style.display = localStorage.getItem('wiji_homed') === 'true' ? 'none' : 'block';
renderArmFromSteps();
UI.log('Stepper Test ready — 5-bar parallel IK active.', 'success');
UI.log(`Arm: d=${IK.ARM.d}mm l1=${IK.ARM.l1}mm l2=${IK.ARM.l2}mm`, 'info');
+2 -2
View File
@@ -64,8 +64,8 @@ export default {
continue;
}
const newSteps1 = IK.radToStepsClosest(res.theta1, steps1);
const newSteps2 = IK.radToStepsClosest(res.theta2, steps2);
const newSteps1 = IK.radToStepsAbsolute(res.theta1, 1);
const newSteps2 = IK.radToStepsAbsolute(res.theta2, 2);
const cmd = `X:${newSteps1},${newSteps2}`;