# FARM EXERGAME 
### Exergame per l'analisi e l'allenamento della destrezza manuale dedicato a soggetti con Malattia di Parkinson

## Codici sorgente principali
> main.py

main script per effettuare hand tracking, creazione server UDP per invio dati tracking al client Unity, hand calibration e definizione della ref_distance (media).
Comunicazione con il json_config.json. 
All'interno di questo script è presente la possibilità di installare automaticamente i package richiesti. 

> ChangeSceneWithButton.cs

Consente il passaggio tra le varie scene Unity, accessibili dalla scena mainMenu. Contiene al suo interno una funzione per la gestione dei suoni di gioco e varie funzioni per la creazione del database, delle cartelle utente e le relative calibrazioni.

> STRUTTURA DATABASE

Il database, se non esiste, viene creato automaticamente con la prima calibrazione effettuata ed il percorso è ".\Exergame\Assets\DATABASE" dall'editor, altrimenti nella build è ".\Exergame_Data\DATABASE". 

La struttura all'interno del database è:
 - DATABASE
	 - ID UTENTE 
		 - CALIBRAZIONE_TIMESTAMP
			 - json_calibration.json
			 - Report_0.json
			 - plotSoglie.png (grafici ottenuti dalla calibrazione)
			 - jsonListSoglie.json (liste relative ai dati di calibrazione per ogni gesture)
			 
> json_config

File di configurazione unico

	{
	"webcamNum": 0,
	"serverIsActive": "false",
	"calibr": "false",
	"isActiveCalibration": "false",
	"timerCalibration": "8",
	"jsonCalibrationPath": "C:/Users/sofia/Desktop/GitHub/TESI/Exergame/Assets\\DATABASE\\sofia\\calibr_030324_13_05_46"
	}

 - webcamNum: inserimento manuale della sorgente video da utilizzare (int)
 - serverIsActive: flag che consente di controllare il corretto funzionamento del server python (bool)
 - calibr: flag che indica se si è in fase di calibrazione (bool)
 - isActiveCalibration: flag che controlla se già presente una calibrazione in corso (necessario per la determinazione di ref_distance e per gestione degli input da tastiera: space) (bool)
 - timerCalibration: intervallo di tempo inserito manualmente, che definisce la durata di ogni calibrazione gesture (tra 4 e 14 secondi)  (int)
 - jsonCalibrationPath: absolute path, creato automaticamente con la creazione della cartella relativa ad una calibrazione utente nel database. Rimanda all'ultima calibrazione effettuata. (string)

> json.calibration.json

File di calibrazione, creato per ogni calibrazione svolta, nella cartella utente dedicata

	{
	"handType": " 'R'",
	"refDistance": 72.0,
	"open": 2.62658548,
	"tap": 0.687433839,
	"PSDx": 111.369347,
	"PSSx": 54.30366
	}

 - handType: indica tipologia di mano (DESTRA 'R', SINISTRA 'L') usata in fase di calibrazione. Necessario per posizionare gli oggetti all'interno della scena in base alla mano usata (string)
 - refDistance: media dei valori ottenuti di ref_distance, calcolati su un intervallo di tempo definito da timerCalibration (float)
 - open: soglia di calibrazione definita per apertura-chiusura mano
 - tap: soglia di calibrazione definita per finger tapping
 - PSDx: soglia di calibrazione definita per la rotazione della mano in senso orario 
 - PSSx: soglia di calibrazione definita per la rotazione della mano in senso antiorario
 - (FE da aggiungere, in questa versione è solo commentata)


## Calibration

> handCalibration.cs

Hand tracking per la fase di calibrazione (simile ad HandTracking.cs ed HandTrackingTrain.cs). 
Script per effettuare la calibrazione e rilevare le dimensioni mano utente. 
Contiene funzioni per il calcolo ed il salvataggio delle soglie di calibrazione individuate (in json_calibration.json, disponibile nel database per ogni utente, per ogni calibrazione effettuata)

> cameraManagerCalibration.cs

Gestione della visuale della Main Camera nella fase di calibrazione e lavora con handCalibration.cs per la determinazione le soglie. 

> plotSoglieJson.py

Script per la creazione dei grafici di calibrazione, richiamato automaticamente nella funzione handCalibration.cs

## Exergame

