Commit 384fb648 authored by Siddharth Aravindan's avatar Siddharth Aravindan Committed by asiddharth

Added defense actions, changed feature space

parent 1b71c1e8
...@@ -26,7 +26,7 @@ LOW_LEVEL_FEATURE_SET, HIGH_LEVEL_FEATURE_SET = range(2) ...@@ -26,7 +26,7 @@ LOW_LEVEL_FEATURE_SET, HIGH_LEVEL_FEATURE_SET = range(2)
NOOP(): Do Nothing NOOP(): Do Nothing
QUIT(): Quit the game ''' QUIT(): Quit the game '''
DASH, TURN, TACKLE, KICK, KICK_TO, MOVE_TO, DRIBBLE_TO, INTERCEPT, \ DASH, TURN, TACKLE, KICK, KICK_TO, MOVE_TO, DRIBBLE_TO, INTERCEPT, \
MOVE, SHOOT, PASS, DRIBBLE, CATCH, NOOP, QUIT = range(15) MOVE, SHOOT, PASS, DRIBBLE, CATCH, NOOP, QUIT, REDUCE_ANGLE_TO_GOAL,MARK_PLAYER,DEFEND_GOAL,GO_TO_BALL = range(19)
''' Possible game status ''' Possible game status
[IN_GAME] Game is currently active [IN_GAME] Game is currently active
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#include <rcsc/param/param_map.h> #include <rcsc/param/param_map.h>
#include <rcsc/param/cmd_line_parser.h> #include <rcsc/param/cmd_line_parser.h>
#include <algorithm> // std::sort
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
...@@ -81,10 +82,12 @@ ...@@ -81,10 +82,12 @@
#include <cstdlib> #include <cstdlib>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <vector>
#include <poll.h> #include <poll.h>
using namespace rcsc; using namespace rcsc;
...@@ -302,6 +305,18 @@ void Agent::actionImpl() { ...@@ -302,6 +305,18 @@ void Agent::actionImpl() {
std::cout << "Got quit from agent." << std::endl; std::cout << "Got quit from agent." << std::endl;
handleExit(); handleExit();
return; return;
case REDUCE_ANGLE_TO_GOAL:
this->doReduceAngleToGoal();
break;
case MARK_PLAYER:
this->doMarkPlayer(int(params[0]));
break;
case DEFEND_GOAL:
this->doDefendGoal();
break;
case GO_TO_BALL:
this->doGoToBall();
break;
default: default:
std::cerr << "ERROR: Unsupported Action: " std::cerr << "ERROR: Unsupported Action: "
<< requested_action << std::endl; << requested_action << std::endl;
...@@ -777,6 +792,242 @@ Agent::doMove() ...@@ -777,6 +792,242 @@ Agent::doMove()
} }
/*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/
/*!
* This Action marks the player with the specified uniform number.
*/
bool Agent::doMarkPlayer(int unum) {
const WorldModel & wm = this->world();
Vector2D kicker_pos = Vector2D :: INVALIDATED;
Vector2D player_pos = Vector2D :: INVALIDATED;
int kicker_unum = -1;
const PlayerPtrCont::const_iterator o_end = wm.opponentsFromSelf().end();
int count = 0;
for ( PlayerPtrCont::const_iterator it = wm.opponentsFromSelf().begin(); it != o_end; ++it ) {
if ( (*it)->distFromBall() < 5 ) {
kicker_pos = (*it)->pos();
kicker_unum = (*it)->unum();
}
}
for ( PlayerPtrCont::const_iterator it = wm.opponentsFromSelf().begin(); it != o_end; ++it ) {
if ( (*it)-> unum() == unum ) {
player_pos = (*it)->pos();
}
}
if (!player_pos.isValid()) {
//Player to be marked not found
return false;
}
if (!kicker_pos.isValid()) {
//Kicker not found
return false;
}
if (unum == kicker_unum || kicker_pos.equals(player_pos)) {
//Player to be marked is kicker
return false;
}
double x = player_pos.x + (kicker_pos.x - player_pos.x)*0.1;
double y = player_pos.y + (kicker_pos.y - player_pos.y)*0.1;
Body_GoToPoint(Vector2D(x,y), 0.25, ServerParam::i().maxDashPower()).execute(this);
return true;
}
/*!
* This Action marks the player which is "nearindex" nearest to the ball.
*/
bool Agent::doMarkPlayerNearIndex(int nearIndex) {
const WorldModel & wm = this->world();
Vector2D kicker_pos = Vector2D :: INVALIDATED;
Vector2D player_pos = Vector2D :: INVALIDATED;
const PlayerPtrCont::const_iterator o_end = wm.opponentsFromSelf().end();
int count = 0;
for ( PlayerPtrCont::const_iterator it = wm.opponentsFromSelf().begin(); it != o_end; ++it ) {
if ( (*it)->distFromBall() < 5 ) {
kicker_pos = (*it)->pos();
}
}
if (nearIndex >=0 && nearIndex <= wm.opponentsFromBall().size()) {
player_pos = wm.opponentsFromBall().at(nearIndex-1)->pos();
}
if (!player_pos.isValid()) {
//"nearIndex Player Not Found
return false;
}
if (!kicker_pos.isValid()) {
//Kicker not found
return false;
}
if (kicker_pos.equals(player_pos)) {
//nearIndex Player to be marked is kicker
return false;
}
double x = player_pos.x + (kicker_pos.x - player_pos.x)*0.1;
double y = player_pos.y + (kicker_pos.y - player_pos.y)*0.1;
Body_GoToPoint(Vector2D(x,y), 0.25, ServerParam::i().maxDashPower()).execute(this);
return true;
}
/*-------------------------------------------------------------------*/
/*!
*
* This action cuts off the angle between the shooter and the goal the players always move to a dynamic line in between the kicker and the goal.
*/
/* Comparator for sorting teammated based on y positions.*/
bool compare_y_pos (PlayerObject* i, PlayerObject* j) {
return i->pos().y < j->pos().y;
}
bool Agent::doReduceAngleToGoal() {
const WorldModel & wm = this->world();
Vector2D goal_pos1( -ServerParam::i().pitchHalfLength(), ServerParam::i().goalHalfWidth() );
Vector2D goal_pos2( -ServerParam::i().pitchHalfLength(), -ServerParam::i().goalHalfWidth() );
const PlayerPtrCont::const_iterator o_end = wm.opponentsFromSelf().end();
Vector2D ball_pos = wm.ball().pos();
double nearRatio = 0.9;
const PlayerPtrCont::const_iterator o_t_end = wm.teammatesFromSelf().end();
std::vector<PlayerObject*> teammatesBetweenBallAndGoal;
Vector2D self_pos = wm.self().pos();
Line2D goal_line_1 (goal_pos1, ball_pos);
Line2D goal_line_2 (goal_pos2, ball_pos);
Vector2D max_angle_end_pt1 = goal_pos2;
Vector2D max_angle_end_pt2 = goal_pos1;
//filter out points not lie in the cone
for (PlayerPtrCont::const_iterator it1 = wm.teammatesFromSelf().begin(); it1 != o_t_end; ++it1 ) {
Vector2D teammate_pos = (*it1)->pos();
double y1 = goal_line_1.getY(teammate_pos.x);
double y2 = goal_line_2.getY(teammate_pos.x);
//check x coordinate
if (teammate_pos.x >= ball_pos.x ) {
continue;
}
// check y coordinate
if (teammate_pos.y <= ((y1>y2)?y2:y1) || teammate_pos.y >= ((y1>=y2)?y1:y2)) {
continue;
}
//push into vector if it passes both tests
teammatesBetweenBallAndGoal.push_back(*it1);
}
sort(teammatesBetweenBallAndGoal.begin(), teammatesBetweenBallAndGoal.end(), compare_y_pos);
double max_angle = 0;
/* find max angle and choose endpoints*/
for (int i = 0; i < teammatesBetweenBallAndGoal.size() + 1; i++) {
Vector2D first_pos = Vector2D::INVALIDATED;
if (i == 0) {
first_pos = goal_pos2;
} else {
first_pos = teammatesBetweenBallAndGoal[i-1] -> pos();
}
Vector2D second_pos = Vector2D::INVALIDATED;
if ( i== teammatesBetweenBallAndGoal.size()) {
second_pos = goal_pos1;
} else {
second_pos = teammatesBetweenBallAndGoal[i] -> pos();
}
double angle1 = atan2(ball_pos.y - first_pos.y, ball_pos.x - first_pos.x);
double angle2 = atan2(ball_pos.y - second_pos.y, ball_pos.x - second_pos.x);
AngleDeg open_angle;
double open_angle_value = fabs(open_angle.normalize_angle(open_angle.rad2deg(angle1-angle2)));
if ( open_angle_value > max_angle) {
max_angle = open_angle_value;
max_angle_end_pt1 = first_pos;
max_angle_end_pt2 = second_pos;
}
}
/*Calculate and go to target point */
Vector2D targetLineEnd1 = max_angle_end_pt1*(1-nearRatio) + ball_pos*nearRatio;
Vector2D targetLineEnd2 = max_angle_end_pt2*(1-nearRatio) + ball_pos*nearRatio;
double dist_to_end1 = targetLineEnd1.dist2(ball_pos);
double dist_to_end2 = targetLineEnd2.dist2(ball_pos);
double ratio = dist_to_end2/(dist_to_end1+dist_to_end2);
Vector2D target = targetLineEnd1 * ratio + targetLineEnd2 * (1-ratio);
Body_GoToPoint(target, 0.25, ServerParam::i().maxDashPower()).execute(this);
return true;
}
/*-------------------------------------------------------------------*/
/*!
*
* This action cuts off the angle between the shooter and the goal the players always moves on a fixed line.
*/
bool Agent::doDefendGoal() {
const WorldModel & wm = this->world();
Vector2D goal_pos1( -ServerParam::i().pitchHalfLength() + ServerParam::i().goalAreaLength(), ServerParam::i().goalHalfWidth() );
Vector2D goal_pos2( -ServerParam::i().pitchHalfLength() + ServerParam::i().goalAreaLength(), -ServerParam::i().goalHalfWidth() );
Vector2D ball_pos = wm.ball().pos();
double dist_to_post1 = goal_pos1.dist2(ball_pos);
double dist_to_post2 = goal_pos2.dist2(ball_pos);
double ratio = dist_to_post2/(dist_to_post1+dist_to_post2);
Vector2D target = goal_pos1 * ratio + goal_pos2 * (1-ratio);
Body_GoToPoint(target, 0.25, ServerParam::i().maxDashPower()).execute(this);
return true;
}
/*-------------------------------------------------------------------*/
/*!
*
* This action makes the agent head directly head towards the ball.
*/
bool Agent::doGoToBall() {
const WorldModel & wm = this->world();
Body_GoToPoint(wm.ball().pos(), 0.25, ServerParam::i().maxDashPower()).execute(this);
return true;
}
/*-------------------------------------------------------------------*/
/*!
Used for 1v1 .
High level action MOVE is taken whenever the agent does not have the ball.
Medium level action DRIBBLE_TO is taken whenever the agent has to turn by a large amount to get the correct angle to shoot at the goal.
High level action SHOOT is used to shoot it to the goal
This is an example action and is not used.
*/
bool Agent::doNewAction1() {
const WorldModel & wm = this->world();
if(! wm.self().isKickable() ) {
this->doMove();
return true;
} else {
Vector2D goal_pos( -ServerParam::i().pitchHalfLength(), 0.0 );
Vector2D self_pos = wm.self().pos();
Vector2D dir (self_pos.x - goal_pos.x, self_pos.y - goal_pos.y);
AngleDeg angle = wm.self().vel().th();
double angle_threshold = 10;
double angle_diff = (dir.th() - angle).degree();
if ( std::fabs(angle_diff) > angle_threshold && goal_pos.dist(self_pos) > 20) {
double x = self_pos.x + 0.1*(goal_pos.x - self_pos.x );
double y = self_pos.y + 0.1*(goal_pos.y - self_pos.y );
Body_Dribble(Vector2D(x,y), 1.0, ServerParam::i().maxDashPower(), 2).execute(this);
} else {
this->doSmartKick();
}
return true;
}
}
/*-------------------------------------------------------------------*/
/*! /*!
*/ */
......
...@@ -84,6 +84,13 @@ protected: ...@@ -84,6 +84,13 @@ protected:
bool doMove(); bool doMove();
bool doForceKick(); bool doForceKick();
bool doHeardPassReceive(); bool doHeardPassReceive();
bool doMarkPlayer(int unum);
bool doMarkPlayerNearIndex(int near_index);
bool doReduceAngleToGoal();
bool doDefendGoal();
bool doGoToBall();
bool doNewAction1();
Communication::Ptr M_communication; Communication::Ptr M_communication;
FieldEvaluator::ConstPtr M_field_evaluator; FieldEvaluator::ConstPtr M_field_evaluator;
......
...@@ -33,7 +33,11 @@ enum action_t ...@@ -33,7 +33,11 @@ enum action_t
DRIBBLE, // [High-Level] Dribble(): Offensive dribble DRIBBLE, // [High-Level] Dribble(): Offensive dribble
CATCH, // [High-Level] Catch(): Catch the ball (Goalie only!) CATCH, // [High-Level] Catch(): Catch the ball (Goalie only!)
NOOP, // Do nothing NOOP, // Do nothing
QUIT // Special action to quit the game QUIT, // Special action to quit the game
REDUCE_ANGLE_TO_GOAL, // [High-Level] Reduce_Angle_To_Goal : Reduces the shooting angle
MARK_PLAYER, // [High-Level] Mark_Player(opponent_unum [0,11]) : Moves to the position in between the kicker and a given player
DEFEND_GOAL,
GO_TO_BALL
}; };
// Status of a HFO game // Status of a HFO game
...@@ -105,6 +109,14 @@ inline int NumParams(const action_t action) { ...@@ -105,6 +109,14 @@ inline int NumParams(const action_t action) {
return 0; return 0;
case QUIT: case QUIT:
return 0; return 0;
case REDUCE_ANGLE_TO_GOAL:
return 0;
case MARK_PLAYER:
return 1;
case DEFEND_GOAL:
return 0;
case GO_TO_BALL:
return 0;
} }
std::cerr << "Unrecognized Action: " << action << std::endl; std::cerr << "Unrecognized Action: " << action << std::endl;
return -1; return -1;
...@@ -145,6 +157,14 @@ inline std::string ActionToString(action_t action) { ...@@ -145,6 +157,14 @@ inline std::string ActionToString(action_t action) {
return "No-op"; return "No-op";
case QUIT: case QUIT:
return "Quit"; return "Quit";
case REDUCE_ANGLE_TO_GOAL:
return "Reduce_Angle_To_Goal";
case MARK_PLAYER:
return "Mark_Player";
case DEFEND_GOAL:
return "Defend_Goal";
case GO_TO_BALL:
return "Go_To_Ball";
default: default:
return "Unknown"; return "Unknown";
} }
......
...@@ -55,10 +55,9 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures( ...@@ -55,10 +55,9 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures(
// Features about the ball // Features about the ball
Vector2D ball_pos = wm.ball().pos(); Vector2D ball_pos = wm.ball().pos();
angleDistToPoint(self_pos, ball_pos, th, r); angleDistToPoint(self_pos, ball_pos, th, r);
// Feature[3]: Dist to ball // Feature[3] and [4]: (x,y) postition of the ball
addNormFeature(r, 0, maxR); addNormFeature(ball_pos.x, -SP.pitchHalfLength()-tolerance_x, tolerance_x);
// Feature[4]: Ang to ball addNormFeature(ball_pos.y, -SP.pitchHalfWidth() - tolerance_y, SP.pitchHalfWidth() + tolerance_y);
addNormFeature(th, -M_PI, M_PI);
// Feature[5]: Able to kick // Feature[5]: Able to kick
addNormFeature(self.isKickable(), false, true); addNormFeature(self.isKickable(), false, true);
...@@ -131,14 +130,13 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures( ...@@ -131,14 +130,13 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures(
addFeature(FEAT_INVALID); addFeature(FEAT_INVALID);
} }
// Features [9+3T - 9+6T]: dist, angle, unum of teammates // Features [9+3T - 9+6T]: x, y, unum of teammates
detected_teammates = 0; detected_teammates = 0;
for (PlayerCont::const_iterator it=teammates.begin(); it != teammates.end(); ++it) { for (PlayerCont::const_iterator it=teammates.begin(); it != teammates.end(); ++it) {
const PlayerObject& teammate = *it; const PlayerObject& teammate = *it;
if (valid(teammate) && detected_teammates < numTeammates) { if (valid(teammate) && detected_teammates < numTeammates) {
angleDistToPoint(self_pos, teammate.pos(), th, r); addNormFeature(teammate.pos().x, -tolerance_x - SP.pitchHalfLength(), tolerance_x );
addNormFeature(r,0,maxR); addNormFeature(teammate.pos().y, -tolerance_y - SP.pitchHalfWidth(), SP.pitchHalfWidth() + tolerance_y);
addNormFeature(th,-M_PI,M_PI);
addFeature(teammate.unum()); addFeature(teammate.unum());
detected_teammates++; detected_teammates++;
} }
...@@ -150,14 +148,13 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures( ...@@ -150,14 +148,13 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures(
addFeature(FEAT_INVALID); addFeature(FEAT_INVALID);
} }
// Features [9+6T - 9+6T+3O]: dist, angle, unum of opponents // Features [9+6T - 9+6T+3O]: x, y, unum of opponents
int detected_opponents = 0; int detected_opponents = 0;
for (PlayerCont::const_iterator it = opponents.begin(); it != opponents.end(); ++it) { for (PlayerCont::const_iterator it = opponents.begin(); it != opponents.end(); ++it) {
const PlayerObject& opponent = *it; const PlayerObject& opponent = *it;
if (valid(opponent) && detected_opponents < numOpponents) { if (valid(opponent) && detected_opponents < numOpponents) {
angleDistToPoint(self_pos, opponent.pos(), th, r); addNormFeature(opponent.pos().x, -tolerance_x - SP.pitchHalfLength(), tolerance_x );
addNormFeature(r,0,maxR); addNormFeature(opponent.pos().y, -tolerance_y - SP.pitchHalfWidth(), SP.pitchHalfWidth() + tolerance_y);
addNormFeature(th,-M_PI,M_PI);
addFeature(opponent.unum()); addFeature(opponent.unum());
detected_opponents++; detected_opponents++;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment