
#include <stdio.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> /* close */
#include <netdb.h> /* gethostbyname */
#include <fcntl.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct in_addr IN_ADDR;
#endif

#ifdef WIN32
#include <conio.h>
#include <windows.h>
#endif
#include <math.h>
#include "remote_socket_client.h"
#include "gestion.h"
//link with ws2_32

/** INFORMATIONS SUR LES PERIPHERIQUES ET COMMANDES
---------------------------------------------------
'V' : Vitesse du moteur (0-50)
'D' : Angle de braquage des roues avant en 1/10° de degré (10 -> 1∞)
'T' : Azimut de la tourelle du télémètre en 1/10°
'R' : Lecture de l'Azimuth de la tourelle en 1/10°
'U' : Distance mesure par le télémètre en 1/100 de mètre (en cm)
'X' : Position absolue X en cm
'Y' : Position absolue Y en cm
'Z' : Position absolue Z en cm
'N' : Numéro de la voiture (en fonction de l'ordre de connection)
'E' : Lecture des evènements (cf Annexe 2)
'H' : Donne le temps de course actuel
'S' : Temps du tour précédent
'I' : Defini le nom du vehicule lettre par lettre
'M' : Mode de course :
8 bits de poids fort: 1 Attente, 2 course, 3 essais libres)
8 bits de poids faible : numero de piste
'C' : Informations sur le dernier capteur touché :
8 bits de poids faible : numéro du capteur
8 bits de poids fort : couleur ('R','J' ou 'V')
'K' : Téléportation de la voiture sur le troncon de piste N
(correspondant au capteur vert numero N).
Attention à n'utiliser que pour des tests, les scores sont invalidés !

Bit 0 : Point de passage Vert, remis à zéro lors de la lecture du périphérique 'C'
1 : Point de passage Jaune, remis à zéro lors de la lecture du périphérique 'C'
2 : Point de passage Rouge, remis à zéro lors de la lecture du périphérique 'C'
3-6 : non utilisés
7 : Point de passage course (vert), remis à zéro lors de la lecture du périphérique 'C'
8 : La piste à changé , remis à zéro lors de la lecture du périphérique 'M'
9 : Le mode de course a changé , remis à zéro lors de la lecture du périphérique 'M'
10 : Début de la course , remis à zéro au changement du mode de course.
11 : Le dernier point de passage est atteint la course est finie , remis à zéro au changement du mode de course.
12 : La voiture est sortie de la piste.
13 : Utilisation de la fonction de téléportation. Classement Invalidé. Remis à zero au changement de piste ou du mode de course.
14 : Faux départ -> destruction de la voiture , remise à zéro au changement du mode de course.
15 : Collision avec le sol, Remise à zéro au changement de piste.
**/


int fin_course=0;
/** Fonction appelée lorsqu'un évènement est recu **/
void f(int v){
    printf ("!!! Event:%04X !!!\n",v);

    /** Detection de la fin de la course **/
    fin_course = v & 0x0800;
}

void deconnection(int v){
    fin_course=1;
}

/** Fonction Principale **/
int main (int argc, char* argv[]){

    Remote_Client remote;
//Initialisation des peripheriques
    remote_init(local_periph,&remote);

/** Définition de la fonction de réception des évènements **/
    remote.event_callback = &f;
    remote.disconnect_callback= &deconnection;


/** Mettre Votre Nom **/
    remote_nom(&remote,"??");


/**Telemetre à gauche 70°**/
    remote_write(&remote,'T',700);

/**Laisse le temps à la voiture de se stabiliser**/
    Sleep(2000);

/**Demarre la voiture avec une vitesse de 20**/
    remote_write(&remote,'V',20);

	do{
    float dist;
    float err;
    float angle;

        /**Lecture de la distance au mur **/
	    dist=remote_read(&remote,'U');

        /**Convertion en metres**/
        dist=dist/100.0f;

	    /**Calcul de l'erreur de distance par rapport à 5.5m du mur**/
	    err=dist-5.5f;

	    /** Calcul de l'angle à appliquer avec une Correction proportionnelle de gain de 11 **/
	    angle = err*11.0f;

        /** Conversion de l'angle en 1/10° **/
        angle=angle*10;

	    /** Definition de l'angle de braquage des roues**/
	    remote_write(&remote,'D',angle);

        /**Tempo 100ms **/
	    Sleep(100);

        printf ("Distance :%3.2f Erreur: %3.2f Angle:%3.2f \n",dist,err,angle);


    /** Attente fin de course ou touche 'Q' appuyée**/
	}while(!fin_course && !touche_Q());

    printf ("Fin de la course\n");
	remote_close(&remote);

	return 0;
}
