Commit 2311a7d8 authored by Matthew Hausknecht's avatar Matthew Hausknecht

Introduced normalization for all of the state features.

parent fe5ddaf2
...@@ -63,6 +63,7 @@ class Trainer(object): ...@@ -63,6 +63,7 @@ class Trainer(object):
self._agentTeam = '' # Name of the team the agent is playing for self._agentTeam = '' # Name of the team the agent is playing for
self._agentNumInt = -1 # Agent's internal team number self._agentNumInt = -1 # Agent's internal team number
self._agentNumExt = -1 # Agent's external team number self._agentNumExt = -1 # Agent's external team number
self._agentServerPort = args.serverPort # Port for agent's server
# =============== MISC =============== # # =============== MISC =============== #
self._offenseTeam = '' # Name of the offensive team self._offenseTeam = '' # Name of the offensive team
self._defenseTeam = '' # Name of the defensive team self._defenseTeam = '' # Name of the defensive team
...@@ -97,12 +98,12 @@ class Trainer(object): ...@@ -97,12 +98,12 @@ class Trainer(object):
self._agentNumExt = self.convertToExtPlayer(self._agentTeam, self._agentNumExt = self.convertToExtPlayer(self._agentTeam,
self._agentNumInt) self._agentNumInt)
agentCmd = 'start_agent.sh -t %s -u %i --numTeammates %i --numOpponents %i'\ agentCmd = 'start_agent.sh -t %s -u %i --numTeammates %i --numOpponents %i'\
' --playingOffense %i'\ ' --playingOffense %i --serverPort %i'\
%(self._agentTeam, self._agentNumExt, numTeammates, numOpponents, %(self._agentTeam, self._agentNumExt, numTeammates, numOpponents,
self._agent_play_offense) self._agent_play_offense, self._agentServerPort)
agentCmd = agentCmd.split(' ') agentCmd = agentCmd.split(' ')
# Ignore stderr because librcsc continually prints to it # Ignore stderr because librcsc continually prints to it
kwargs = {'stderr':open('/dev/null','w')} kwargs = {}#{'stderr':open('/dev/null','w')}
p = subprocess.Popen(agentCmd, **kwargs) p = subprocess.Popen(agentCmd, **kwargs)
p.wait() p.wait()
with open('/tmp/start%i' % p.pid,'r') as f: with open('/tmp/start%i' % p.pid,'r') as f:
......
...@@ -101,6 +101,8 @@ def parseArgs(args=None): ...@@ -101,6 +101,8 @@ def parseArgs(args=None):
help='Don\'t use a learning agent.') help='Don\'t use a learning agent.')
p.add_argument('--no-sync', dest='sync', action='store_false', default=True, p.add_argument('--no-sync', dest='sync', action='store_false', default=True,
help='Run server in non-sync mode') help='Run server in non-sync mode')
p.add_argument('--server-port', dest='serverPort', type=int, default=6008,
help='Port to run agent server on.')
return p.parse_args(args=args) return p.parse_args(args=args)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -77,6 +77,7 @@ usage() ...@@ -77,6 +77,7 @@ usage()
echo " --numTeammates NUM number of teammates" echo " --numTeammates NUM number of teammates"
echo " --numOpponents NUM number of opponents" echo " --numOpponents NUM number of opponents"
echo " --playingOffense [0|1] are we playing offense or defense" echo " --playingOffense [0|1] are we playing offense or defense"
echo " --serverPort NUM port for server to list on"
echo " --seed NUM seed for rng" echo " --seed NUM seed for rng"
echo " --gdb runs with gdb on (default:off)" echo " --gdb runs with gdb on (default:off)"
) 1>&2 ) 1>&2
...@@ -265,6 +266,15 @@ do ...@@ -265,6 +266,15 @@ do
shift 1 shift 1
;; ;;
--serverPort)
if [ $# -lt 2 ]; then
usage
exit 1
fi
opts="${opts} --serverPort ${2}"
shift 1
;;
--seed) --seed)
if [ $# -lt 2 ]; then if [ $# -lt 2 ]; then
usage usage
......
...@@ -93,6 +93,9 @@ ...@@ -93,6 +93,9 @@
using namespace rcsc; using namespace rcsc;
float min_feat_val = 1e8;
float max_feat_val = -1e8;
// Socket Error // Socket Error
void error(const char *msg) void error(const char *msg)
{ {
...@@ -100,10 +103,31 @@ void error(const char *msg) ...@@ -100,10 +103,31 @@ void error(const char *msg)
exit(1); exit(1);
} }
// Minimium and feature values
#define FEAT_MIN -1.
#define FEAT_MAX 1.
// Add a feature without normalizing
#define ADD_FEATURE(val) \ #define ADD_FEATURE(val) \
assert(featIndx < numFeatures); \ assert(featIndx < numFeatures); \
feature_vec[featIndx++] = val; feature_vec[featIndx++] = val;
// Add a feature and normalize to the range [FEAT_MIN, FEAT_MAX]
#define ADD_NORM_FEATURE(val, min_val, max_val) \
assert(featIndx < numFeatures); \
if (val < min_val || val > max_val) { std::cout << "Violated Feature Bounds: " << val << " Expected min/max: [" << min_val << ", " << max_val << "]" << std::endl;} \
assert(val >= min_val); \
assert(val <= max_val); \
feature_vec[featIndx++] = ((val - min_val) / (max_val - min_val)) \
* (FEAT_MAX - FEAT_MIN) + FEAT_MIN;
#define LOG_FEATURE(val) \
if (val <= min_feat_val) \
min_feat_val = val; \
if (val >= max_feat_val) \
max_feat_val = val; \
std::cout << "FEATURE " << val << " [" << min_feat_val << ", " << max_feat_val << "]" << std::endl;
Agent::Agent() Agent::Agent()
: PlayerAgent(), : PlayerAgent(),
M_communication(), M_communication(),
...@@ -111,7 +135,8 @@ Agent::Agent() ...@@ -111,7 +135,8 @@ Agent::Agent()
M_action_generator(createActionGenerator()), M_action_generator(createActionGenerator()),
numTeammates(-1), numOpponents(-1), numFeatures(-1), numTeammates(-1), numOpponents(-1), numFeatures(-1),
lastTrainerMessageTime(-1), lastTrainerMessageTime(-1),
episode_start(true), maxHFORadius(-1),
server_port(6008),
server_running(false) server_running(false)
{ {
boost::shared_ptr< AudioMemory > audio_memory( new AudioMemory ); boost::shared_ptr< AudioMemory > audio_memory( new AudioMemory );
...@@ -177,6 +202,7 @@ bool Agent::initImpl(CmdLineParser & cmd_parser) { ...@@ -177,6 +202,7 @@ bool Agent::initImpl(CmdLineParser & cmd_parser) {
my_params.add()("numOpponents", "", &numOpponents, "number of opponents"); my_params.add()("numOpponents", "", &numOpponents, "number of opponents");
my_params.add()("playingOffense", "", &playingOffense, my_params.add()("playingOffense", "", &playingOffense,
"are we playing offense or defense"); "are we playing offense or defense");
my_params.add()("serverPort", "", &server_port, "Port to start server on");
cmd_parser.parse(my_params); cmd_parser.parse(my_params);
if (cmd_parser.count("help") > 0) { if (cmd_parser.count("help") > 0) {
...@@ -211,11 +237,26 @@ bool Agent::initImpl(CmdLineParser & cmd_parser) { ...@@ -211,11 +237,26 @@ bool Agent::initImpl(CmdLineParser & cmd_parser) {
features_per_player * (numTeammates + numOpponents); features_per_player * (numTeammates + numOpponents);
feature_vec.resize(numFeatures); feature_vec.resize(numFeatures);
const ServerParam& SP = ServerParam::i();
// Grab the field dimensions
pitchLength = SP.pitchLength();
pitchWidth = SP.pitchWidth();
pitchHalfLength = SP.pitchHalfLength();
pitchHalfWidth = SP.pitchHalfWidth();
goalHalfWidth = SP.goalHalfWidth();
penaltyAreaLength = SP.penaltyAreaLength();
penaltyAreaWidth = SP.penaltyAreaWidth();
// Maximum possible radius in HFO
maxHFORadius = sqrtf(pitchHalfLength * pitchHalfLength +
pitchHalfWidth * pitchHalfWidth);
return true; return true;
} }
void Agent::updateStateFeatures() { void Agent::updateStateFeatures() {
// TODO: Need to normalize these features
featIndx = 0; featIndx = 0;
const ServerParam& SP = ServerParam::i(); const ServerParam& SP = ServerParam::i();
const WorldModel& wm = this->world(); const WorldModel& wm = this->world();
...@@ -223,18 +264,26 @@ void Agent::updateStateFeatures() { ...@@ -223,18 +264,26 @@ void Agent::updateStateFeatures() {
// ======================== SELF FEATURES ======================== // // ======================== SELF FEATURES ======================== //
const SelfObject& self = wm.self(); const SelfObject& self = wm.self();
const Vector2D& self_pos = self.pos(); const Vector2D& self_pos = self.pos();
const AngleDeg& self_ang = self.body();
// Absolute (x,y) position of the agent. // Absolute (x,y) position of the agent.
ADD_FEATURE(self.posValid() ? 1. : 0.); ADD_FEATURE(self.posValid() ? FEAT_MAX : FEAT_MIN);
// ADD_FEATURE(self_pos.x); // ADD_FEATURE(self_pos.x);
// ADD_FEATURE(self_pos.y); // ADD_FEATURE(self_pos.y);
// Speed of the agent. Alternatively, (x,y) velocity could be used. // Direction and speed of the agent.
ADD_FEATURE(self.velValid() ? 1. : 0.); ADD_FEATURE(self.velValid() ? FEAT_MAX : FEAT_MIN);
ADD_FEATURE(self.speed()); if (self.velValid()) {
addAngFeature(self_ang - self.vel().th());
ADD_NORM_FEATURE(self.speed(), 0., observedSelfSpeedMax);
} else {
ADD_FEATURE(0);
ADD_FEATURE(0);
ADD_FEATURE(0);
}
// Global Body Angle -- 0:right -90:up 90:down 180/-180:left // Global Body Angle -- 0:right -90:up 90:down 180/-180:left
ADD_FEATURE(self.body().degree()); addAngFeature(self_ang);
// Neck Angle -- We probably don't need this unless we are // Neck Angle -- We probably don't need this unless we are
// controlling the neck manually. // controlling the neck manually.
...@@ -243,8 +292,8 @@ void Agent::updateStateFeatures() { ...@@ -243,8 +292,8 @@ void Agent::updateStateFeatures() {
// std::cout << "FaceAngle: " << self.face() << std::endl; // std::cout << "FaceAngle: " << self.face() << std::endl;
// } // }
ADD_FEATURE(self.stamina()); ADD_NORM_FEATURE(self.stamina(), 0., observedStaminaMax);
ADD_FEATURE(self.isFrozen() ? 1. : 0.); ADD_FEATURE(self.isFrozen() ? FEAT_MAX : FEAT_MIN);
// Probabilities - Do we want these??? // Probabilities - Do we want these???
// std::cout << "catchProb: " << self.catchProbability() << std::endl; // std::cout << "catchProb: " << self.catchProbability() << std::endl;
...@@ -252,72 +301,85 @@ void Agent::updateStateFeatures() { ...@@ -252,72 +301,85 @@ void Agent::updateStateFeatures() {
// std::cout << "fouldProb: " << self.foulProbability() << std::endl; // std::cout << "fouldProb: " << self.foulProbability() << std::endl;
// Features indicating if we are colliding with an object // Features indicating if we are colliding with an object
ADD_FEATURE(self.collidesWithBall() ? 1. : 0.); ADD_FEATURE(self.collidesWithBall() ? FEAT_MAX : FEAT_MIN);
ADD_FEATURE(self.collidesWithPlayer() ? 1. : 0.); ADD_FEATURE(self.collidesWithPlayer() ? FEAT_MAX : FEAT_MIN);
ADD_FEATURE(self.collidesWithPost() ? 1. : 0.); ADD_FEATURE(self.collidesWithPost() ? FEAT_MAX : FEAT_MIN);
ADD_FEATURE(self.isKickable() ? 1. : 0.); ADD_FEATURE(self.isKickable() ? FEAT_MAX : FEAT_MIN);
// inertiaPoint estimates the ball point after a number of steps // inertiaPoint estimates the ball point after a number of steps
// self.inertiaPoint(n_steps); // self.inertiaPoint(n_steps);
// ======================== LANDMARK FEATURES ======================== // // ======================== LANDMARK FEATURES ======================== //
// Maximum possible radius in HFO
float maxR = sqrtf(SP.pitchHalfLength()*SP.pitchHalfLength() +
SP.pitchHalfWidth()*SP.pitchHalfWidth());
// Top Bottom Center of Goal // Top Bottom Center of Goal
rcsc::Vector2D goalCenter(SP.pitchHalfLength(), 0); rcsc::Vector2D goalCenter(pitchHalfLength, 0);
addLandmarkFeature(goalCenter, self_pos); addLandmarkFeatures(goalCenter, self_pos, self_ang);
rcsc::Vector2D goalPostTop(SP.pitchHalfLength(), -SP.goalHalfWidth()); rcsc::Vector2D goalPostTop(pitchHalfLength, -goalHalfWidth);
addLandmarkFeature(goalPostTop, self_pos); addLandmarkFeatures(goalPostTop, self_pos, self_ang);
rcsc::Vector2D goalPostBot(SP.pitchHalfLength(), SP.goalHalfWidth()); rcsc::Vector2D goalPostBot(pitchHalfLength, goalHalfWidth);
addLandmarkFeature(goalPostBot, self_pos); addLandmarkFeatures(goalPostBot, self_pos, self_ang);
// Top Bottom Center of Penalty Box // Top Bottom Center of Penalty Box
rcsc::Vector2D penaltyBoxCenter(SP.pitchHalfLength() - SP.penaltyAreaLength(), rcsc::Vector2D penaltyBoxCenter(pitchHalfLength - penaltyAreaLength, 0);
0); addLandmarkFeatures(penaltyBoxCenter, self_pos, self_ang);
addLandmarkFeature(penaltyBoxCenter, self_pos); rcsc::Vector2D penaltyBoxTop(pitchHalfLength - penaltyAreaLength,
rcsc::Vector2D penaltyBoxTop(SP.pitchHalfLength() - SP.penaltyAreaLength(), -penaltyAreaWidth / 2.);
-SP.penaltyAreaWidth()/2.); addLandmarkFeatures(penaltyBoxTop, self_pos, self_ang);
addLandmarkFeature(penaltyBoxTop, self_pos); rcsc::Vector2D penaltyBoxBot(pitchHalfLength - penaltyAreaLength,
rcsc::Vector2D penaltyBoxBot(SP.pitchHalfLength() - SP.penaltyAreaLength(), penaltyAreaWidth / 2.);
SP.penaltyAreaWidth()/2.); addLandmarkFeatures(penaltyBoxBot, self_pos, self_ang);
addLandmarkFeature(penaltyBoxBot, self_pos);
// Corners of the Playable Area // Corners of the Playable Area
rcsc::Vector2D centerField(0, 0); rcsc::Vector2D centerField(0, 0);
addLandmarkFeature(centerField, self_pos); addLandmarkFeatures(centerField, self_pos, self_ang);
rcsc::Vector2D cornerTopLeft(0, -SP.pitchHalfWidth()); rcsc::Vector2D cornerTopLeft(0, -pitchHalfWidth);
addLandmarkFeature(cornerTopLeft, self_pos); addLandmarkFeatures(cornerTopLeft, self_pos, self_ang);
rcsc::Vector2D cornerTopRight(SP.pitchHalfLength(), -SP.pitchHalfWidth()); rcsc::Vector2D cornerTopRight(pitchHalfLength, -pitchHalfWidth);
addLandmarkFeature(cornerTopRight, self_pos); addLandmarkFeatures(cornerTopRight, self_pos, self_ang);
rcsc::Vector2D cornerBotRight(SP.pitchHalfLength(), SP.pitchHalfWidth()); rcsc::Vector2D cornerBotRight(pitchHalfLength, pitchHalfWidth);
addLandmarkFeature(cornerBotRight, self_pos); addLandmarkFeatures(cornerBotRight, self_pos, self_ang);
rcsc::Vector2D cornerBotLeft(0, SP.pitchHalfWidth()); rcsc::Vector2D cornerBotLeft(0, pitchHalfWidth);
addLandmarkFeature(cornerBotLeft, self_pos); addLandmarkFeatures(cornerBotLeft, self_pos, self_ang);
// Distances to the edges of the playable area
if (self.posValid()) {
// Distance to Left field line // Distance to Left field line
ADD_FEATURE(self_pos.x); addDistFeature(self_pos.x, pitchHalfLength);
// Distance to Right field line // Distance to Right field line
ADD_FEATURE(SP.pitchHalfLength() - self.pos().x); addDistFeature(pitchHalfLength - self_pos.x, pitchHalfLength);
// Distance to top field line
addDistFeature(pitchHalfWidth + self_pos.y, pitchWidth);
// Distance to Bottom field line // Distance to Bottom field line
ADD_FEATURE(SP.pitchHalfWidth() - self.pos().y); addDistFeature(pitchHalfWidth - self_pos.y, pitchWidth);
// Distance to Top field line } else {
ADD_FEATURE(SP.pitchHalfWidth() + self.pos().y); ADD_FEATURE(0);
ADD_FEATURE(0);
ADD_FEATURE(0);
ADD_FEATURE(0);
}
// ======================== BALL FEATURES ======================== // // ======================== BALL FEATURES ======================== //
const BallObject& ball = wm.ball(); const BallObject& ball = wm.ball();
ADD_FEATURE(ball.rposValid() ? 1. : 0.); // Angle and distance to the ball
ADD_FEATURE(ball.angleFromSelf().degree()); ADD_FEATURE(ball.rposValid() ? FEAT_MAX : FEAT_MIN);
ADD_FEATURE(ball.distFromSelf()); if (ball.rposValid()) {
ADD_FEATURE(ball.velValid() ? 1. : 0.); addAngFeature(ball.angleFromSelf());
ADD_FEATURE(ball.vel().x); addDistFeature(ball.distFromSelf(), maxHFORadius);
ADD_FEATURE(ball.vel().y); } else {
// std::cout << "DistFromBall: " << self.distFromBall() << std::endl; ADD_FEATURE(0);
// [0,180] Agent's left side from back to front ADD_FEATURE(0);
// [0,-180] Agent's right side from back to front ADD_FEATURE(0);
// std::cout << "AngleFromBall: " << self.angleFromBall() << std::endl; }
// std::cout << "distFromSelf: " << self.distFromSelf() << std::endl; // Velocity and direction of the ball
// std::cout << "angleFromSelf: " << self.angleFromSelf() << std::endl; ADD_FEATURE(ball.velValid() ? FEAT_MAX : FEAT_MIN);
if (ball.velValid()) {
// SeverParam lists ballSpeedMax a 2.7 which is too low
ADD_NORM_FEATURE(ball.vel().r(), 0., observedBallSpeedMax);
addAngFeature(ball.vel().th());
} else {
ADD_FEATURE(0);
ADD_FEATURE(0);
ADD_FEATURE(0);
}
assert(featIndx == num_basic_features); assert(featIndx == num_basic_features);
...@@ -330,15 +392,16 @@ void Agent::updateStateFeatures() { ...@@ -330,15 +392,16 @@ void Agent::updateStateFeatures() {
PlayerObject* teammate = *it; PlayerObject* teammate = *it;
if (teammate->pos().x > 0 && teammate->unum() > 0 && if (teammate->pos().x > 0 && teammate->unum() > 0 &&
detected_teammates < numTeammates) { detected_teammates < numTeammates) {
// Angle dist to teammate. Teammate's body angle and velocity. addPlayerFeatures(*teammate, self_pos, self_ang);
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++; detected_teammates++;
} }
} }
// Add zero features for any missing teammates
for (int i=detected_teammates; i<numTeammates; ++i) {
for (int j=0; j<features_per_player; ++j) {
ADD_FEATURE(0);
}
}
// ======================== OPPONENT FEATURES ======================== // // ======================== OPPONENT FEATURES ======================== //
int detected_opponents = 0; int detected_opponents = 0;
...@@ -348,34 +411,72 @@ void Agent::updateStateFeatures() { ...@@ -348,34 +411,72 @@ void Agent::updateStateFeatures() {
PlayerObject* opponent = *it; PlayerObject* opponent = *it;
if (opponent->pos().x > 0 && opponent->unum() > 0 && if (opponent->pos().x > 0 && opponent->unum() > 0 &&
detected_opponents < numOpponents) { detected_opponents < numOpponents) {
// Angle dist to opponent. Opponents's body angle and velocity. addPlayerFeatures(*opponent, self_pos, self_ang);
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++; detected_opponents++;
} }
} }
// Add zero features for any missing opponents
// Add zeros for missing teammates or opponents. This should only for (int i=detected_opponents; i<numOpponents; ++i) {
// happen during initialization. for (int j=0; j<features_per_player; ++j) {
for (int i=featIndx; i<numFeatures; ++i) {
ADD_FEATURE(0); ADD_FEATURE(0);
} }
}
assert(featIndx == numFeatures); assert(featIndx == numFeatures);
for (int i=0; i<numFeatures; ++i) {
if (feature_vec[i] < FEAT_MIN || feature_vec[i] > FEAT_MAX) {
std::cout << "Invalid Feature! Indx:" << i << " Val:" << feature_vec[i] << std::endl;
exit(1);
}
}
}
void Agent::addAngFeature(const rcsc::AngleDeg& ang) {
ADD_FEATURE(ang.sin());
ADD_FEATURE(ang.cos());
}
void Agent::addDistFeature(float dist, float maxDist) {
float proximity = 1.f - std::max(0.f, std::min(1.f, dist/maxDist));
ADD_NORM_FEATURE(proximity, 0., 1.);
} }
// Add the angle and distance to the landmark to the feature_vec // Add the angle and distance to the landmark to the feature_vec
void Agent::addLandmarkFeature(const rcsc::Vector2D& landmark, void Agent::addLandmarkFeatures(const rcsc::Vector2D& landmark,
const rcsc::Vector2D& self_pos) { const rcsc::Vector2D& self_pos,
const rcsc::AngleDeg& self_ang) {
if (self_pos == Vector2D::INVALIDATED) {
ADD_FEATURE(0);
ADD_FEATURE(0);
ADD_FEATURE(0);
} else {
Vector2D vec_to_landmark = landmark - self_pos; Vector2D vec_to_landmark = landmark - self_pos;
ADD_FEATURE(vec_to_landmark.th().degree()); addAngFeature(self_ang - vec_to_landmark.th());
ADD_FEATURE(vec_to_landmark.r()); addDistFeature(vec_to_landmark.r(), maxHFORadius);
}
}
void Agent::addPlayerFeatures(rcsc::PlayerObject& player,
const rcsc::Vector2D& self_pos,
const rcsc::AngleDeg& self_ang) {
assert(player.posValid());
// Angle dist to player.
addLandmarkFeatures(player.pos(), self_pos, self_ang);
// Player's body angle
addAngFeature(player.body());
if (player.velValid()) {
// Player's speed
ADD_NORM_FEATURE(player.vel().r(), 0., observedPlayerSpeedMax);
// Player's velocity direction
addAngFeature(player.vel().th());
} else {
ADD_FEATURE(0);
ADD_FEATURE(0);
ADD_FEATURE(0);
}
} }
void Agent::startServer() { void Agent::startServer(int server_port) {
std::cout << "Starting Server on Port " << server_port << std::endl; std::cout << "Starting Server on Port " << server_port << std::endl;
struct sockaddr_in serv_addr, cli_addr; struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); sockfd = socket(AF_INET, SOCK_STREAM, 0);
...@@ -457,7 +558,7 @@ hfo_status_t Agent::getGameStatus() { ...@@ -457,7 +558,7 @@ hfo_status_t Agent::getGameStatus() {
*/ */
void Agent::actionImpl() { void Agent::actionImpl() {
if (!server_running) { if (!server_running) {
startServer(); startServer(server_port);
clientHandshake(); clientHandshake();
} }
......
...@@ -90,28 +90,57 @@ protected: ...@@ -90,28 +90,57 @@ protected:
// Get the current game status // Get the current game status
hfo_status_t getGameStatus(); hfo_status_t getGameStatus();
// Encodes an angle feature as the sin and cosine of that angle,
// effectively transforming a single angle into two features.
void addAngFeature(const rcsc::AngleDeg& ang);
// Encodes a proximity feature which is defined by a distance as
// well as a maximum possible distance, which acts as a
// normalizer. Encodes the distance as [0-far, 1-close]. Ignores
// distances greater than maxDist or less than 0.
void addDistFeature(float dist, float maxDist);
// Add the angle and distance to the landmark to the feature_vec // Add the angle and distance to the landmark to the feature_vec
void addLandmarkFeature(const rcsc::Vector2D& landmark, void addLandmarkFeatures(const rcsc::Vector2D& landmark,
const rcsc::Vector2D& self_pos); const rcsc::Vector2D& self_pos,
const rcsc::AngleDeg& self_ang);
// Add features corresponding to another player.
void addPlayerFeatures(rcsc::PlayerObject& player,
const rcsc::Vector2D& self_pos,
const rcsc::AngleDeg& self_ang);
// Start the server and listen for a connection.
void startServer(int server_port=6008);
int numTeammates; // Transmit information to the client and ensure it can recieve.
int numOpponents; void clientHandshake();
protected:
int numTeammates; // Number of teammates in HFO
int numOpponents; // Number of opponents in HFO
bool playingOffense; // Are we playing offense or defense? bool playingOffense; // Are we playing offense or defense?
int numFeatures; // Total number of features int numFeatures; // Total number of features
// Number of features for non-player objects. Clearly this is the answer. // Number of features for non-player objects.
const static int num_basic_features = 42; const static int num_basic_features = 58;
// Number of features for each player or opponent in game. // Number of features for each player or opponent in game.
const static int features_per_player = 5; const static int features_per_player = 8;
std::vector<float> feature_vec; // Contains the current features
int featIndx; // Feature being populated int featIndx; // Feature being populated
const static int server_port = 6008; std::vector<float> feature_vec; // Contains the current features
long lastTrainerMessageTime; // Last time the trainer sent a message
bool episode_start; // True only in the timestep that the game is starting
// Start the server and listen for a connection. // Observed values of some parameters.
virtual void startServer(); const static float observedSelfSpeedMax = 0.46;
// Transmit information to the client and ensure it can recieve. const static float observedPlayerSpeedMax = 0.75;
virtual void clientHandshake(); const static float observedStaminaMax = 8000.;
const static float observedBallSpeedMax = 3.0;
float maxHFORadius; // Maximum possible distance in HFO playable region
// Useful measures defined by the Server Parameters
float pitchLength, pitchWidth, pitchHalfLength, pitchHalfWidth,
goalHalfWidth, penaltyAreaLength, penaltyAreaWidth;
long lastTrainerMessageTime; // Last time the trainer sent a message
int server_port; // Port to start the server on
bool server_running; // Is the server running?
int sockfd, newsockfd; // Server sockets
private: private:
bool doPreprocess(); bool doPreprocess();
...@@ -122,8 +151,6 @@ protected: ...@@ -122,8 +151,6 @@ protected:
Communication::Ptr M_communication; Communication::Ptr M_communication;
FieldEvaluator::ConstPtr M_field_evaluator; FieldEvaluator::ConstPtr M_field_evaluator;
ActionGenerator::ConstPtr M_action_generator; ActionGenerator::ConstPtr M_action_generator;
bool server_running; // Is the server running?
int sockfd, newsockfd; // Server sockets
}; };
#endif #endif
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