Esempio n. 1
0
// --------------------------------------------------------------------------
// commence le movement qui va vers l'entree d'un pont juste un peu decalle en y (~15cm)
// --------------------------------------------------------------------------
bool StrategyAttackCL::gotoBridgeEntryNear(Millimeter y)
{
    Trajectory t;
    disableBridgeCaptors();
    LOG_COMMAND("gotoBridgeEntry Hard Near:%d\n", (int)y);
    // on ne va pas loin en y donc on fait un joli mouvement en S
    // met les servos en position
    Millimeter y2 = RobotPos->y();
    if (y>1800) { // pont du bord
      Move->go2Target(Point(BRIDGE_ENTRY_NAVIGATE_X, y2), 3, 30);
    } else if (y<1500) { //  pont du bord ou pont contre le milieu
      Move->go2Target(Point(BRIDGE_ENTRY_NAVIGATE_X, y2), 3, 30);
    } else { // ponts au milieu
      t.push_back(Point(BRIDGE_DETECT_BUMP_X-100, y2));
      t.push_back(Point(BRIDGE_ENTRY_NAVIGATE_X, (2*y+y2)/3)); 
      Move->followTrajectory(t, TRAJECTORY_RECTILINEAR, 3, 30);
    }
     
    Events->wait(evtEndMove);
    Move->enableAccelerationController(false);
    if (checkEndEvents()) return false; 
    if(!Events->isInWaitResult(EVENTS_MOVE_END)) {
      // collision
      Move->backward(100);
      Events->wait(evtEndMoveNoCollision);
      return false;
    }
    
    // va en face du pont
    enableBridgeCaptors();
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->go2Target(BRIDGE_DETECT_BUMP_X, y, 2, 30);
    // dont need to wait, it is done by the upper function
    return true;
}
Esempio n. 2
0
// --------------------------------------------------------------------------
// commence le movement qui va vers l'entree d'un pont tres decalle en y (>20cm)
// --------------------------------------------------------------------------
bool StrategyAttackCL::gotoBridgeEntryFar(Millimeter y)
{
    disableBridgeCaptors();
    Millimeter y2 = RobotPos->y();
    LOG_COMMAND("gotoBridgeEntry Hard Far:%d\n", (int)y);
    // on va loin: on recule bettement puit on prend un point cible
    // on s'eloigne un peu du bord, pour aller en x qui nous permet
    //de nous promener tranquillement le long de la riviere
    Move->go2Target(BRIDGE_ENTRY_NAVIGATE_X, y2, 2, 40); // norotation
    Events->wait(evtEndMove);
    if (checkEndEvents() || 
        !Events->isInWaitResult(EVENTS_MOVE_END)) {
        Move->enableAccelerationController(false);
        return false;
    }
    
    // va en face du pont
    enableBridgeCaptors();
    Trajectory t;
    // Pour eviter les rotations finales on 
    if (y2 < y)
      t.push_back(Point(BRIDGE_ENTRY_NAVIGATE_X, y-75));
    else
      t.push_back(Point(BRIDGE_ENTRY_NAVIGATE_X, y+75));
    t.push_back(Point(BRIDGE_DETECT_BUMP_X, y));
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->followTrajectory(t, TRAJECTORY_RECTILINEAR, 2, 30, true); // norotation
    // dont wait events, it is done by the upper function
    return true;
}
Esempio n. 3
0
// --------------------------------------------------------------------------
// va a l'endroit ou on detecte les pont par capteurs sharps 
// --------------------------------------------------------------------------
bool StrategyAttackCL::gotoBridgeDetection(bool gotoSiouxFirst)
{
  Events->disable(EVENTS_NO_BRIDGE_BUMP_LEFT);
  Events->disable(EVENTS_NO_BRIDGE_BUMP_RIGHT);
  while(true) {
      LOG_INFO("gotoBridgeDetection(%s)\n",
               gotoSiouxFirst?"Passe par le milieu":"Passe par un pont normal");
      Trajectory t;
      t.push_back(Point(RobotPos->x(), RobotPos->y()));
      // if looping (while(true)..) be careful not to go too close.
      if (RobotPos->x() < BRIDGE_DETECT_SHARP_X - 500)
	  t.push_back(Point(RobotPos->x()+250, RobotPos->y()));
      if (gotoSiouxFirst) {
          // va vers le pont du milieu
          t.push_back(Point(BRIDGE_DETECT_SHARP_X-250, BRIDGE_ENTRY_SIOUX_Y));
          t.push_back(Point(BRIDGE_DETECT_SHARP_X,     BRIDGE_ENTRY_SIOUX_Y));
      } else {
          // va vers la gauche du terrain pour detecter la position du pont d'un coup
          t.push_back(Point(BRIDGE_DETECT_SHARP_X-250, BRIDGE_ENTRY_MIDDLE_BORDURE_Y));
          t.push_back(Point(BRIDGE_DETECT_SHARP_X,     BRIDGE_ENTRY_MIDDLE_BORDURE_Y));
      }
      Move->followTrajectory(t, TRAJECTORY_RECTILINEAR, -1, 40); // gain, vitesse max
      Events->wait(evtEndMove);
      if (checkEndEvents()) return false;
      if (Events->isInWaitResult(EVENTS_MOVE_END)) {
	Move->rotate(0);
	Move->stop();

         Events->wait(evtEndMove);
	 if (checkEndEvents()) return false;
	 if (Events->isInWaitResult(EVENTS_MOVE_END)) {
	   return true;
	 }
	 return true;
      }
      if (RobotPos->x()>600 || Timer->time() > 6000) {
	// collision: on recule et on essaye de repartir par un autre endroit...
	Move->backward(150);
	Events->wait(evtEndMoveNoCollision);
	gotoSiouxFirst = !gotoSiouxFirst;
      }
      if (isZeroAngle(RobotPos->thetaAbsolute() - M_PI, M_PI_2) &&
	  RobotPos->x() < 600)
      {
	Move->backward(700);
	Events->wait(evtEndMoveNoCollision);
	gotoSiouxFirst = !gotoSiouxFirst;
      }
  }
  return false;
}
// ---------------------------------------------------------------
// strategie exploration en passant par la rangee en y = 1350
// ---------------------------------------------------------------
bool StrategyLargeAttackCL::preDefinedSkittleExploration2()
{
    LOG_COMMAND("preDefinedLargeSkittleExploration2\n");
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    bool noRotation = true;
    Point lineStart(2500, 1500);
    Point lineEnd(3200, 1500);
    Move->go2Target(lineStart,
		    MOVE_USE_DEFAULT_GAIN,
		    MOVE_USE_DEFAULT_SPEED,
		    noRotation);
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        if (checkEndEvents()) return false; // c'est la fin du match?
	CollisionEnum collision = checkCollisionEvents();
	if (collision != COLLISION_NONE) {
	    if (!handleCollision(collision, lineStart, lineEnd))
		return false;
	} else {
	    LOG_WARNING("don't know what caused abort of movement. -> abort predefined exploration\n");
	    return false;
	}
    } else {
	// go2Target succeeded its movement.
	Move->rotate(0); // face right border
	Events->wait(evtEndMove);
	if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
	    if (checkEndEvents()) return false; // end of match
	    // ok. normally the collision can only be on the left side...
	    CollisionEnum collision = checkCollisionEvents();
	    if (collision == COLLISION_LEFT) {
		if (!handleCollision(collision, lineStart, lineEnd))
		    return false;
	    } else if (collision == COLLISION_NONE) {
		LOG_WARNING("unhandled event. leaving function\n");
		return false;
	    } else {
		LOG_WARNING("collision, but most likely not a support\n");
		return false;
	    }
	}
    }

    bool endOfLine = false;
    while (!endOfLine) {
	Move->go2Target(lineEnd);
	Events->wait(evtEndMove);
	if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
	    // let's hope it's a support.
	    if (checkEndEvents()) return false; // c'est la fin du match?
	    CollisionEnum collision = checkCollisionEvents();
	    if (collision != COLLISION_NONE) {
		if (!handleCollision(collision, lineStart, lineEnd))
		    return false;
	    } else {
		LOG_WARNING("don't know what caused abort of movement. -> abort predefined exploration\n");
		return false;
	    }
	    if (!RobotPos->isTargetForward(lineEnd))
		endOfLine = true;
	} else {
	    // ok. no more supports detected
	    endOfLine = true;
	}
    }

    LOG_INFO("predefined-large finished.\n");

    //alignBorder();
    
    // on recule un petit peu car on ne sais pas ce qu'on va se prendre en
    // approchant du robot adverse!, mieux vaut tenir que courir
    MvtMgr->setRobotDirection(MOVE_DIRECTION_BACKWARD);
    Trajectory t;
    t.clear();
    t.push_back(Point(3144, 1350)); 
    t.push_back(Point(3190, 1700)); 
    Move->followTrajectory(t, TRAJECTORY_BASIC);
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    //alignBorder();

    // on va droit sur l'adversaire
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->go2Target(Point(3190, 650));
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    // on recule un peu
    MvtMgr->setRobotDirection(MOVE_DIRECTION_BACKWARD);
    Move->go2Target(Point(3190, 1050));
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }
    
    t.clear();
    t.push_back(Point(2550, 1050)); 
    t.push_back(Point(2594, 1650)); 
    t.push_back(Point(3340, 1650)); 
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->followTrajectory(t, TRAJECTORY_BASIC);
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    MvtMgr->setRobotDirection(MOVE_DIRECTION_BACKWARD);
    Move->go2Target(Point(3190, 1650));
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    return true;
}
// ---------------------------------------------------------------
// strategie exploration en passant par la rangee en y = 1650
// ---------------------------------------------------------------
bool StrategyLargeAttackCL::preDefinedSkittleExploration1()
{
    return preDefinedSkittleExploration2();
    LOG_COMMAND("preDefinedLargeSkittleExploration1\n");
    Trajectory t;
    t.push_back(Point(2640, 1650)); 
    t.push_back(Point(3240, 1650));
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->followTrajectory(t, TRAJECTORY_BASIC);
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    //alignBorder();

    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->rotate(-M_PI_2);
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }
    
    //alignBorder();
    
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->go2Target(Point(3190, 650));
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    MvtMgr->setRobotDirection(MOVE_DIRECTION_BACKWARD);
    Move->go2Target(Point(3190, 1050));
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }
    
    t.clear();
    t.push_back(Point(2550, 1050)); 
    t.push_back(Point(2594, 1400)); 
    t.push_back(Point(3340, 1350)); 
    MvtMgr->setRobotDirection(MOVE_DIRECTION_FORWARD);
    Move->followTrajectory(t, TRAJECTORY_BASIC);
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    MvtMgr->setRobotDirection(MOVE_DIRECTION_BACKWARD);
    Move->go2Target(Point(3190, 1350));
    Events->wait(evtEndMove);
    if (!Events->isInWaitResult(EVENTS_MOVE_END)) {
        // on n'a pas reussi
        // c'est la fin du match?
        if (checkEndEvents()) return false;
        // TODO manage collisions
        return false;
    }

    return true;
}
void RRT::optimize_trajectory(){
    Trajectory traj;
    double length, new_length;
    double v_max = world.leader->get_limits().vMax*0.8;
    double c_max = world.leader->get_limits().cMax;
    double c_min = world.leader->get_limits().cMin;
    State st = states[0],
            st2;
    for (int i = 0; i < out_trajectory.size(); ++i) {
        traj.push_back(Desc(st,out_trajectory[i]));
        st2 = world.leader->calculate_state(st, out_trajectory[i]);
        st = st2;
    }
    traj.push_back(Desc(st,Control()));

#ifdef DEBUG_RRT
    length = 0;
    for (int i = 0; i < traj.size(); ++i) {
        length += traj[i].control.t * traj[i].control.v;
    }
    TimeMeasurement tm;
    tm.start();
    std::cout << "RRT: original trajectory length: " << length <<  std::endl;
    /*
    std::cout << std::endl << "LEADER PLANNED POSITIONS:" << std::endl;
    for (int i = 0; i < traj.size(); ++i) {
        std::cout << "	X = [ " << traj[i].state.X(0) << ", " << traj[i].state.X(1) << ", " << traj[i].state.X(2) << " ]" << std::endl;
    }
*/
#endif
    int loop = 0;
    bool isValid;
    bool endPoint;
    while(loop < 100){
        ++loop;
        int n_first = rand() % traj.size();
        int n_second = rand() % traj.size();
        while(n_first == n_second){
            n_second = rand() % traj.size();
        }

        if (n_first > n_second){
            const int p = n_first;
            n_first = n_second;
            n_second = p;
        }

        length = 0;
        for (int i = n_first; i < n_second; ++i) {
            length += traj[i].control.t * fabs(traj[i].control.v);
        }
        endPoint = false;
        if (n_second != traj.size()-1){
            dubins = new geom::Dubins(geom::Position(geom::Point(traj[n_first].state.X(0),traj[n_first].state.X(1)), traj[n_first].state.phi),
                                      geom::Position(geom::Point(traj[n_second].state.X(0),traj[n_second].state.X(1)), traj[n_second].state.phi),
                                      1/world.leader->cMax());
        }else{
            endPoint = true;
            dubins = new geom::Dubins(geom::Position(geom::Point(traj[n_first].state.X(0),traj[n_first].state.X(1)), traj[n_first].state.phi),
                                      geom::Point(goal[0],goal[1]),
                    1/world.leader->cMax());
            length += dist2D(traj.back().state.X,Vector(goal[0],goal[1],0));
        }
        new_length = dubins->getLength();

        if (new_length < length){
#ifdef DEBUG_RRT_DUBINS
            if (endPoint){
            std::cout << "DUBINS: original part length   : " << length <<  std::endl;
            std::cout << "        simplified part length : " << new_length <<  std::endl;
            std::cout << "        type of Dubins maneuver: " << dubins->getTypeOfManeuver() << " [RSR, LSL, LSR, RSL, RLR, LRL, LS, RS]" << std::endl;
            }
#endif

            Trajectory new_traj;
            for (int i = 0; i < n_first; ++i) {
                new_traj.push_back(traj[i]);
            }
            double t1, t2, t3, c1, c2, c3;
            State state_first = traj[n_first].state;
            Control cnt;
            switch (dubins->getTypeOfManeuver()) {
            case geom::RSR:
                t1 = dubins->getRadius()*fabs(dubins->getLen1())/v_max;
                t2 = dubins->getLen2()/v_max;
                t3 = dubins->getRadius()*fabs(dubins->getLen3())/v_max;
                c1 = c_min;
                c2 = 0;
                c3 = c_min;
                break;
            case geom::LSL:
                t1 = dubins->getRadius()*fabs(dubins->getLen1())/v_max;
                t2 = dubins->getLen2()/v_max;
                t3 = dubins->getRadius()*fabs(dubins->getLen3())/v_max;
                c1 = c_max;
                c2 = 0;
                c3 = c_max;
                break;
            case geom::LSR:
                t1 = dubins->getRadius()*fabs(dubins->getLen1())/v_max;
                t2 = dubins->getLen2()/v_max;
                t3 = dubins->getRadius()*fabs(dubins->getLen3())/v_max;
                c1 = c_max;
                c2 = 0;
                c3 = c_min;
                break;
            case geom::RSL:
                t1 = dubins->getRadius()*fabs(dubins->getLen1())/v_max;
                t2 = dubins->getLen2()/v_max;
                t3 = dubins->getRadius()*fabs(dubins->getLen3())/v_max;
                c1 = c_min;
                c2 = 0;
                c3 = c_max;
                break;
            case geom::RLR:
                t1 = dubins->getRadius()*fabs(dubins->getLen1())/v_max;
                t2 = dubins->getRadius()*fabs(dubins->getLen2())/v_max;
                t3 = dubins->getRadius()*fabs(dubins->getLen3())/v_max;
                c1 = c_min;
                c2 = c_max;
                c3 = c_min;
                break;
            case geom::LRL:
                t1 = dubins->getRadius()*fabs(dubins->getLen1())/v_max;
                t2 = dubins->getRadius()*fabs(dubins->getLen2())/v_max;
                t3 = dubins->getRadius()*fabs(dubins->getLen3())/v_max;
                c1 = c_max;
                c2 = c_min;
                c3 = c_max;
                break;
            default:
                break;
            }

            State s_new, s_old = state_first;
            int n_added = 0;
            if (t1 > eps){
                while (t1-RRT_TIME_STEP>eps){
                    cnt = Control(v_max,0,c1,RRT_TIME_STEP);
                    new_traj.push_back(Desc(s_old,cnt));
                    t1 -= RRT_TIME_STEP;

                    s_new = world.leader->calculate_state(s_old, cnt);
                    s_old = s_new;
                    ++n_added;
                }
                cnt = Control(v_max,0,c1,t1);
                new_traj.push_back(Desc(s_old,cnt));
                s_new = world.leader->calculate_state(s_old, cnt);
                s_old = s_new;
                ++n_added;
            }

            if (t2 > eps){
                while (t2-RRT_TIME_STEP>eps){
                    cnt = Control(v_max,0,c2,RRT_TIME_STEP);
                    new_traj.push_back(Desc(s_old,cnt));
                    t2 -= RRT_TIME_STEP;

                    s_new = world.leader->calculate_state(s_old, cnt);
                    s_old = s_new;
                    ++n_added;
                }
                cnt = Control(v_max,0,c2,t2);
                new_traj.push_back(Desc(s_old,cnt));
                s_new = world.leader->calculate_state(s_old, cnt);
                s_old = s_new;
                ++n_added;
            }
            if (t3 > eps){
                while (t3-RRT_TIME_STEP>eps){
                    cnt = Control(v_max,0,c3,RRT_TIME_STEP);
                    new_traj.push_back(Desc(s_old,cnt));
                    t3 -= RRT_TIME_STEP;

                    s_new = world.leader->calculate_state(s_old, cnt);
                    s_old = s_new;
                    ++n_added;
                }
                cnt = Control(v_max,0,c3,t3);
                new_traj.push_back(Desc(s_old,cnt));
                ++n_added;
            }

            isValid = true;
            for (int i = 0; i < n_added; ++i) {
                const int index = new_traj.size()-n_added+i;
                Points pts = world.leader->getSampledTrajectory(new_traj[index].state,&new_traj[index].control,1);
                for (int j = 0; j < pts.size(); ++j) {
                    isValid &= world.map->wall_distance(pts[j]) > world.leader->get_ra();
                    if (!isValid)
                        break;
                }
                if (!isValid)
                    break;
            }
            if (!isValid){
                continue;
            }

            loop = 0;
            if (!endPoint){
                for (int i = n_second; i < traj.size(); ++i) {
                    new_traj.push_back(traj[i]);
                }
            }else{
                s_new = world.leader->calculate_state(new_traj.back().state, new_traj.back().control);
                new_traj.push_back(Desc(State(goal[0],goal[1],0,0),Control()));
            }
            traj = new_traj;

        }
    }
    out_trajectory.clear();
    for (int i = 0; i < traj.size()-1; ++i) {
        out_trajectory.push_back(traj[i].control);
    }

#ifdef DEBUG_RRT
    length = 0;
    for (int i = 0; i < traj.size(); ++i) {
        length += traj[i].control.t * traj[i].control.v;
    }
    tm.end();
    std::cout << "RRT: optimized trajectory length: " << length <<  std::endl;
    std::cout << "                            size: " << traj.size()-1 <<  std::endl;

    /*
    std::cout << std::endl;
    for (int i = 0; i < traj.size(); ++i) {
        std::cout << "   v = " << traj[i].control.v << ", w = " << traj[i].control.w << ", c = " << traj[i].control.c << ", t = " << traj[i].control.t << std::endl;
    }
    */
#endif

}