// Emanuele Ercoli 702270, emanuele.ercoli@studenti.unimi.it
// Progetto per il corso di Sistemi Intelligenti A.A. 2006/2007
//
// Implementazione per il robot AIBO di un n-armed bandit problem.
// Il goal è dato dal raggiungimento delle coccole, mentre le azioni disponibili sono FERMO,CAMMINO.
//

#ifndef AIBOCoccole_H_DEFINED
#define AIBOCoccole_H_DEFINED
#include <OPENR/OObject.h>
#include <OPENR/OSubject.h>
#include <OPENR/OObserver.h>
#include <OPENR/RCRegion.h>
#include "def.h"
#include "../Motion/MotionInterface.h"  //contiene le costanti di gestione del movimento di motion

class AIBOCoccole : public OObject
{
  public:

    AIBOCoccole();  //costruttore di default

    virtual ~AIBOCoccole(){};     //distruttore di default

    OSubject* subject[numOfSubject];            //array dei subject dell'oggetto

    OObserver* observer[numOfObserver];         //array degli observer dell'oggetto

    virtual OStatus DoInit(const OSystemEvent& event);  //inizializza le strutture di comunicazione inter-object

    virtual OStatus DoStart(const OSystemEvent& event); //attiva la comunicazione inter-object

    virtual OStatus DoStop(const OSystemEvent& event);  //disattiva la comunicazione inter-object

    virtual OStatus DoDestroy(const OSystemEvent& event);           //distrugge le strutture di comunicazione inter-object

    void TimerMind(void *msg);      //timer del ragionamento

    void TimerSensor(void *msg);    //timer polling dal sensore coccole

    void TimerDist(void *msg);    //timer polling dal sensore della distanza

  private:

    static const slongword LIMITE = 300000;     //distanza minima per essere in pericolo collisione ostacolo (espresso in micrometri)

    static const short N_AZIONI = 2;    //numero delle azioni
    
    static const double ALFA = 0.1;   //step size fissato per problema non stazionario
    
    static const double EPSILON = 0.1;       //epsilon per la generazione della politica epsilon-greedy

    static const short vel = 50;	//velocità in camminamento dell'AIBO in mm/s 

    long reward; //reward

    double Q[N_AZIONI];                        //valori delle azioni

    enum
    {
     FERMO,                               //Q[0]
     CAMMINO,                             //Q[1]
    } azione;  //rappresenta le azioni disponibili

    OPrimitiveID sensorIDBack;    //oggetto per la gestione della primitiva del sensore di tatto posteriore
    
    OSensorValue sensorValueBack; //contiene il valore del sensore della schiena

    OPrimitiveID sensorIDDist;    //oggetto per la gestione della primitiva del sensore per la distanza
    
    OSensorValue sensorValueDist; //contiene il valore del sensore della distanza

    void controlloAzione(void);            //funzione che gestisce le azioni
};

#endif
