Software, Firmware e Operação
Código-fonte, serviço Rust, ROS 2 e fluxo operacional do Kill Switch
Kill Switch - Software, Firmware e Operação
1. Firmware Serial (ESP32C3)
Código-Fonte: robot-button.cpp
void setup() {
pinMode(0, INPUT_PULLUP); // Botão no GPIO 0
Serial.begin(115200); // Inicializa serial a 115200 baud
}
void loop() {
int state = digitalRead(0);
// Lógica invertida: LOW = pressionado (1), HIGH = solto (0)
Serial.println(state == LOW ? "1" : "0");
delay(50); // Polling a cada 50ms
}Explicação da Lógica
| Linha | Explicação |
|---|---|
pinMode(0, INPUT_PULLUP) | Configura GPIO 0 como entrada com pull-up interno |
Serial.begin(115200) | Inicializa comunicação serial a 115200 baud |
digitalRead(0) | Lê o estado atual do GPIO 0 |
state == LOW ? "1" : "0" | Se LOW (pressionado), envia "1"; senão envia "0" |
delay(50) | Aguarda 50ms antes de próxima leitura (~20 Hz) |
Comportamento
- Lê o estado do GPIO 0 a cada 50ms
- Envia "1" quando o botão está pressionado (LOW)
- Envia "0" quando o botão está solto (HIGH)
- Taxa de transmissão: ~20 mensagens por segundo
A taxa de 50ms é um bom compromisso entre responsividade e economia de energia. Pode ser ajustada conforme necessário.
2. Serviço Rust no Robô
O serviço Rust roda no sistema do robô e é responsável por monitorar a porta serial e traduzir sinais para comandos ROS.
Responsabilidades Principais
- Monitoramento Serial: Escuta continuamente a porta tty AM0
- Lógica de Flip-Flop: Detecta transições de estado
- Publicação ROS: Envia comando para tópico
/cmd/dump - Logging Estruturado: Registra eventos com trace_id
Pseudocódigo
use serialport;
use ros2_client;
fn main() {
let mut serial_port = serialport::open("/dev/ttyAM0")
.expect("Failed to open serial port");
serial_port.set_baud_rate(115200)
.expect("Failed to set baud rate");
let mut ros_publisher = ros2_client::create_publisher("/cmd/dump");
let mut previous_state = '0';
loop {
let mut buffer = [0; 1];
match serial_port.read_exact(&mut buffer) {
Ok(_) => {
let current_byte = buffer[0] as char;
if current_byte == '1' && previous_state == '0' {
// Transição 0→1: Botão pressionado
log_event("KILL_SWITCH_ACTIVATED", "CRITICAL");
ros_publisher.publish(EmergencyStopCommand {
action: "DUMP".to_string(),
timestamp: get_current_time_utc(),
trace_id: generate_trace_id(),
});
} else if current_byte == '0' && previous_state == '1' {
// Transição 1→0: Botão liberado
log_event("KILL_SWITCH_RELEASED", "HIGH");
ros_publisher.publish(RecoverCommand {
action: "RECOVER_FROM_FALL".to_string(),
timestamp: get_current_time_utc(),
});
}
previous_state = current_byte;
}
Err(e) => {
log_event("SERIAL_READ_ERROR", "ERROR");
eprintln!("Error reading from serial: {}", e);
}
}
}
}Estrutura de Eventos Publicados
{
"timestamp": "2025-12-10T16:30:45.123Z",
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"event": "KILL_SWITCH_ACTIVATED",
"severity": "CRITICAL",
"source": "SERIAL",
"action": "DUMP",
"ack_time_ms": 245
}{
"timestamp": "2025-12-10T16:30:50.456Z",
"trace_id": "550e8400-e29b-41d4-a716-446655440001",
"event": "KILL_SWITCH_RELEASED",
"severity": "HIGH",
"source": "SERIAL",
"action": "RECOVER_FROM_FALL"
}3. Integração com ROS 2
O serviço Rust publica em dois tópicos ROS 2:
| Tópico | Mensagem | Frequência | Descrição |
|---|---|---|---|
/cmd/dump | EmergencyStopCommand | Sob demanda | Ativa Dump Mode |
/cmd/recover | RecoverCommand | Sob demanda | Ativa Recover from Fall |
Subscribers ROS 2
O robot controller (outro nó ROS 2) se inscreve nesses tópicos e executa as ações correspondentes:
void estop_callback(const EmergencyStopCommand& msg) {
// Desliga todos os motores
for (auto& motor : motors) {
motor.set_torque(0);
}
robot_state = DUMP_MODE;
log_event("DUMP_MODE_ACTIVATED");
}
void recover_callback(const RecoverCommand& msg) {
// Inicia sequência de recuperação
robot_state = RECOVERING;
execute_recovery_sequence();
}4. Fluxo Operacional
Sequência de Acionamento
A sequência de acionamento segue 8 etapas principais:
| Etapa | Ação | Tempo | Responsável | Status |
|---|---|---|---|---|
| 1 | Operador pressiona botão | T+0ms | Operador | Crítica |
| 2 | ESP32C3 detecta transição GPIO | T+0-50ms | Microcontrolador | Crítica |
| 3 | Transmissão Serial iniciada | T+50-100ms | ESP32C3 | Crítica |
| 4 | Serviço Rust recebe sinal serial | T+100-150ms | Rust Service | Crítica |
| 5 | ROS Topic /cmd/dump publicado | T+150-200ms | ROS 2 | Crítica |
| 6 | Motor controllers recebem comando | T+200-300ms | Robot Hardware | Crítica |
| 7 | Torque cortado (Dump Mode ativado) | T+300-500ms | Robot Motors | Crítica |
| 8 | Dump Mode confirmado | T+500-1000ms | Robot | Crítica |
SLA: ACK ≤ 1 segundo (RF-KS-006)
Diagrama de Sequência
Playbooks de Resposta
Playbook KS-001: Acionamento Normal
Procedimento Operacional Completo
Gatilho: Operador detecta situação de risco iminente
Passos:
- Operador pressiona o botão de emergência (cogumelo amarelo)
- Sistema detecta pressão e envia sinal via Serial
- Robô entra em Dump Mode (motores desligados)
- Operador aguarda confirmação visual (robô imóvel)
- Operador libera o botão após situação controlada
- Robô entra em modo Recover from Fall (sequência automática)
- Operador aguarda recuperação completa
- Revisar logs de telemetria
- Verificar se houve danos ao robô
- Atualizar relatório de incidentes
Playbook KS-002: Falha de Comunicação Serial
Recuperação de Falha Serial
Gatilho: Serviço Rust não recebe sinal serial por > 5 segundos
Passos:
- Sistema detecta perda de comunicação serial
- Ativar failsafe mecânico (se disponível)
- Registrar evento importante no SIEM com trace_id
- Notificar Analista 4 via ChatOps em < 60 segundos
- Investigar causa raiz (cabo solto, driver serial, etc.)
- Restaurar conexão e validar funcionamento
- Executar teste de carga Kill Switch para confirmar
SLA de Resposta: 5 minutos para mitigação
Responsável: Analista 4 (SIEM-ROB)
Investigação:
- Verificar logs de erro do ESP32C3
- Testar conexão USB-C
- Validar baud rate e configuração serial
Playbook KS-003: Acionamento Indevido
Falso Positivo
Gatilho: Botão acionado sem situação de emergência
Passos:
- Registrar timestamp e contexto do acionamento
- Verificar logs de telemetria do robô (bateria, sensores, etc.)
- Investigar se houve contato acidental ou falha de hardware
- Se falso positivo confirmado, documentar em post-mortem
- Avaliar necessidade de proteção física adicional (capa, etc.)
- Atualizar guidelines operacionais se necessário
- Comunicar ao operador sobre o incidente
SLA de Resposta: 2 minutos para contenção
Responsável: Operador + Analista 4
Análise:
- Taxa de falsos positivos por hora
- Padrão de acionamentos (acidental vs. intencional)
- Necessidade de ajuste de sensibilidade
Resumo
O software do Kill Switch é composto por firmware simples no ESP32C3, um serviço Rust robusto que monitora a porta serial, e integração com ROS 2 para acionamento de Dump Mode. O fluxo operacional garante resposta em menos de 1 segundo com procedimentos bem documentados para diferentes cenários.