Progetto Firefly Sonar | LINK AL PROGETTO

Requisiti

Realizzazione di un simulatore di un sistema costituito da 3 lucciole e dotato di un Sonar. Il comportamento del sistema è dinamico:
  • Quando il sonar rileva un ostacolo a una distanza minore di una soglia prefissata DMIN, le lucciole devono lampeggiare in modo sincronizzato.
  • Quando la distanza dell’ostacolo (ri)supera DMIN, le lucciole tornano a lampeggiare in modo random (asincrono).
È richiesta la definizione di un modello QAK che simuli accuratamente l'alternanza tra le due modalità.

Analisi dei Requisiti

Analisi del Problema

Architettura del Sistema Estesa

Il sistema mantiene la separazione in due contesti (ctxfirefly e ctxgrid), ma introduce una nuova fonte di dati: l'evento globale sonar_data : distance(D), generato da un componente hardware reale o da un attore mock (sonarsimulator).

La necessità di alternare tra modalità random e sincrona impone un cambiamento radicale alla logica di controllo. Il Coordinatore non può più limitarsi a emettere un segnale di clock fisso. Deve diventare un coordinatore capace di:

Limite QAk e Pattern Architetturale: Nel linguaggio QAk, non è possibile gestire contemporaneamente una transizione temporale (whenTime) e una reattiva (whenEvent) nello stesso blocco di stato. Per risolvere questo conflitto, è stato introdotto il pattern dello "Stato Vuoto" (work), che funge da snodo non bloccante per l'attore.

Progetto

Il Coordinatore "Intelligente"

Il coordinator gestisce una variabile di stato IsSyncActive. Utilizza uno stato di attesa attiva (work) per alternare la gestione del timer (emissione del clock) e l'arrivo asincrono dei dati del sonar.

State work { // Punto di snodo non bloccante }
Transition t0 
    whenTime 1500        -> emitSyncSignal
    whenEvent sonar_data -> handleSonar

State handleSonar {
    onMsg( sonar_data : distance(D) ){
        [# var Distance = payloadArg(0).toInt() #]
        if [# Distance < DMIN #] {
            if [# !IsSyncActive #] {
                emit startSync : startSync(1)
                [# IsSyncActive = true #]
            }
        } else {
            // Logica inversa per stopSync
        }
    }
}
Goto work

Firefly: Attori Ibridi e Reversibili

Le lucciole ora alternano un ciclo interno autonomo (tramite delay randomici) a uno stato reattivo in cui attendono il segnale dal coordinatore.

// --- MODALITÀ ASINCRONA ---
State randomFlashing {
    // Lampeggio con timer interno casuale
}
Transition t0 
    whenTime 50          -> randomFlashing
    whenEvent startSync  -> wait_sync

// --- MODALITÀ SINCRONA ---
State wait_sync {
    // In attesa del segnale di clock globale
}
Transition t1
    whenEvent sync      -> flash
    whenEvent stopSync  -> randomFlashing

Vantaggi della soluzione