Skip to content
commandAllerA.cpp 7.39 KiB
Newer Older
hilnius's avatar
hilnius committed
#include "commandAllerA.h"
#include "odometrie.h"
hilnius's avatar
hilnius committed
#include "strategieV2.h"
#include "leds.h"
hilnius's avatar
hilnius committed
#ifndef abs
hilnius's avatar
hilnius committed
#endif
hilnius's avatar
hilnius committed

CommandAllerA::CommandAllerA(Position p, bool reculer, float vitesseLineaireMax, float vitesseFin, float /*precisionAngle*/, float distance): Command()
hilnius's avatar
hilnius committed
{
    smoothFactor            = 0.f;
    requireSmoothMovement   = false;
    bonAngle                = false;
    angleSmoothEnd          = false;
    stopAtDistance          = distance;

hilnius's avatar
hilnius committed
    but = p;
Alex's avatar
Alex committed
    vitesseLinMax = vitesseLineaireMax;
Alex's avatar
Alex committed
    vFin2 = vitesseFin*vitesseFin;
hilnius's avatar
hilnius committed
    m_reculer = reculer;
    this->precisionAngle = -1.f;//precisionAngle;
hilnius's avatar
hilnius committed
}

void CommandAllerA::update()
{
hilnius's avatar
hilnius committed
    float accAngMax = ACCELERATION_ANGULAIRE_MAX;
    float vitAngMax = VITESSE_ANGULAIRE_MAX;
    float accLinMax = ACCELERATION_LINEAIRE_MAX;
    float decLinMax = DECELERATION_LINEAIRE_MAX;
Alex's avatar
Alex committed
    float vitLinMax = vitesseLinMax;//VITESSE_LINEAIRE_MAX;
Alexandre Manoury's avatar
Alexandre Manoury committed
    float vitLinIntermediate = vitesseLinMax * 0.75;
hilnius's avatar
hilnius committed

    if(this->getLimit())
    {
        vitLinMax = vitesseLinMax/3;
        allumerLED();
        allumerLED2();
    }
    else
    {
        //eteindreLED();
    }

hilnius's avatar
hilnius committed
    //float angleVitesseMax = M_PI/10.0f;
    float angleVitesseMax = 0.5f*vitAngMax*vitAngMax/accAngMax;
    //float distanceVitesseMax = 350.0f;
Alex's avatar
Alex committed
    float distanceVitesseMax = 0.5f*(vitLinMax*vitLinMax-vFin2)/decLinMax;
hilnius's avatar
hilnius committed
    float angle = Odometrie::odometrie->getPos().getAngle();
    Position pos = Odometrie::odometrie->getPos().getPosition();
    Vec2d deltaFirst = but - pos;
    Vec2d deltaNext;
    if (this->requireSmoothMovement)
        deltaNext = nextGoal - but;

    // distances
    float distanceNext = (this->requireSmoothMovement ? deltaNext.getNorme() : 0);
    // disable smooth if short moves
    /*if (this->requireSmoothMovement && distanceNext < 50.)
        this->requireSmoothMovement = false;*/
    float distanceIntermediate = (this->requireSmoothMovement ? deltaFirst.getNorme() : 0);

    bool isChangingToNext = false;

    // smooth movement
    Vec2d delta;
    if (this->requireSmoothMovement)
    {
        if (distanceIntermediate > this->smoothFactor)
            delta = deltaFirst;
        else
        {
            isChangingToNext = true;
            delta = deltaFirst + (deltaNext - deltaFirst) * (0.5f - distanceIntermediate / (this->smoothFactor * 2.));
        }
    }
    else
        delta = computedGoal - pos;

    // distances
    float distanceFinal = (this->requireSmoothMovement ? delta.getNorme() + distanceNext : delta.getNorme() - stopAtDistance);
hilnius's avatar
hilnius committed
    float angleVise = atan2(delta.getY(),delta.getX());

    if (m_reculer)
        angleVise += M_PI;

    float diffAng = AngleTools::diffAngle(angleVise,angle);
hilnius's avatar
hilnius committed

    // reste sur place tant que le robot n'a pas le bon angle
    float angleMaxPourAvancer;
    if (precisionAngle<0.)
        angleMaxPourAvancer = M_PI/25.0f;//25.0f;
    else
        angleMaxPourAvancer = DEGTORAD(3.);//25.0f;
hilnius's avatar
hilnius committed
    if (!bonAngle)
    {
        if (fabs(diffAng) < angleMaxPourAvancer)
hilnius's avatar
hilnius committed
        {
            bonAngle = true;
hilnius's avatar
hilnius committed
        }
hilnius's avatar
hilnius committed
        {
            linSpeed *= 0.95f;
        }
    }
Pika's avatar
Pika committed

    StrategieV2::setTourneSurSoiMeme((!bonAngle)&&(abs(linSpeed)<0.2f));

    if (linSpeed > 0.2f)
        StrategieV2::enableSharpsGroup(true);
    else if (linSpeed < -0.2f)
        StrategieV2::enableSharpsGroup(false);
    else
        StrategieV2::emptySharpsToCheck();

    bool distanceOk = /*(distanceBut > derniereDistance) || */(distanceFinal < 30.0f);
Pika's avatar
Pika committed

    // vitesse angulaire
    if (distanceOk)
    {
        //vitAngMax = VITESSE_ANGULAIRE_SLOW_MAX;
Pika's avatar
Pika committed
        //linSpeed = 0.;
    }
    {
        angSpeed = 0.;
    }
    else */

    if (fabs(diffAng) > angleVitesseMax / 10.f)
        angleSmoothEnd = false;
    /*else if (fabs(diffAng) < angleVitesseMax / 20.f)
        angleSmoothEnd = true;*/

    if (angleSmoothEnd)
    {
        angSpeed = diffAng*vitAngMax/angleVitesseMax;
    }
    else
Pika's avatar
Pika committed
    {
        bool hasToDecelerate = (fabs(diffAng) < (angSpeed * angSpeed / accAngMax - accAngMax*2.));

Pika's avatar
Pika committed
        if (diffAng > 0)
        {
            if (!hasToDecelerate)
                angSpeed += accAngMax;
            else if (angSpeed > accAngMax*2)
                angSpeed -= accAngMax*2;
Pika's avatar
Pika committed

            if (angSpeed > vitAngMax)
                angSpeed = vitAngMax;
        }
        else
        {
            if (!hasToDecelerate)
                angSpeed -= accAngMax;
            else if (angSpeed < -accAngMax*2)
                angSpeed += accAngMax*2;
Pika's avatar
Pika committed

            if (angSpeed < -vitAngMax)
                angSpeed = -vitAngMax;
        }

    }

    // vitesse angulaire
    /*if (abs(diffAng) > angleVitesseMax)
    {
         if (diffAng > 0)
            angSpeed += accAngMax;
         else
            angSpeed -= accAngMax;
Pika's avatar
Pika committed

        if (angSpeed > vitAngMax)
            angSpeed = vitAngMax;
        else if (angSpeed < -vitAngMax)
            angSpeed = -vitAngMax;
    }
    else
    {
        angSpeed = diffAng*vitAngMax/angleVitesseMax;
    }*/
hilnius's avatar
hilnius committed

    // vitesse linéaire
hilnius's avatar
hilnius committed
    {
        if (fabs(diffAng) > angleMaxPourAvancer && !isChangingToNext)
Pika's avatar
Pika committed
        {
            float linSpeedVisee = (m_reculer ? -vitLinIntermediate : vitLinIntermediate);

            if (abs(linSpeed) < abs(linSpeedVisee))
            {
                linSpeed += (m_reculer ? -accLinMax : accLinMax);
                if (abs(linSpeed) > abs(linSpeedVisee))
                    linSpeed = linSpeedVisee;
            }
            else if (abs(linSpeed) > abs(linSpeedVisee))
            {
                linSpeed += (m_reculer ? accLinMax : -accLinMax);
                if (abs(linSpeed) < abs(linSpeedVisee))
                    linSpeed = linSpeedVisee;
            }
        }
        else if (distanceFinal > distanceVitesseMax)
        {
            linSpeed += (m_reculer ? -accLinMax : accLinMax);
            //DebugWindow::getInstance()->plot(4, "status", 2, 10);
Pika's avatar
Pika committed
            if (linSpeed > vitLinMax)
                linSpeed = vitLinMax;
            else if (linSpeed < -vitLinMax)
                linSpeed = -vitLinMax;
Pika's avatar
Pika committed
        }
        else
        {
            float linSpeedVisee = sqrt(vFin2+2.0f*distanceFinal*decLinMax);
Pika's avatar
Pika committed
            if (m_reculer)
Pika's avatar
Pika committed

            //DebugWindow::getInstance()->plot(4, "status", 2, 20);
            linSpeed += (m_reculer ? -accLinMax : accLinMax);
hilnius's avatar
hilnius committed

Pika's avatar
Pika committed
            if (abs(linSpeed) > abs(linSpeedVisee))
                linSpeed = linSpeedVisee;

            //linSpeed = distanceBut * vitesseLinMax / distanceVitesseMax;
Pika's avatar
Pika committed
        }
hilnius's avatar
hilnius committed
    }

    if ((isChangingToNext && distanceIntermediate > lastDistance) || distanceFinal < 10.0f)
    {
hilnius's avatar
hilnius committed
}

void CommandAllerA::smoothMovement(Position nextGoal, float smoothFactor)
{
    this->smoothFactor = smoothFactor;
    this->nextGoal = nextGoal;
    this->requireSmoothMovement = true;

    markAsSmooth();
}