> HandTracking.cs

Script per conversione e gestione del tracking in Unity ricevuto da server python. 
Contiene la funzione per il calcolo dell'angolo di intra-extra rotazione della mano ed eventualmente funzione per il calcolo dell'angolo di flesso-estensione (commentato e non inserito nella versione attuale del sistema)

> gestureRecognizer.cs

Script per il riconoscimento delle gesture effettuate (apertura chiusura mano, finger tapping) durante il gameplay, tramite confronto con le soglie di calibrazione (salvate in json_calibration.json nel database, per ogni calibrazione effettuata da ogni utente)

> cameraManager.cs

Approccio modulare dell'exergame. Gestione della visuale della Main Camera nella fase di gioco. Consente di effettuare più loop di gioco, divisi in:

 - cameraPos = 0: inizio del gioco, lista ordine da effettuare 
 - cameraPos = 1: apertura/chiusura mano --> presa delle uova
 - cameraPos = 2: intra-extra rotazione della mano --> riempimento bottiglie latte
 - cameraPos = 3: finger tapping --> presa delle ciliegie
 - cameraPos = 4: transizione tramite input da tastiera: space. Possibile sviluppo: inserimento di un ulteriore minigioco con la flesso-estensione (FE, presente nei codici in parte e commentato)
 - cameraPos = 5: finger tapping continuo --> spostamento macchina sulla mappa

Si ricomincia il loop di gioco ed in cameraPos = 0 si visualizza la tabella di riepilogo dell'ordine effettuato + nuove richieste di gioco. 

> grabObject.cs | updatePosition.cs | basketCounter.cs

Questi script combinati, consentono di determinare se avviene la collisione tra i landmark della mano e l'oggetto da afferrare/toccare e gestiscono l'aggiornamento della posizione dell'oggetto afferrato (spostamento oggetto nel cestino, rotazione della valvola).

> spawnerObject.cs | respawnEgg.cs | respawnCherry.cs

Gestiscono lo spawn ed il respawn degli oggetti afferrati, dunque, con cui si deve avere una interazione per giocare. 

> scoreScript.cs

Calcolo e gestione punteggi di gioco e salvataggio delle performance di gioco, tempi impiegati per ogni task, errori commessi nel file Report_numSessioneGioco.json (ad esempio Report_0.json), disponibile nel database, presente per ogni sessione di gioco svolta, per ogni calibrazione effettuata da ogni utente.

> mapDrawing.cs | mapChecker.cs

Gestione task relativo alla mappa (cameraPos=5). Controllo se il percorso della mappa sia stato effettuato correttamente, tramite box collider inseriti lungo il percorso. 

## Training
Stessi codici utilizzati per l'EXERGAME, ma riadattati alle esigenze del training: senza conteggio errori e senza punteggi. 
  
# Guida all'utilizzo del sistema
#### Percorsi file 
I seguenti file, main.py | json_config.json | plotSoglieJson.py, sono presenti in ".\Exergame\Assets". 
Tutti gli altri script sono presenti in ".\Assets\Script\" in calibrationScript, exergameScript, trainingScript. 

#### Build exergame
Quando si effettua una build dell'exergame, è necessario copiare poi manualmente i seguenti file nello stesso percorso indicato sopra: main.py | json_config.json | plotSoglieJson.py.
Per il corretto funzionamento della build assicurarsi di eseguire la build da un absolute path che non contiene spazi. 

#### Note per il corretto funzionamento 
Nel file json_config, è necessario che la variabile serverIsActive sia false, prima di eseguire l'applicazione. Durante l'esecuzione dell'exergame, si setterà automaticamente a true, ma assicurarsi che sia tornata a false automaticamente in caso di interruzioni/problemi particolari. 
Definire inoltre il tipo di webcam da utilizzare (modificare parametro se presenti più sorgerti video e scegliere quella desiderata) e il tempo di calibrazione per la determinazione delle soglie. 

#### Requirements
Versione Python: 3.11

Inoltre, per installare i pacchetti dell'exergame in automatico, eseguire prima lo script main.py a parte, altrimenti installare manualmente: 
 - cvzone: v 1.6
 - keyboard: v 0.13.5
 - numpy:  v 1.26.4

Successivamente eseguire la build o il progetto Unity. 
