La Commessa CoSMO -- Risorse per la fase di implementazione





AVVISO IMPORTANTE: È disponibile una nuova versione dell'utility CosmoRD, più robusta rispetto ai problemi di rete transitori e con dei colori più visibili per le Arpe e il Bardo. Potete scaricarla all'URL http://islp.di.unipi.it/~gervasi/CosmoRD.jar. Come al solito, usate il comando appropriato per il vostro browser per scaricare l'eseguibile Java. Rimane la compatibilità totale con la vecchia versione di CosmoRD.

La fase di implementazione  prevede l'uso di un simulatore distribuito che riproduce l'ambiente del campo sperimentale di raccolta dei minerali allestito dalla CoSMO. Tutti i gruppi partecipanti  concorrono, in contemporanea, a raccogliere la manganese all'interno dello stesso campo.

La comunicazione fra il software delle ARPA e il simulatore avviene attraverso connessioni di rete (socket), tramite lo scambio di comandi (e relative risposte) testuali. La  situazione sul campo di test viene esaminate in forma grafica tramite il programma  CosmoRD.

CosmoRD

L'archivio jar contenente il programma può essere scaricato qui (attenzione: alcuni browser potrebbero tentare di eseguire il programma in linea anziché scaricarlo sul disco - usate i comandi appropriati per il vostro browser). Il tool viene eseguito tramite il comando

java -jar CosmoRD.jar login password [server]

in cui login e password sono gli stessi usati per accedere a Circe, mentre server, che è opzionale, indica la macchina su cui è in esecuzione il server CoSMO. Se non indicato, server si riferisce per default a localhost.

GUI di CosmoRD
La finestra di CosmoRD presenta un'ampia area dedicata alla visualizzazione del fondo oceanico e alcuni controlli in basso. Nell'area dedicata alla mappa, i puntini rossi rappresentano noduli di manganese, mentre il BARDO e le ARPE di un gruppo sono rappresentati da punti di altro colore (che dipende dal gruppo). In particolare, il BARDO appare come un quadratino etichettato con il nome del gruppo, mentre le ARPE appaiono come puntini piu' piccoli, numerati da 1 a 5.
Ciascun gruppo "vede" soltanto il proprio BARDO e le proprie ARPE, ma altri gruppi possono essere in azione contemporaneamente: può dunque accadere che alcuni noduli "scompaiano" improvvisamente dal fondo marino.

In basso, da sinistra, troviamo un testo che descrive lo stato dell'applicazione e due indicatori di livello. Il primo indica il numero di gruppi collegati in un certo momento, mentre il secondo presenta un'indicazione del livello di carico della CPU sulla macchina locale.

Infine, la casella "Aggiorna" consente di attivare o sospendere l'aggiornamento della visualizzazione: quando "Aggiorna" non è attivo, il traffico sulla rete viene ridotto in maniera sostanziale, migliorando le condizioni di lavoro per tutti.


Suggerimenti per la codifica in Java

Le operazioni di gestione dei socket in Java possono essere semplificate adottando alcuni semplici accorgimenti. In primo luogo, occorre aprire un socket e creare due Stream (uno per l'input, uno per l'output) attraverso i quali realizzare le comunicazioni con il server. Queste operazioni possono essere fatte con il codice seguente, inserito nel metodo main(), in un costruttore, o comunque eseguito durante la fase di inizializzazione della vostra Arpa:

import java.net.*;
import java.io.*;
/* ... */
Socket sock=null;
PrintWriter out;
BufferedReader in;
/* ... */
try {
    sock = new Socket(server, 7890);
    sock.setSoTimeout(10000);
    out = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()),true);
    in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
    /* qui chiamate il corpo della vostra Arpa */
} catch (IOException e) {
    System.err.println(e);
} finally {
    if (sock!=null)
        sock.close();
}


Dopo questa inizializzazione, si possono scrivere i comandi (POSITION, DOCK, ecc.) su out, e leggere le risposte del server (OK, FAIL, ecc.) da in. Un buon metodo per semplificare le interazioni con il server consiste nel definire una funzione di utilità che si occupi di inviare un comando e leggere la relativa risposta, come la seguente:

public String exec(String cmd) throws IOException
{
    // per il debug: System.err.println("EXEC: "+cmd);
    out.println(cmd);
    String res = in.readLine();
    // per il debug: System.err.println("RES: "+res);
    return res;
}


in questo modo,  per eseguire un comando è sufficiente invocare il metodo exec():

res = exec("3 BATT");

(si veda avanti per l'esatta sintassi dei comandi e delle risposte).


Struttura dei comandi

Rispetto a quanto riportato  nell'enunciato del problema, il simulatore introduce una piccola variazione: allo scopo di  preservare le risorse di sistema, il simulatore usa un socket per ogni gruppo, anziché uno per ARPA come sarebbe stato più appropriato. Per distinguere a quale arpa fa riferimento un comando, si rende necessario premettere un codice numerico (0-4) ad ogni comando. Così, il comando

3 BATT
ha l'effetto di restituire lo stato di carica della batteria della vostra quarta Arpa. Le risposte ai comandi hanno sempre il formato

OK eventuali risultati

oppure

FAIL ragione del fallimento

con l'eccezione del comando RECV, che può restituire anche NULL per indicare che non ci sono messaggi pendenti.


Autenticazione, login e logout

Ogni sessione con il simulatore deve cominciare con un comando di autenticazione, che ha la forma

0 LOGIN login password

in cui login e password sono, come al solito, quelli usati per accedere a Circe. È inoltre utile chiudere "ordinatamente" le sessioni, con il comando
0 LOGOUT
Una sessione viene comunque chiusa anche in altri casi:
  1. quando tutte le ARPE esauriscono la batteria;
  2. quando il BARDO raggiunge la sua capacità di carico massima;
  3. quando si verifica un errore di rete;
  4. quando trascorrono 15 secondi senza che sia ricevuto alcun comando.
Se non si usa il comando LOGOUT, può dunque capitare di dover attendere l'esaurimento delle batterie prima che sia possibile riconnettersi al simulatore.


Sperimentazione e debugging

Per sperimentare il funzionamento e la sintassi dei comandi, può essere utile connettersi al simulatore in modo testo usando il comando telnet:

telnet server 7890

una volta aperta la connessione, potete digitare i comandi che inviereste normalmente (iniziando da "0 LOGIN ..."), e osservare i risultati. Per uscire da telnet, usate la sequenza CTRL+], Enter, "quit", Enter.