feat(web): migra Movimento com homem-morto e trava de hardware
- Controle: opt-in de movimento fisico, botao "segure para mover" (mouse, toque e teclado), sliders das articulacoes tambem so movem enquanto pressionados; velocidade e interpolacao ficam no servidor - sequencias prontas e posturas salvas: previa so na tela ou execucao segurando o botao ate o fim; soltar interrompe na hora - posturas com nome inline (sem prompt), exclusao confirmada inline, exportar/importar; posturas aparecem na paleta (Ctrl+K) - Calibracao: testes de fim de curso por canal, marcar limites e tabela editavel com validacao antes de salvar - Diagnostico (antigo Servos): ao vivo limitado a 10/s, bloqueado quando o braco esta com os motores - desenho esquematico do braco em SVG com previa animada - servidor: evento 'motores' tambem ao ligar canais; renovar no alvo devolve movendo=false para a sequencia avancar - aba escondida ou E-Stop soltam o braco e desativam o movimento Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -88,6 +88,15 @@ class ControleServos:
|
||||
with self.lock:
|
||||
return dict(disponivel=self.hw is not None, erro=self.error, ativos=sorted(self.active),
|
||||
dono=self.dono, travado=self.travado)
|
||||
def ligar(self, canais_prazos):
|
||||
"""Registra canais energizados até o prazo; avisa o painel quando algum canal liga."""
|
||||
with self.lock:
|
||||
novos = False
|
||||
for canal, prazo in canais_prazos:
|
||||
novos = novos or canal not in self.active
|
||||
self.active[canal] = prazo
|
||||
if novos:
|
||||
self.publicar('motores', self.motores())
|
||||
def reservar(self, nome):
|
||||
"""Braço e diagnóstico usam o mesmo PCA9685 com limites diferentes: um de cada vez."""
|
||||
with self.lock:
|
||||
@@ -110,7 +119,7 @@ class ControleServos:
|
||||
if self.hw is None: raise OSError('PCA9685 indisponível neste servidor')
|
||||
self.reservar('diagnostico')
|
||||
self.hw.pulse(row['canal'], pulse)
|
||||
self.active[row['canal']] = time.monotonic() + 2
|
||||
self.ligar([(row['canal'], time.monotonic() + 2)])
|
||||
return self.status()
|
||||
def expire(self, now):
|
||||
with self.lock:
|
||||
|
||||
Reference in New Issue
Block a user