Skip to content
strategiev3.cpp 16 KiB
Newer Older
#include "strategiev3.h"
#include "strategieV2.h"
#include "actionGoTo.h"
#include "leds.h"
#include "odometrie.h"
#include "asservissement.h"
#include "dijkstra.h"
#include "etape.h"

#ifndef ROBOTHW
    #include <QDebug>
#endif
//#include <iostream>
Arnaud Cadot's avatar
Arnaud Cadot committed
StrategieV3::StrategieV3(bool /*isYellow*/) : MediumLevelAction()
{
    this->avoiding = false;
    this->etapeEnCours = 0;
    this->statusStrat=1;
    this->enTrainEviterReculant = false;
    this->enTrainEviterAvancant = false;
    this->millisecondesRestantes = 90 * 1000;

#ifndef ROBOTHW
    colorLiaisonsEtapes = QColor("blue");
    colorEtapeGoal = QColor("red");
    colorEtapesIntermediaires = QColor("yellow");
    colorEtapes = QColor("orange");
    colorTexteEtapes = QColor("black");
    colorEtapesRobotVu = QColor("black");
#endif
    //this->actionEtape[this->etapeEnCours]->reset();
    //this->actionGoto[this->etapeEnCours].reset();
Arnaud Cadot's avatar
Arnaud Cadot committed

Arnaud Cadot's avatar
Arnaud Cadot committed
    tableauEtapesTotal[this->etapeEnCours]->reset();

    //Si on est en train d'éviter, on revient à l'étape précédente, et on marque l'étape comme à éviter
    if(this->avoiding)
    {
        qDebug() << "En train d'eviter";
Arnaud Cadot's avatar
Arnaud Cadot committed
        this->tableauEtapesTotal[this->etapeEnCours]->robotVu();
        //this->tableauEtapesTotal[this->etapeEnCours]->setState(-2);
        this->tableauEtapesTotal[etapeEnCours]->getParent()->setParent(this->tableauEtapesTotal[this->etapeEnCours]);
        this->etapeEnCours = this->tableauEtapesTotal[etapeEnCours]->getParent()->getNumero();

        //On recalcul les distances par rapport à l'étape où l'on vient d'arriver
        dijkstra->setEtapeCourante(this->etapeEnCours);

        if(this->enTrainEviterReculant)
        {
            this->enTrainEviterReculant = false;
            this->enTrainEviterAvancant = true;
Arnaud Cadot's avatar
Arnaud Cadot committed
            tableauEtapesTotal[etapeEnCours]->getActionGoTo()->setGoBack(false);
            //actionEtape[etapeEnCours]->setGoBack(false);
        }
        else
        {
            this->enTrainEviterReculant = true;
            this->enTrainEviterAvancant = false;
Arnaud Cadot's avatar
Arnaud Cadot committed
            tableauEtapesTotal[etapeEnCours]->getActionGoTo()->setGoBack(true);
            //actionEtape[etapeEnCours]->setGoBack(true);
        }

Arnaud Cadot's avatar
Arnaud Cadot committed
        StrategieV2::addTemporaryAction(tableauEtapesTotal[etapeEnCours]->getActionGoTo());
        //StrategieV2::addTemporaryAction(actionEtape[etapeEnCours]);
Arnaud Cadot's avatar
Arnaud Cadot committed
        //dijkstra->setEtapeCourante((this->tableauEtapesTotal[this->etapeEnCours]->getParent()->getNumero()));
        if(dijkstra->run() != 0)
        {
            // Si run renvoit autre chose que 0, c'est que l'étape en cours a changée.
            // Cela arrive pour débloquer le robot
Arnaud Cadot's avatar
Arnaud Cadot committed
            //Etape* ancienneEtape = this->tableauEtapesTotal[this->etapeEnCours];
            //this->etapeEnCours = this->tableauEtapesTotal[this->etapeEnCours]->getParent()->getNumero();
            /*this->actionEtape[this->etapeEnCours]->reset();
            this->actionGoto[this->etapeEnCours].reset();*/
Arnaud Cadot's avatar
Arnaud Cadot committed
            tableauEtapesTotal[this->etapeEnCours]->reset();
        }

        //On retourne à l'étape intermédiaire précédente, en marche arrière
        statusStrat=1;
        qDebug() << "Pas en train d'eviter";
        //On reset toute les directions à aller en marche avant
        for(int i = 0 ; i < this->nombreEtapes ; i++)
        {
            /*actionGoto[i].setGoBack(false);
            actionEtape[i]->setGoBack(false);*/
Arnaud Cadot's avatar
Arnaud Cadot committed
            tableauEtapesTotal[i]->setGoBack(false);
        }
        this->enTrainEviterReculant = false;
        this->enTrainEviterAvancant = false;

Arnaud Cadot's avatar
Arnaud Cadot committed
        qDebug() << "Status strat: " << statusStrat;

        if(this->statusStrat==2)//Si on vient d'arriver à une étape intermédiare
        {
            this->updateIntermedaire();
        }
        else//Sinon, statusStrat==1, et il faut donc choisir un nouvel objectif
        {
            // Si on n'était pas en train d'éviter
            if(!(enTrainEviterReculant || enTrainEviterAvancant))
            {
                //L'objectif qu'on vient de remplir est maintenant un simple point de passage
Arnaud Cadot's avatar
Arnaud Cadot committed
                //this->tableauEtapesTotal[this->etapeEnCours]->finir();//Vieux, on utilise maintenant updateStock dans la strat de l'année en cours
                //Idem pour les autres étapes correspondant au même objectif
Arnaud Cadot's avatar
Arnaud Cadot committed
                for(int etapeLiee = 0 ; etapeLiee < this->tableauEtapesTotal[this->etapeEnCours]->getNombreEtapesLieesParFinirEtape() ; etapeLiee++)
Arnaud Cadot's avatar
Arnaud Cadot committed
                    int numeroEtapeLiee = this->tableauEtapesTotal[this->etapeEnCours]->getEtapesLieesParFinirEtape()[etapeLiee];
                    this->tableauEtapesTotal[numeroEtapeLiee]->finir();
                //Mise à jour du stock et l'objectif qu'on vient de remplir est maintenant un simple point de passage
                this->updateStock();

                //On est maintenant arrivé à l'étape de fin de l'action (en général c'est la même étape, mais pas toujours, ex : les claps de 2015)
Arnaud Cadot's avatar
Arnaud Cadot committed
                this->etapeEnCours = this->tableauEtapesTotal[this->etapeEnCours]->getNumeroEtapeFinAction() == -1
Axel Baudot's avatar
Axel Baudot committed
                                        ? this->etapeEnCours
Arnaud Cadot's avatar
Arnaud Cadot committed
                                        : this->tableauEtapesTotal[this->etapeEnCours]->getNumeroEtapeFinAction();
Arnaud Cadot's avatar
Arnaud Cadot committed

                qDebug() << "Etape en cours: " << etapeEnCours;
            }


            int score = 0;
            bool resteDesChosesAFaire = updateScores();

            // S'il n'y a plus d'objectif dans tout le graphe, on se replit vers une position où on ne bloque pas l'adversaire.
            // Sinon, il y a risque de prendre un avertissement pour anti-jeu (évité de peu pour le premier match de Krabi 2014)
            if(!resteDesChosesAFaire)
            {
Arnaud Cadot's avatar
Arnaud Cadot committed
                qDebug() << "Trucs à faire 1";
                for(int i = 0 ; i < this->nombreEtapes ; i++)
                {
Arnaud Cadot's avatar
Arnaud Cadot committed
                    this->tableauEtapesTotal[i]->oublieRobotVu();
                }
                resteDesChosesAFaire = updateScores();

                //S'il n'y a VRAIMENT plus rien à faire
                if(!resteDesChosesAFaire)
                {
Arnaud Cadot's avatar
Arnaud Cadot committed
                    qDebug() << "Trucs à faire 2";
                    //Si on est au garage, on s'arrête
                    if(this->etapeEnCours == this->numeroEtapeGarage)
                    {
                        this->statusStrat=-1;//Plus rien à faire, on passe à l'action suivante de stratégieV2
#ifndef ROBOTHW
                        qDebug() << "Fin de StrategieV3";
#endif
                        return this->statusStrat;
                    }
                    else
                    {
                        //Sinon on y va
Arnaud Cadot's avatar
Arnaud Cadot committed
                        this->tableauEtapesTotal[this->numeroEtapeGarage]->setScore(1000);

            //On recalcul les distances par rapport à l'étape où l'on vient d'arriver
            dijkstra->setEtapeCourante(this->etapeEnCours);
            if(dijkstra->run() != 0)
            {
                // Si run renvoit autre chose que 0, c'est que l'étape en cours a changée.
                // Cela arrive pour débloquer le robot
Arnaud Cadot's avatar
Arnaud Cadot committed
                //Etape* ancienneEtape = this->tableauEtapesTotal[this->etapeEnCours];
                //this->etapeEnCours = this->tableauEtapesTotal[this->etapeEnCours]->getParent()->getNumero();
                tableauEtapesTotal[this->etapeEnCours]->getAction()->reset();

            //On sélectionne l'objectif le plus prometteur : pas trop loin et qui rapporte
            int meilleurEtape = -1;
            int scoreMaxi = -100000;

            int scoreTypeEtape = 0;
            for(int i = 0 ; i < this->nombreEtapes ; i++)
Arnaud Cadot's avatar
Arnaud Cadot committed
                scoreTypeEtape = this->tableauEtapesTotal[i]->getScore();
        //        score = modificateurTemporel*(10000-this->tableauEtapesTotal[i]->getDistance() + scoreTypeEtape);
                score = (10000-this->tableauEtapesTotal[i]->getDistance() + scoreTypeEtape);
                if((scoreMaxi < score) && scoreTypeEtape && (this->tableauEtapesTotal[i]->getDistance() != -1))
                    scoreMaxi = score;
                    meilleurEtape = i;
                if(this->etapeEnCours == this->numeroEtapeGarage)
                {
                    this->statusStrat=-1;//Plus rien à faire, on passe à l'action suivante de stratégieV2
                    return this->statusStrat;
                }
                else
                {
                    meilleurEtape = this->numeroEtapeGarage;
                }

            this->goal = meilleurEtape;
            this->statusStrat = 2;//Jusqu'à preuve du contraire, la prochaine étape est une étape intermédiaire
            this->updateIntermedaire();//On y va
Arnaud Cadot's avatar
Arnaud Cadot committed

    qDebug() << "Update finished";
void StrategieV3::resetEverything(){
    for(int i = 0 ; i < 10 ; i++){
Arnaud Cadot's avatar
Arnaud Cadot committed
        this->tableauEtapesTotal[i]->setState(0);
void StrategieV3::collisionAvoided(){
    this->avoiding = true;
}


void StrategieV3::updateIntermedaire()
{
    //Note : le parent d'une étape est l'étape le rapprochant le plus de l'étape d'origine
    //Ainsi, le parent du parent du parent... de n'importe quelle étape est l'étape d'origine
    //(sauf peut être le parent de l'étape d'origine, mais on s'en fout

    #ifndef ROBOTHW
        qDebug() << "updateIntermedaire\n";
    #endif
    int etapeOuOnVientDArriver = this->etapeEnCours;
    this->etapeEnCours = this->goal;

    // Si la prochaine étape est le goal, alors au prochain update il faudra trouver un nouvel objectif -> status = 1;
Arnaud Cadot's avatar
Arnaud Cadot committed
    if(((this->tableauEtapesTotal[this->etapeEnCours]->getParent()->getNumero())) == etapeOuOnVientDArriver)
        #ifndef ROBOTHW
Arnaud Cadot's avatar
Arnaud Cadot committed
            qDebug() << "la prochaine etape est le goal\n" << etapeOuOnVientDArriver;
        #endif
    //On cherche l'etape suivant vers l'etape - but
Arnaud Cadot's avatar
Arnaud Cadot committed
    while(((this->tableauEtapesTotal[this->etapeEnCours]->getParent()->getNumero())) != etapeOuOnVientDArriver)
Arnaud Cadot's avatar
Arnaud Cadot committed

Arnaud Cadot's avatar
Arnaud Cadot committed
        this->etapeEnCours = ((this->tableauEtapesTotal[this->etapeEnCours]->getParent()->getNumero()));

    }

    if(this->statusStrat == 1)
    {
Arnaud Cadot's avatar
Arnaud Cadot committed
        qDebug() << "Okay ici";
        //On réalise l'action de l'étape - but
Arnaud Cadot's avatar
Arnaud Cadot committed
        StrategieV2::addTemporaryAction(tableauEtapesTotal[this->etapeEnCours]->getAction());
    }
    else
    {
        //On ajoute l'action d'aller en ligne droite vers cette étape intermédiaire
Arnaud Cadot's avatar
Arnaud Cadot committed
        tableauEtapesTotal[this->etapeEnCours]->getActionGoTo()->setNextGoal(tableauEtapesTotal[this->nextStep]->getPosition());
Arnaud Cadot's avatar
Arnaud Cadot committed
        StrategieV2::addTemporaryAction(tableauEtapesTotal[this->etapeEnCours]->getActionGoTo());
    }
}


#ifndef ROBOTHW
void StrategieV3::paint(QPainter* p)
{
    for(int numeroEtape = 0 ; numeroEtape<this->nombreEtapes ; numeroEtape++)
        QPoint position = QPoint(
Arnaud Cadot's avatar
Arnaud Cadot committed
        this->tableauEtapesTotal[numeroEtape]->getPosition().getX(),
        this->tableauEtapesTotal[numeroEtape]->getPosition().getY());

        // Affichage des étapes
        p->setPen(colorEtapesIntermediaires);//"orange"));
        p->setBrush(colorEtapesIntermediaires);//"orange"));
        p->setOpacity(1.0f);
        p->drawEllipse(position,10,10);

        // Etape - but en surbrillance
        if(numeroEtape == this->goal)
        {
            p->setPen(colorEtapeGoal);
            p->setBrush(colorEtapeGoal);
            p->setOpacity(1.0f);
            p->drawEllipse(position,30,30);
        }

        // Etape actuelle en surbrillance
        if(numeroEtape == this->etapeEnCours)
        {
            p->setPen(colorEtapesIntermediaires);
            p->setBrush(colorEtapesIntermediaires);
            p->setOpacity(1.0f);
            p->drawEllipse(position,25,25);
        }

        // Etapes où on a vu un robot
Arnaud Cadot's avatar
Arnaud Cadot committed
        if(this->tableauEtapesTotal[numeroEtape]->aEviter())
        {
            p->setPen(colorEtapesRobotVu);
            p->setBrush(colorEtapesRobotVu);
            p->setOpacity(1.0f);
            p->drawEllipse(position,20,20);
        }

        //Affichage du numéro des étapes
        QFont font;
        font.setPixelSize(50);
        p->setFont(font);
        p->setOpacity(1);
        p->setPen(colorTexteEtapes);
        p->setBrush(colorTexteEtapes);
Arnaud Cadot's avatar
Arnaud Cadot committed
        p->drawText(position, QString::number(this->tableauEtapesTotal[numeroEtape]->getNumero()));

        // Affichage des liaisons entre étapes
Arnaud Cadot's avatar
Arnaud Cadot committed
        for(int numeroChild = 0 ; numeroChild < this->tableauEtapesTotal[numeroEtape]->getNbChildren() ; numeroChild++)
        {
//            Affichages de liaisons
//            QPoint positionChild = QPoint(
Arnaud Cadot's avatar
Arnaud Cadot committed
//            this->tableauEtapesTotal[numeroEtape]->getChildren()[numeroChild]->getPosition().getX(),
//            -(this->tableauEtapesTotal[numeroEtape]->getChildren()[numeroChild]->getPosition().getY()));

            // Affichage des demi-liaisons, pour mieux voir les liens mono-directionnels
            QPoint positionChild = QPoint(
Arnaud Cadot's avatar
Arnaud Cadot committed
            (this->tableauEtapesTotal[numeroEtape]->getChildren()[numeroChild]->getPosition().getX()+this->tableauEtapesTotal[numeroEtape]->getPosition().getX())/2,
            (this->tableauEtapesTotal[numeroEtape]->getChildren()[numeroChild]->getPosition().getY()+this->tableauEtapesTotal[numeroEtape]->getPosition().getY())/2);
            p->setOpacity(0.5f);
            p->setPen(colorLiaisonsEtapes);
            p->setBrush(colorLiaisonsEtapes);
            p->drawLine(position.x(), position.y(),positionChild.x(),positionChild.y());
            p->drawEllipse(position,10,10);
        }

        //Affichage du type d'étape
        QPoint positionTypeEtape = QPoint(
Arnaud Cadot's avatar
Arnaud Cadot committed
        this->tableauEtapesTotal[numeroEtape]->getPosition().getX(),
        this->tableauEtapesTotal[numeroEtape]->getPosition().getY() + 50);
        p->setFont(font);
        p->setPen(colorTexteEtapes);
        p->setBrush(colorTexteEtapes);
Arnaud Cadot's avatar
Arnaud Cadot committed
        p->drawText(positionTypeEtape, Etape::getShortNameType(this->tableauEtapesTotal[numeroEtape]->getEtapeType()));
    p->setOpacity(1);
}
#endif

    for(int i=0; i<this->nombreEtapes; i++)
Arnaud Cadot's avatar
Arnaud Cadot committed
        tableauEtapesTotal[i]->computeChildDistances();
Arnaud Cadot's avatar
Arnaud Cadot committed
    this->dijkstra = new Dijkstra(tableauEtapesTotal, this->nombreEtapes);
Arnaud Cadot's avatar
Arnaud Cadot committed
    tableauEtapesTotal[0]->setParent(tableauEtapesTotal[0]);// Evite de planter si on detecte dès la première boucle (dans le simu)

    dijkstra->setEtapeCourante(0);
Arnaud Cadot's avatar
Arnaud Cadot committed
    switch(this->tableauEtapesTotal[this->etapeEnCours]->getEtapeType()){
Arnaud Cadot's avatar
Arnaud Cadot committed
            this->tableauEtapesTotal[this->etapeEnCours]->setEtapeType(Etape::POINT_PASSAGE);
Arnaud Cadot's avatar
Arnaud Cadot committed
            this->tableauEtapesTotal[this->etapeEnCours]->setEtapeType(Etape::POINT_PASSAGE);
bool StrategieV3::updateScores() {
    //Mise à jour du score correspondant à chaque étape
    //CETTE PARTIE EST A AMELIORER
    //on pourrait prendre en compte :
    //le fait le transporter un feu, ce qui active les objectifs de dépose done
    //le temps que prend chaque action
    //le temps restant done
    //la trajectoire de notre autre robot
    //...
    //C'est aussi utilisé pour savoir si on est dans un sous-graphe sans objectif,
    //et qu'il faut oublier qu'on a vu des robots
    int scoreTypeEtape = 0;
    //float modificateurTemporel = 1.f;

    bool resteDesChosesAFaire = false;
    for(int i = 0 ; i < this->nombreEtapes ; i++)
    {
        scoreTypeEtape=this->getScoreEtape(i);
        if(scoreTypeEtape)
        {
            resteDesChosesAFaire = true;
        }
Arnaud Cadot's avatar
Arnaud Cadot committed
        qDebug() << "Etape " << i << " Score: " << scoreTypeEtape;

Arnaud Cadot's avatar
Arnaud Cadot committed
        this->tableauEtapesTotal[i]->setScore(scoreTypeEtape);
    }
    return resteDesChosesAFaire;
}