feat(pose_3d): save/load/delete named poses

This commit is contained in:
Adriano Dal Pastro committed 2026-05-21 16:03:38 +02:00
1 parent a81fc9acf9
commit bb6796bfe3
1 file changed
+79
+79
View File
@@ -496,6 +496,84 @@ function bindJogAutoApply() {
});
}
// ----- named poses -----
async function onSavePose() {
const name = ($('p3PoseName').value || '').trim();
if (!name) { alert('Inserisci un nome'); return; }
if (!/^[A-Za-z0-9_-]{1,40}$/.test(name)) {
alert('Nome: solo [A-Za-z0-9_-], 1-40 caratteri');
return;
}
const side = state.active_side;
const pose = state.target[side] || state.current[side];
if (!pose) { alert('Nessuna posa da salvare'); return; }
if (state.saved_poses[name]) {
if (!confirm(`Posa "${name}" esiste già — sovrascrivere?`)) return;
}
try {
await jsonFetch(`/api/pose_3d/poses/${encodeURIComponent(name)}`, {
method: 'PUT', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
side, position: pose.position, quaternion: pose.quaternion,
}),
});
$('p3PoseName').value = '';
await pollState(); // refresh dropdown
$('p3PoseSelect').value = name;
} catch (e) {
showError(`Salvataggio fallito: ${e.message}`);
}
}
async function onGoPose() {
const name = $('p3PoseSelect').value;
if (!name) { alert('Seleziona una posa dal dropdown'); return; }
if (state.mode === 'jog') {
if (!confirm(`Eseguire posa "${name}" SUL ROBOT REALE? (Jog mode)`)) return;
}
const dry_run = (state.mode === 'editor');
clearError();
try {
const res = await jsonFetch(
`/api/pose_3d/poses/${encodeURIComponent(name)}/go`,
{
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ dry_run, precise: state.precise }),
},
);
const r = res.result || {};
if (r.reached_target === false || r.stalled === true) {
showError(`Vai a "${name}": residual ${(r.position_error_mm||0).toFixed(1)} mm`);
} else {
$('p3Status').textContent = `✓ Posa "${name}" applicata` +
(dry_run ? ' (simulato)' : '');
$('p3Status').className = 'p3-status ok';
}
} catch (e) {
showError(e.message);
}
}
async function onDeletePose() {
const name = $('p3PoseSelect').value;
if (!name) { alert('Seleziona una posa dal dropdown'); return; }
if (!confirm(`Cancellare definitivamente la posa "${name}"?`)) return;
try {
await jsonFetch(`/api/pose_3d/poses/${encodeURIComponent(name)}`, {
method: 'DELETE',
});
await pollState();
} catch (e) {
showError(e.message);
}
}
function bindPoseButtons() {
$('p3PoseSaveBtn').addEventListener('click', onSavePose);
$('p3PoseGoBtn').addEventListener('click', onGoPose);
$('p3PoseDelBtn').addEventListener('click', onDeletePose);
}
// ----- init triggered on first activation -----
let inited = false;
function ensureInit() {
@@ -511,6 +589,7 @@ function ensureInit() {
bindModeControls();
bindPreciseControl();
bindJogAutoApply();
bindPoseButtons();
pollState();
pollTimer = setInterval(pollState, POLL_MS);
}