102 lines
3.5 KiB
TypeScript
102 lines
3.5 KiB
TypeScript
import { Router } from 'express';
|
|
import { raspiService } from '../services/raspi.service.js';
|
|
|
|
const router = Router();
|
|
|
|
const commandMap = [
|
|
// Catalan forward
|
|
{ words: ['endavant', 'avança'], action: 'forward' },
|
|
// Catalan backward
|
|
{ words: ['atras', 'enrere', 'atras'], action: 'backward' },
|
|
// Catalan left
|
|
{ words: ['esquerra', 'esquerre', 'stoppa'], action: 'left' },
|
|
// Catalan right
|
|
{ words: ['dreta', 'destre'], action: 'right' },
|
|
// Stop
|
|
{ words: ['atura', 'atura', 'pare', 'stop', 'parada', 'aturar'], action: 'stop' },
|
|
// Pick up / grab
|
|
{ words: ['recull', 'pega', 'pilla', 'agafa'], action: 'pick' },
|
|
// Eject / throw
|
|
{ words: ['llança', 'tira', 'expulsa', ' llença'], action: 'eject' },
|
|
|
|
// Spanish forward
|
|
{ words: ['adelante'], action: 'forward' },
|
|
// Spanish backward
|
|
{ words: ['atras', 'atrás', 'reversa', 'al tras'], action: 'backward' },
|
|
// Spanish left
|
|
{ words: ['izquierda', 'izq'], action: 'left' },
|
|
// Spanish right
|
|
{ words: ['derecha', 'der'], action: 'right' },
|
|
// Spanish stop
|
|
{ words: ['para', 'stop', 'pare', 'deten', 'frena', 'alto'], action: 'stop' },
|
|
];
|
|
|
|
function resolveCommand(text: string) {
|
|
const lower = text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
for (const entry of commandMap) {
|
|
for (const word of entry.words) {
|
|
const normalizedWord = word.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
if (lower.includes(normalizedWord)) {
|
|
return entry.action;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
router.post('/text', async (req, res) => {
|
|
const { text } = req.body;
|
|
if (!text || typeof text !== 'string') {
|
|
return res.status(400).json({ error: 'Text is required' });
|
|
}
|
|
|
|
const action = resolveCommand(text);
|
|
if (!action) {
|
|
return res.json({ recognized: text.trim(), action: null, message: 'No motor command matched. Use: endavant, atras, esquerra, dreta, atura, recull, llança' });
|
|
}
|
|
|
|
try {
|
|
switch (action) {
|
|
case 'forward': {
|
|
const result = await raspiService.motorStepForward();
|
|
return res.json({ recognized: text.trim(), action: 'forward', result });
|
|
}
|
|
case 'backward': {
|
|
const result = await raspiService.motorStepBackward();
|
|
return res.json({ recognized: text.trim(), action: 'backward', result });
|
|
}
|
|
case 'left': {
|
|
await raspiService.motorStepForward();
|
|
await new Promise(r => setTimeout(r, 600));
|
|
await raspiService.motorStop();
|
|
return res.json({ recognized: text.trim(), action: 'turn-left', result: { status: 'turned left' } });
|
|
}
|
|
case 'right': {
|
|
await raspiService.motorStepBackward();
|
|
await new Promise(r => setTimeout(r, 600));
|
|
await raspiService.motorStop();
|
|
return res.json({ recognized: text.trim(), action: 'turn-right', result: { status: 'turned right' } });
|
|
}
|
|
case 'stop': {
|
|
const result = await raspiService.motorStop();
|
|
return res.json({ recognized: text.trim(), action: 'stop', result });
|
|
}
|
|
case 'pick': {
|
|
return res.json({ recognized: text.trim(), action: 'pick', message: 'Pick command received' });
|
|
}
|
|
case 'eject': {
|
|
return res.json({ recognized: text.trim(), action: 'eject', message: 'Eject command received' });
|
|
}
|
|
}
|
|
} catch (err: unknown) {
|
|
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
return res.status(500).json({
|
|
recognized: text.trim(),
|
|
action,
|
|
error: `Command execution failed: ${message}`,
|
|
});
|
|
}
|
|
});
|
|
|
|
export default router;
|