/* * Final Project -- referee.cc */ #define PREDATOR_X_MAX -7 #define PREDATOR_X_MIN -10.5 #define PREDATOR_Y_MAX 5 #define PREDATOR_Y_MIN -2 #define PREY_X_MAX -1 #define PREY_X_MIN -4.5 #define PREY_Y_MAX 5 #define PREY_Y_MIN -2 // Minimum starting separation of X and Y, pioneer2dx size is [0.44,0.33] #define MIN_PRED_SEPARATION 0.45 #define CAPTURE_RANGE 2 #define RAND(a,b) rand() * ((double)b-a) / (double)RAND_MAX + (double)a #include #include #include #include #include #include #include "InputMap.h" using namespace PlayerCc; using namespace std; #include "args.h" bool clearPath(double x_s, double y_s, double x_e, double y_e); int main(int argc, char** argv) { parse_args(argc,argv); try { PlayerClient robot(gHostname, gPort); SimulationProxy state(&robot); Graphics2dProxy draw(&robot); double pred1X, pred1Y, pred2X, pred2Y, preyX, preyY, buf; double pred1Heading, pred2Heading; double pred1Dist, pred2Dist; time_t start, stop; inputMap_v2(0, (char*)"autolab.pnm"); srand(time(NULL)); cout << "Connected - Press enter to start simulation...\n"; while (!getchar()); start = time(NULL); state.SetPose2d((char *)string("prey").c_str(), RAND(PREY_X_MIN,PREY_X_MAX), RAND(PREY_Y_MIN,PREY_Y_MAX), RAND(-M_PI, M_PI)); state.SetPose2d((char *)string("predator1").c_str(), RAND(PREDATOR_X_MIN,PREDATOR_X_MAX), RAND(PREDATOR_Y_MIN,PREDATOR_Y_MAX), RAND(-M_PI, M_PI)); state.SetPose2d((char *)string("predator2").c_str(), RAND(PREDATOR_X_MIN,PREDATOR_X_MAX), RAND(PREDATOR_Y_MIN,PREDATOR_Y_MAX), RAND(-M_PI, M_PI)); // don't put the predators on top of each other state.GetPose2d((char *)string("predator1").c_str(), pred1X, pred1Y, pred1Heading); state.GetPose2d((char *)string("predator2").c_str(), pred2X, pred2Y, pred2Heading); state.GetPose2d((char *)string("prey").c_str(), preyX, preyY, buf); while(fabs(pred1X-pred2X) < MIN_PRED_SEPARATION && fabs(pred1Y - pred2Y) < MIN_PRED_SEPARATION) { state.SetPose2d((char *)string("predator1").c_str(), RAND(PREY_X_MIN, PREY_X_MAX), RAND(PREY_Y_MIN, PREY_Y_MAX), RAND(-M_PI, M_PI)); state.SetPose2d((char *)string("predator2").c_str(), RAND(PREY_X_MIN, PREY_X_MAX), RAND(PREY_Y_MIN, PREY_Y_MAX), RAND(-M_PI, M_PI)); state.GetPose2d((char *)string("predator1").c_str(), pred1X, pred1Y, pred1Heading); state.GetPose2d((char *)string("predator2").c_str(), pred2X, pred2Y, pred2Heading); } cout << "Predator 1 starting orientation:\t(" << pred1X << "," << pred1Y << ")\n"; cout << "Predator 2 starting orientation:\t(" << pred2X << "," << pred2Y << ")\n"; cout << "Prey starting orientation:\t\t(" << preyX << "," << preyY << ")\n"; // go into read-think-act loop for(;;) { state.GetPose2d((char *)string("prey").c_str(), preyX, preyY, pred1Heading); state.GetPose2d((char *)string("predator1").c_str(), pred1X, pred1Y, pred2Heading); state.GetPose2d((char *)string("predator2").c_str(), pred2X, pred2Y, buf); pred1Dist = sqrt(pow(pred1X-preyX,2)+pow(pred1Y-preyY,2)); pred2Dist = sqrt(pow(pred2X-preyX,2)+pow(pred2Y-preyY,2)); bool pred1Clear = clearPath(pred1X, pred1Y, preyX, preyY); bool pred2Clear = clearPath(pred2X, pred2Y, preyX, preyY); if ((pred1Dist <= CAPTURE_RANGE) && (pred2Dist <= CAPTURE_RANGE) && pred1Clear && pred2Clear) { stop = time(NULL); cout << "----Capture!-----\n"; cout << "\tPredator 1\t(" << pred1X << "," << pred1Y << ")\n"; cout << "\tPredator 2\t(" << pred2X << "," << pred2Y << ")\n"; cout << "\tPrey\t\t(" << preyX << "," << preyY << ")\n"; cout << "\tPredator 1 Distance\t" << pred1Dist << endl; cout << "\tPredator 2 Distance\t" << pred2Dist << endl; cout << "Capture occurred after " << stop - start << " seconds\n"; cout << "-----------------\n"; exit(stop-start); } } } catch (PlayerCc::PlayerError e) { std::cerr << e << std::endl; return -1; } } #define xToMapX(cell_size, x) (x/cell_size) + width/(2*SCALE_MAP) #define yToMapY(cell_size, y) height/(2*SCALE_MAP) - (y/cell_size) bool isCellOccupied(int x, int y) { return gridMap[y][x] == 1.0; } bool clearPath(double x_s, double y_s, double x_g, double y_g) { double x_cell_size = 24.0/width * SCALE_MAP; double y_cell_size = 24.0/height * SCALE_MAP; //convert to map coordinates. int map_x_s = xToMapX(x_cell_size, x_s); int map_y_s = yToMapY(y_cell_size, y_s); int map_x_g = xToMapX(x_cell_size, x_g); int map_y_g = yToMapY(y_cell_size, y_g); bool steep = abs(map_y_g - map_y_s) > abs(map_x_g - map_x_s); int temp = 0; if(steep) { temp = map_x_g; map_x_g = map_y_g; map_y_g = temp; temp = map_x_s; map_x_s = map_y_s; map_y_s = temp; } if( map_x_s > map_x_g ) { temp = map_x_s; map_x_s = map_x_g; map_x_g = temp; temp = map_y_s; map_y_s = map_y_g; map_y_g = temp; } int deltax = map_x_g - map_x_s; int deltay = abs(map_y_g - map_y_s); int error = deltax/2; int ystep = (map_y_s < map_y_g) ? 1 : -1; int y = map_y_s; for(int x = map_x_s; x < map_x_g; x++) { if(steep) { if(isCellOccupied(y,x)) { return false; } } else if(isCellOccupied(x,y)) { return false; } error -= deltay; if(error < 0) { y += ystep; error += deltax; } } return true; }