Commit 2a7f23b1 authored by Matthew Hausknecht's avatar Matthew Hausknecht

Added start script for agent. Refactored state variables.

parent 8ad9a9e7
......@@ -85,14 +85,19 @@ class Trainer(object):
self._agentTeam = self._offenseTeam
self._agentNumInt = 1 if self._numOffense == 1 \
else self._rng.randint(1, self._numOffense)
numTeammates = self._numOffense - 1
numOpponents = self._numDefense
else:
assert self._numDefense > 0
self._agentTeam = self._defenseTeam
self._agentNumInt = 0 if self._numDefense == 1 \
else self._rng.randint(0, self._numDefense)
numTeammates = self._numOffense
numOpponents = self._numDefense - 1
self._agentNumExt = self.convertToExtPlayer(self._agentTeam,
self._agentNumInt)
agentCmd = 'start_agent.sh -t %s -u %i'%(self._agentTeam, self._agentNumExt)
agentCmd = 'start_agent.sh -t %s -u %i --numTeammates %i --numOpponents %i'\
%(self._agentTeam, self._agentNumExt, numTeammates, numOpponents)
agentCmd = agentCmd.split(' ')
# Ignore stderr because librcsc continually prints to it
kwargs = {'stderr':open('/dev/null','w')}
......@@ -475,22 +480,23 @@ class Trainer(object):
def getOffensiveResetPosition(self):
""" Returns a random position for an offensive player. """
offsets = [
[-1,-1],
[-1,1],
[1,1],
[1,-1],
[0,2],
[0,-2],
[-2,-2],
[-2,2],
[2,2],
[2,-2],
]
offset = offsets[self._rng.randint(len(offsets))]
offset_from_ball = 0.1 * self.PITCH_LENGTH * self._rng.rand(2) + \
0.1 * self.PITCH_LENGTH * numpy.array(offset)
return self.boundPoint(self._ballPosition + offset_from_ball)
# offsets = [
# [-1,-1],
# [-1,1],
# [1,1],
# [1,-1],
# [0,2],
# [0,-2],
# [-2,-2],
# [-2,2],
# [2,2],
# [2,-2],
# ]
# offset = offsets[self._rng.randint(len(offsets))]
# offset_from_ball = 0.1 * self.PITCH_LENGTH * self._rng.rand(2) + \
# 0.1 * self.PITCH_LENGTH * numpy.array(offset)
# return self.boundPoint(self._ballPosition + offset_from_ball)
return self._ballPosition
def getDefensiveResetPosition(self):
""" Returns a random position for a defensive player. """
......
#!/bin/bash
BINARY_DIR=`dirname $0` #"$( cd "$( dirname "$0" )" && pwd )"
CONFIG_DIR=$BINARY_DIR/../config
player="${BINARY_DIR}/agent"
coach="${BINARY_DIR}/sample_coach"
teamname="HELIOS_base"
host="localhost"
port=6000
coach_port=""
debug_server_host=""
debug_server_port=""
player_conf="${CONFIG_DIR}/player.conf"
config_dir="${CONFIG_DIR}/formations-dt"
coach_conf="${CONFIG_DIR}/coach.conf"
team_graphic="--use_team_graphic off"
number=11
usecoach="true"
unum=0
sleepprog=sleep
goaliesleep=1
sleeptime=1
debugopt=""
coachdebug=""
opts=""
offline_logging=""
offline_mode=""
fullstateopt=""
record_stats_file=""
use_gdb=""
run_debug_version=""
usage()
{
(echo "Usage: $0 [options]"
echo "Available options:"
echo " --help prints this"
echo " -h, --host HOST specifies server host (default: localhost)"
echo " -p, --port PORT specifies server port (default: 6000)"
echo " -P --coach-port PORT specifies server port for online coach (default: 6002)"
echo " -t, --teamname TEAMNAME specifies team name"
echo " -n, --number NUMBER specifies the number of players"
echo " -u, --unum UNUM specifies the uniform number of players"
echo " -C, --without-coach specifies not to run the coach"
echo " -f, --formation DIR specifies the formation directory"
echo " --team-graphic FILE specifies the team graphic xpm file"
echo " --offline-logging writes offline client log (default: off)"
echo " --offline-client-mode starts as an offline client (default: off)"
echo " --debug writes debug log (default: off)"
echo " --debug-server-connect connects to the debug server (default: off)"
echo " --debug-server-host HOST specifies debug server host (default: localhost)"
echo " --debug-server-port PORT specifies debug server port (default: 6032)"
echo " --debug-server-logging writes debug server log (default: off)"
echo " --log-dir DIRECTORY specifies debug log directory (default: /tmp)"
echo " --debug-log-ext EXTENSION specifies debug log file extension (default: .log)"
echo " --fullstate FULLSTATE_TYPE specifies fullstate model handling"
echo " FULLSTATE_TYPE is one of [ignore|reference|override]."
echo " --offensePlayers player1 ... specifies the numbers of the offense players"
echo " --defensePlayers player1 ... specifies the numbers of the defense players"
echo " --record_stats_file FILE specifies file to write stats to"
echo " --learn-actions NUM number of instances to learn actions, don't do the normal play"
echo " --learn-index NUM learning index"
echo " --learn-path STR learn path"
echo " --model-path STR model path"
echo " --option-filename FILE name of file with json options"
echo " --teammate STR name of teammates"
echo " --numTeammates NUM number of teammates"
echo " --numOpponents NUM number of opponents"
echo " --seed NUM seed for rng"
echo " --gdb runs with gdb on (default:off)"
) 1>&2
}
while [ $# -gt 0 ]
do
case $1 in
--help)
usage
exit 0
;;
-h|--host)
if [ $# -lt 2 ]; then
usage
exit 1
fi
host="${2}"
shift 1
;;
-p|--port)
if [ $# -lt 2 ]; then
usage
exit 1
fi
port="${2}"
shift 1
;;
-P|--coach-port)
if [ $# -lt 2 ]; then
usage
exit 1
fi
coach_port="${2}"
shift 1
;;
-t|--teamname)
if [ $# -lt 2 ]; then
usage
exit 1
fi
teamname="${2}"
shift 1
;;
-n|--number)
if [ $# -lt 2 ]; then
usage
exit 1
fi
number="${2}"
shift 1
;;
-u|--unum)
if [ $# -lt 2 ]; then
usage
exit 1
fi
unum="${2}"
shift 1
;;
-C|--without-coach)
usecoach="false"
;;
-f|--formation)
if [ $# -lt 2 ]; then
usage
exit 1
fi
config_dir="${2}"
shift 1
;;
--team-graphic)
if [ $# -lt 2 ]; then
usage
exit 1
fi
team_graphic="--use_team_graphic on --team_graphic_file ${2}"
shift 1
;;
--offline-logging)
offline_logging="--offline_logging"
;;
--offline-client-mode)
offline_mode="on"
;;
--record_stats_file)
if [ $# -lt 2 ]; then
usage
exit 1
fi
record_stats_file="--record_stats_file ${2}"
shift 1
;;
--learn-actions)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --learn-actions ${2}"
shift 1
;;
--learn-index)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --learn-index ${2}"
shift 1
;;
--learn-path)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --learn-path ${2}"
shift 1
;;
--model-path)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --model-path ${2}"
shift 1
;;
--option-filename)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --option-filename ${2}"
shift 1
;;
--teammate)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --teammate ${2}"
shift 1
;;
--numTeammates)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --numTeammates ${2}"
shift 1
;;
--numOpponents)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --numOpponents ${2}"
shift 1
;;
--seed)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --seed ${2}"
shift 1
;;
--trainer)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --trainer ${2}"
shift 1
;;
--save-path)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --save-path ${2}"
shift 1
;;
--gdb)
use_gdb="true"
;;
--run-debug-version)
run_debug_version="true"
;;
--debug)
debugopt="${debugopt} --debug"
coachdebug="${coachdebug} --debug"
;;
--debug-server-connect)
debugopt="${debugopt} --debug_server_connect"
;;
--debug-server-host)
if [ $# -lt 2 ]; then
usage
exit 1
fi
debug_server_host="${2}"
shift 1
;;
--debug-server-port)
if [ $# -lt 2 ]; then
usage
exit 1
fi
debug_server_port="${2}"
shift 1
;;
--debug-server-logging)
debugopt="${debugopt} --debug_server_logging"
;;
--log-dir)
if [ $# -lt 2 ]; then
usage
exit 1
fi
debugopt="${debugopt} --log_dir ${2}"
shift 1
;;
--debug-log-ext)
if [ $# -lt 2 ]; then
usage
exit 1
fi
debugopt="${debugopt} --debug_log_ext ${2}"
shift 1
;;
--fullstate)
if [ $# -lt 2 ]; then
usage
exit 1
fi
fullstate_type="${2}"
shift 1
case "${fullstate_type}" in
ignore)
fullstateopt="--use_fullstate false --debug_fullstate false"
;;
reference)
fullstateopt="--use_fullstate false --debug_fullstate true"
;;
override)
fullstateopt="--use_fullstate true --debug_fullstate true"
;;
*)
usage
exit 1
;;
esac
;;
*)
echo 1>&2
echo "invalid option \"${1}\"." 1>&2
echo 1>&2
usage
exit 1
;;
esac
shift 1
done
if [ X"${offline_logging}" != X'' ]; then
if [ X"${offline_mode}" != X'' ]; then
echo "'--offline-logging' and '--offline-mode' cannot be used simultaneously."
exit 1
fi
fi
if [ X"${coach_port}" = X'' ]; then
coach_port=`expr ${port} + 2`
fi
if [ X"${debug_server_host}" = X'' ]; then
debug_server_host="${host}"
fi
if [ X"${debug_server_port}" = X'' ]; then
debug_server_port=`expr ${port} + 32`
fi
opt="--player-config ${player_conf} --config_dir ${config_dir}"
opt="${opt} -h ${host} -p ${port} -t ${teamname}"
opt="${opt} ${fullstateopt}"
opt="${opt} --debug_server_host ${debug_server_host}"
opt="${opt} --debug_server_port ${debug_server_port}"
opt="${opt} ${offline_logging}"
opt="${opt} ${debugopt}"
ping -c 1 $host
i=1
while [ $i -le ${number} ] ; do
offline_number=""
if [ X"${offline_mode}" != X'' ]; then
offline_number="--offline_client_number ${i}"
fi
tempsleeptime=${sleeptime}
goalie=""
if [ $i -eq 1 ]; then
goalie="-g ${record_stats_file}"
tempsleeptime=${goaliesleep}
fi
if [ $unum -eq 0 ] || [ $unum -eq $i ]; then
cmd="${player} ${opt} ${opts} ${offline_number} ${goalie} --reconnect $i"
if [ X"${use_gdb}" = X'' ]; then
${cmd} &
echo "PID: $!" > /tmp/start$BASHPID
else
gdb -ex run --args ${cmd}
fi
$sleepprog ${tempsleeptime}
fi
i=`expr $i + 1`
done
if [ "${usecoach}" = "true" ]; then
coachopt="--coach-config ${coach_conf}"
coachopt="${coachopt} -h ${host} -p ${coach_port} -t ${teamname}"
coachopt="${coachopt} ${team_graphic}"
coachopt="${coachopt} --debug_server_host ${debug_server_host}"
coachopt="${coachopt} --debug_server_port ${debug_server_port}"
coachopt="${coachopt} ${offline_logging}"
coachopt="${coachopt} ${debugopt}"
offline_number=""
if [ X"${offline_mode}" != X'' ]; then
offline_mode="--offline_client_mode"
fi
if [ $unum -eq 0 ] || [ $unum -eq 12 ]; then
$coach ${coachopt} ${offline_mode} &
fi
fi
......@@ -85,25 +85,26 @@
#include <string>
#include <cstdlib>
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace rcsc;
/*-------------------------------------------------------------------*/
/*!
#define ADD_FEATURE(val) \
assert(featIndx < numFeatures); \
feature_vec[featIndx++] = val;
*/
Agent::Agent()
: PlayerAgent(),
M_communication(),
M_field_evaluator( createFieldEvaluator() ),
M_action_generator( createActionGenerator() )
M_field_evaluator(createFieldEvaluator()),
M_action_generator(createActionGenerator()),
numTeammates(-1), numOpponents(-1), numFeatures(-1)
{
boost::shared_ptr< AudioMemory > audio_memory( new AudioMemory );
M_worldmodel.setAudioMemory( audio_memory );
//
// set communication message parser
//
addSayMessageParser( SayMessageParser::Ptr( new BallMessageParser( audio_memory ) ) );
addSayMessageParser( SayMessageParser::Ptr( new PassMessageParser( audio_memory ) ) );
addSayMessageParser( SayMessageParser::Ptr( new InterceptMessageParser( audio_memory ) ) );
......@@ -135,89 +136,65 @@ Agent::Agent()
// addSayMessageParser( SayMessageParser::Ptr( new FreeMessageParser< 2 >( audio_memory ) ) );
// addSayMessageParser( SayMessageParser::Ptr( new FreeMessageParser< 1 >( audio_memory ) ) );
//
// set freeform message parser
//
setFreeformParser( FreeformParser::Ptr( new FreeformParser( M_worldmodel ) ) );
setFreeformParser(FreeformParser::Ptr(new FreeformParser(M_worldmodel)));
//
// set action generators
//
// M_action_generators.push_back( ActionGenerator::Ptr( new PassGenerator() ) );
//
// set communication planner
//
M_communication = Communication::Ptr( new SampleCommunication() );
}
/*-------------------------------------------------------------------*/
/*!
*/
Agent::~Agent()
{
M_communication = Communication::Ptr(new SampleCommunication());
}
/*-------------------------------------------------------------------*/
/*!
*/
bool
Agent::initImpl( CmdLineParser & cmd_parser )
{
bool result = PlayerAgent::initImpl( cmd_parser );
bool Agent::initImpl(CmdLineParser & cmd_parser) {
bool result = PlayerAgent::initImpl(cmd_parser);
// read additional options
result &= Strategy::instance().init( cmd_parser );
rcsc::ParamMap my_params( "Additional options" );
#if 0
std::string param_file_path = "params";
param_map.add()
( "param-file", "", &param_file_path, "specified parameter file" );
#endif
result &= Strategy::instance().init(cmd_parser);
cmd_parser.parse( my_params );
rcsc::ParamMap my_params("Additional options");
my_params.add()("numTeammates", "", &numTeammates, "number of teammates");
my_params.add()("numOpponents", "", &numOpponents, "number of opponents");
if ( cmd_parser.count( "help" ) > 0 )
{
cmd_parser.parse(my_params);
if (cmd_parser.count("help") > 0) {
my_params.printHelp( std::cout );
return false;
}
if ( cmd_parser.failed() )
{
if (cmd_parser.failed()) {
std::cerr << "player: ***WARNING*** detected unsuppprted options: ";
cmd_parser.print( std::cerr );
std::cerr << std::endl;
}
if ( ! result )
{
if (!result) {
return false;
}
if ( ! Strategy::instance().read( config().configDir() ) )
{
if (!Strategy::instance().read(config().configDir())) {
std::cerr << "***ERROR*** Failed to read team strategy." << std::endl;
return false;
}
if ( KickTable::instance().read( config().configDir() + "/kick-table" ) )
{
if (KickTable::instance().read(config().configDir() + "/kick-table")) {
std::cerr << "Loaded the kick table: ["
<< config().configDir() << "/kick-table]"
<< std::endl;
}
assert(numTeammates >= 0);
assert(numOpponents >= 0);
numFeatures = num_basic_features +
features_per_player * (numTeammates + numOpponents);
feature_vec.resize(numFeatures);
return true;
}
std::vector<float> Agent::getState() {
void Agent::updateStateFeatures() {
// TODO: Need to normalize these features
std::vector<float> feature_vec;
featIndx = 0;
const ServerParam& SP = ServerParam::i();
const WorldModel& wm = this->world();
......@@ -226,16 +203,16 @@ std::vector<float> Agent::getState() {
const Vector2D& self_pos = self.pos();
// Absolute (x,y) position of the agent.
feature_vec.push_back(self.posValid() ? 1. : 0.);
// feature_vec.push_back(self_pos.x);
// feature_vec.push_back(self_pos.y);
ADD_FEATURE(self.posValid() ? 1. : 0.);
// ADD_FEATURE(self_pos.x);
// ADD_FEATURE(self_pos.y);
// Speed of the agent. Alternatively, (x,y) velocity could be used.
feature_vec.push_back(self.velValid() ? 1. : 0.);
feature_vec.push_back(self.speed());
ADD_FEATURE(self.velValid() ? 1. : 0.);
ADD_FEATURE(self.speed());
// Global Body Angle -- 0:right -90:up 90:down 180/-180:left
feature_vec.push_back(self.body().degree());
ADD_FEATURE(self.body().degree());
// Neck Angle -- We probably don't need this unless we are
// controlling the neck manually.
......@@ -244,8 +221,8 @@ std::vector<float> Agent::getState() {
// std::cout << "FaceAngle: " << self.face() << std::endl;
// }
feature_vec.push_back(self.stamina());
feature_vec.push_back(self.isFrozen() ? 1. : 0.);
ADD_FEATURE(self.stamina());
ADD_FEATURE(self.isFrozen() ? 1. : 0.);
// Probabilities - Do we want these???
// std::cout << "catchProb: " << self.catchProbability() << std::endl;
......@@ -253,10 +230,10 @@ std::vector<float> Agent::getState() {
// std::cout << "fouldProb: " << self.foulProbability() << std::endl;
// Features indicating if we are colliding with an object
feature_vec.push_back(self.collidesWithBall() ? 1. : 0.);
feature_vec.push_back(self.collidesWithPlayer() ? 1. : 0.);
feature_vec.push_back(self.collidesWithPost() ? 1. : 0.);
feature_vec.push_back(self.isKickable() ? 1. : 0.);
ADD_FEATURE(self.collidesWithBall() ? 1. : 0.);
ADD_FEATURE(self.collidesWithPlayer() ? 1. : 0.);
ADD_FEATURE(self.collidesWithPost() ? 1. : 0.);
ADD_FEATURE(self.isKickable() ? 1. : 0.);
// inertiaPoint estimates the ball point after a number of steps
// self.inertiaPoint(n_steps);
......@@ -267,52 +244,52 @@ std::vector<float> Agent::getState() {
SP.pitchHalfWidth()*SP.pitchHalfWidth());
// Top Bottom Center of Goal
rcsc::Vector2D goalCenter(SP.pitchHalfLength(), 0);
addLandmarkFeature(goalCenter, self_pos, feature_vec);
addLandmarkFeature(goalCenter, self_pos);
rcsc::Vector2D goalPostTop(SP.pitchHalfLength(), -SP.goalHalfWidth());
addLandmarkFeature(goalPostTop, self_pos, feature_vec);
addLandmarkFeature(goalPostTop, self_pos);
rcsc::Vector2D goalPostBot(SP.pitchHalfLength(), SP.goalHalfWidth());
addLandmarkFeature(goalPostBot, self_pos, feature_vec);
addLandmarkFeature(goalPostBot, self_pos);
// Top Bottom Center of Penalty Box
rcsc::Vector2D penaltyBoxCenter(SP.pitchHalfLength() - SP.penaltyAreaLength(),
0);
addLandmarkFeature(penaltyBoxCenter, self_pos, feature_vec);
addLandmarkFeature(penaltyBoxCenter, self_pos);
rcsc::Vector2D penaltyBoxTop(SP.pitchHalfLength() - SP.penaltyAreaLength(),
-SP.penaltyAreaWidth()/2.);
addLandmarkFeature(penaltyBoxTop, self_pos, feature_vec);
addLandmarkFeature(penaltyBoxTop, self_pos);
rcsc::Vector2D penaltyBoxBot(SP.pitchHalfLength() - SP.penaltyAreaLength(),
SP.penaltyAreaWidth()/2.);
addLandmarkFeature(penaltyBoxBot, self_pos, feature_vec);
addLandmarkFeature(penaltyBoxBot, self_pos);
// Corners of the Playable Area
rcsc::Vector2D centerField(0, 0);
addLandmarkFeature(centerField, self_pos, feature_vec);
addLandmarkFeature(centerField, self_pos);
rcsc::Vector2D cornerTopLeft(0, -SP.pitchHalfWidth());
addLandmarkFeature(cornerTopLeft, self_pos, feature_vec);
addLandmarkFeature(cornerTopLeft, self_pos);
rcsc::Vector2D cornerTopRight(SP.pitchHalfLength(), -SP.pitchHalfWidth());
addLandmarkFeature(cornerTopRight, self_pos, feature_vec);
addLandmarkFeature(cornerTopRight, self_pos);
rcsc::Vector2D cornerBotRight(SP.pitchHalfLength(), SP.pitchHalfWidth());
addLandmarkFeature(cornerBotRight, self_pos, feature_vec);
addLandmarkFeature(cornerBotRight, self_pos);
rcsc::Vector2D cornerBotLeft(0, SP.pitchHalfWidth());
addLandmarkFeature(cornerBotLeft, self_pos, feature_vec);
addLandmarkFeature(cornerBotLeft, self_pos);
// Distance to Left field line
feature_vec.push_back(self_pos.x);
ADD_FEATURE(self_pos.x);
// Distance to Right field line
feature_vec.push_back(SP.pitchHalfLength() - self.pos().x);
ADD_FEATURE(SP.pitchHalfLength() - self.pos().x);
// Distance to Bottom field line
feature_vec.push_back(SP.pitchHalfWidth() - self.pos().y);
ADD_FEATURE(SP.pitchHalfWidth() - self.pos().y);
// Distance to Top field line
feature_vec.push_back(SP.pitchHalfWidth() + self.pos().y);
ADD_FEATURE(SP.pitchHalfWidth() + self.pos().y);
// ======================== BALL FEATURES ======================== //
const BallObject& ball = wm.ball();
feature_vec.push_back(ball.rposValid() ? 1. : 0.);
feature_vec.push_back(ball.angleFromSelf().degree());
feature_vec.push_back(ball.distFromSelf());
feature_vec.push_back(ball.velValid() ? 1. : 0.);
feature_vec.push_back(ball.vel().x);
feature_vec.push_back(ball.vel().y);
ADD_FEATURE(ball.rposValid() ? 1. : 0.);
ADD_FEATURE(ball.angleFromSelf().degree());
ADD_FEATURE(ball.distFromSelf());
ADD_FEATURE(ball.velValid() ? 1. : 0.);
ADD_FEATURE(ball.vel().x);
ADD_FEATURE(ball.vel().y);
// std::cout << "DistFromBall: " << self.distFromBall() << std::endl;
// [0,180] Agent's left side from back to front
// [0,-180] Agent's right side from back to front
......@@ -320,47 +297,60 @@ std::vector<float> Agent::getState() {
// std::cout << "distFromSelf: " << self.distFromSelf() << std::endl;
// std::cout << "angleFromSelf: " << self.angleFromSelf() << std::endl;
assert(featIndx == num_basic_features);
// ======================== TEAMMATE FEATURES ======================== //
// Vector of PlayerObject pointers sorted by increasing distance from self
int detected_teammates = 0;
const PlayerPtrCont& teammates = wm.teammatesFromSelf();
for (PlayerPtrCont::const_iterator it = teammates.begin();
it != teammates.end(); ++it) {
PlayerObject* teammate = *it;
if (teammate->pos().x > 0 && teammate->unum() > 0) {
if (teammate->pos().x > 0 && teammate->unum() > 0 &&
detected_teammates < numTeammates) {
// Angle dist to teammate. Teammate's body angle and velocity.
feature_vec.push_back((teammate->pos()-self_pos).th().degree());
feature_vec.push_back(teammate->distFromSelf());
feature_vec.push_back(teammate->body().degree());
feature_vec.push_back(teammate->vel().x);
feature_vec.push_back(teammate->vel().y);
ADD_FEATURE((teammate->pos()-self_pos).th().degree());
ADD_FEATURE(teammate->distFromSelf());
ADD_FEATURE(teammate->body().degree());
ADD_FEATURE(teammate->vel().x);
ADD_FEATURE(teammate->vel().y);
detected_teammates++;
}
}
// ======================== OPPONENT FEATURES ======================== //
int detected_opponents = 0;
const PlayerPtrCont& opponents = wm.opponentsFromSelf();
for (PlayerPtrCont::const_iterator it = opponents.begin();
it != opponents.end(); ++it) {
PlayerObject* opponent = *it;
if (opponent->pos().x > 0 && opponent->unum() > 0) {
if (opponent->pos().x > 0 && opponent->unum() > 0 &&
detected_opponents < numOpponents) {
// Angle dist to opponent. Opponents's body angle and velocity.
feature_vec.push_back((opponent->pos()-self_pos).th().degree());
feature_vec.push_back(opponent->distFromSelf());
feature_vec.push_back(opponent->body().degree());
feature_vec.push_back(opponent->vel().x);
feature_vec.push_back(opponent->vel().y);
ADD_FEATURE((opponent->pos()-self_pos).th().degree());
ADD_FEATURE(opponent->distFromSelf());
ADD_FEATURE(opponent->body().degree());
ADD_FEATURE(opponent->vel().x);
ADD_FEATURE(opponent->vel().y);
detected_opponents++;
}
}
return feature_vec;
// Add zeros for missing teammates or opponents. This should only
// happen during initialization.
for (int i=featIndx; i<numFeatures; ++i) {
ADD_FEATURE(0);
}
assert(featIndx == numFeatures);
}
// Add the angle and distance to the landmark to the feature_vec
void Agent::addLandmarkFeature(const rcsc::Vector2D& landmark,
const rcsc::Vector2D& self_pos,
std::vector<float>& feature_vec) {
const rcsc::Vector2D& self_pos) {
Vector2D vec_to_landmark = landmark - self_pos;
feature_vec.push_back(vec_to_landmark.th().degree());
feature_vec.push_back(vec_to_landmark.r());
ADD_FEATURE(vec_to_landmark.th().degree());
ADD_FEATURE(vec_to_landmark.r());
}
/*-------------------------------------------------------------------*/
......@@ -369,7 +359,7 @@ void Agent::addLandmarkFeature(const rcsc::Vector2D& landmark,
virtual method in super class
*/
void Agent::actionImpl() {
std::vector<float> state = getState();
updateStateFeatures();
// Do decision making here
......
......@@ -37,8 +37,7 @@
class Agent : public rcsc::PlayerAgent {
public:
Agent();
virtual ~Agent();
std::vector<float> getState();
virtual ~Agent() {};
virtual FieldEvaluator::ConstPtr getFieldEvaluator() const;
protected:
......@@ -59,11 +58,24 @@ protected:
virtual FieldEvaluator::ConstPtr createFieldEvaluator() const;
virtual ActionGenerator::ConstPtr createActionGenerator() const;
private:
// Updated the state features stored in feature_vec
void updateStateFeatures();
// Add the angle and distance to the landmark to the feature_vec
void addLandmarkFeature(const rcsc::Vector2D& landmark,
const rcsc::Vector2D& self_pos,
std::vector<float>& feature_vec);
const rcsc::Vector2D& self_pos);
int numTeammates;
int numOpponents;
int numFeatures; // Total number of features
// Number of features for non-player objects. Clearly this is the answer.
const static int num_basic_features = 42;
// Number of features for each player or opponent in game.
const static int features_per_player = 5;
std::vector<float> feature_vec; // Contains the current features
int featIndx; // Feature being populated
private:
bool doPreprocess();
bool doShoot();
bool doForceKick();
......
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