Commit 0104ff75 authored by Matthew Hausknecht's avatar Matthew Hausknecht

Merge pull request #18 from sanmit/master

Updated referee model to broadcast last player to touch the ball
parents 2687b320 63c3fb68
......@@ -215,18 +215,23 @@ class Trainer(object):
assert body[0] == 'referee', 'Expected referee message.'
_,ts,event = body
self._frame = int(ts)
if event == 'GOAL':
endOfTrial = False
if 'GOAL' in event:
self._numGoals += 1
self._numGoalFrames += self._frame - self._lastTrialStart
endOfTrial = True
elif event == 'OUT_OF_BOUNDS':
self._numBallsOOB += 1
elif event == 'CAPTURED_BY_DEFENSE':
endOfTrial = True
elif 'CAPTURED_BY_DEFENSE' in event:
self._numBallsCaptured += 1
endOfTrial = True
elif event == 'OUT_OF_TIME':
self._numOutOfTime += 1
endOfTrial = True
elif event == 'HFO_FINISHED':
self._done = True
if event in {'GOAL','OUT_OF_BOUNDS','CAPTURED_BY_DEFENSE','OUT_OF_TIME'}:
if endOfTrial:
self._numTrials += 1
print 'EndOfTrial: %d / %d %d %s'%\
(self._numGoals, self._numTrials, self._frame, event)
......
......@@ -42,9 +42,9 @@ if __name__ == '__main__':
print 'Episode', episode, 'ended with',
# Check what the outcome of the episode was
if status == HFO_Status.GOAL:
print 'goal'
print 'goal', hfo.playerOnBall().unum
elif status == HFO_Status.CAPTURED_BY_DEFENSE:
print 'captured by defense'
print 'captured by defense', hfo.playerOnBall().unum
elif status == HFO_Status.OUT_OF_BOUNDS:
print 'out of bounds'
elif status == HFO_Status.OUT_OF_TIME:
......
......@@ -19,21 +19,21 @@ if __name__ == '__main__':
# Connect to the agent server on port 6000 with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
hfo.connectToAgentServer(port, HFO_Features.HIGH_LEVEL_FEATURE_SET)
# Play 5 episodes
for episode in xrange(5):
# Play 100 episodes
for episode in xrange(100):
status = HFO_Status.IN_GAME
while status == HFO_Status.IN_GAME:
# Grab the state features from the environment
features = hfo.getState()
# Take an action and get the current game status
hfo.act(HFO_Actions.DASH, 20.0, 0)
hfo.step()
status = hfo.step()
print 'Episode', episode, 'ended with',
# Check what the outcome of the episode was
if status == HFO_Status.GOAL:
print 'goal'
print 'goal', hfo.playerOnBall().unum
elif status == HFO_Status.CAPTURED_BY_DEFENSE:
print 'captured by defense'
print 'captured by defense', hfo.playerOnBall().unum
elif status == HFO_Status.OUT_OF_BOUNDS:
print 'out of bounds'
elif status == HFO_Status.OUT_OF_TIME:
......
......@@ -36,6 +36,26 @@ int main(int argc, char** argv) {
// Advance the environment and get the game status
status = hfo.step();
}
// Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: ";
switch (status) {
case GOAL:
cout << "goal " << hfo.playerOnBall().unum << endl;
break;
case CAPTURED_BY_DEFENSE:
cout << "captured by defense " << hfo.playerOnBall().unum << endl;
break;
case OUT_OF_BOUNDS:
cout << "out of bounds" << endl;
break;
case OUT_OF_TIME:
cout << "out of time" << endl;
break;
default:
cout << "Unknown status " << status << endl;
exit(1);
}
}
hfo.act(QUIT);
};
......@@ -46,6 +46,25 @@ int main(int argc, char** argv) {
// Advance the environment and get the game status
status = hfo.step();
}
// Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: ";
switch (status) {
case GOAL:
cout << "goal " << hfo.playerOnBall().unum << endl;
break;
case CAPTURED_BY_DEFENSE:
cout << "captured by defense " << hfo.playerOnBall().unum << endl;
break;
case OUT_OF_BOUNDS:
cout << "out of bounds" << endl;
break;
case OUT_OF_TIME:
cout << "out of time" << endl;
break;
default:
cout << "Unknown status " << status << endl;
exit(1);
}
}
hfo.act(QUIT);
};
import socket, struct, thread, time
import socket, struct, thread, time, collections
class HFO_Features:
''' An enum of the possible HFO feature sets. For descriptions see
......@@ -30,10 +30,17 @@ class HFO_Actions:
DASH, TURN, TACKLE, KICK, KICK_TO, MOVE_TO, DRIBBLE_TO, INTERCEPT, \
MOVE, SHOOT, PASS, DRIBBLE, CATCH, NOOP, QUIT = range(15)
HFO_Player = collections.namedtuple("HFO_Player", "side unum")
class HFO_Status:
''' Current status of the HFO game. '''
IN_GAME, GOAL, CAPTURED_BY_DEFENSE, OUT_OF_BOUNDS, OUT_OF_TIME = range(5)
class HFO_SideID:
''' Team side for a player or object'''
RIGHT, NEUTRAL, LEFT = range(-1, 2)
class HFOEnvironment(object):
''' The HFOEnvironment is designed to be the main point of contact
......@@ -47,6 +54,7 @@ class HFOEnvironment(object):
self.requested_action = None # Action to execute and parameters
self.say_msg = '' # Outgoing message to say
self.hear_msg = '' # Incoming heard message
self.player_on_ball = None # Current player holding the ball
def NumParams(self, action_type):
''' Returns the number of required parameters for each action type. '''
......@@ -117,8 +125,9 @@ class HFOEnvironment(object):
# Send what we recieved
self.socket.send(struct.pack("i", self.numFeatures))
# Get the current game status
data = self.socket.recv(struct.calcsize("i"))
status = struct.unpack("i", data)[0]
data = self.socket.recv(struct.calcsize("iii"))
status, side, unum = struct.unpack("iii", data)
self.player_on_ball = HFO_Player(side,unum)
assert status == HFO_Status.IN_GAME, "Status check failed"
print '[Agent Client] Handshake complete'
......@@ -144,6 +153,10 @@ class HFOEnvironment(object):
''' Receive incoming communications from other players. '''
return self.hear_msg
def playerOnBall(self):
''' Get the current player holding the ball'''
return self.player_on_ball
def step(self):
''' Indicates the agent is done and the environment should
progress. Returns the game status after the step'''
......@@ -157,8 +170,9 @@ class HFOEnvironment(object):
self.say_msg = ''
# Get the current game status
data = self.socket.recv(struct.calcsize("i"))
status = struct.unpack("i", data)[0]
data = self.socket.recv(struct.calcsize("iii"))
status, side, unum = struct.unpack("iii", data)
self.player_on_ball = HFO_Player(side,unum)
# Get the next state features
state_data = self.socket.recv(struct.calcsize('f')*self.numFeatures)
......
......@@ -248,17 +248,19 @@ void HFOEnvironment::handshakeAgentServer(feature_set_t feature_set) {
exit(1);
}
// Recieve the game status
status_t status;
if (recv(sockfd, &status, sizeof(status_t), 0) < 0) {
perror("[Agent Client] ERROR recv from socket");
int game_status[3];
if (recv(sockfd, &(game_status[0]), 3 * sizeof(int), 0) < 0) {
perror("[Agent Client] ERROR receiving game status from socket");
close(sockfd);
exit(1);
}
if (status != IN_GAME) {
if (game_status[0] != IN_GAME) {
std::cout << "[Agent Client] Handshake failed: status check." << std::endl;
close(sockfd);
exit(1);
}
player_on_ball.side = (SideID)game_status[1];
player_on_ball.unum = game_status[2];
std::cout << "[Agent Client] Handshake complete" << std::endl;
}
......@@ -289,6 +291,10 @@ std::string HFOEnvironment::hear() {
return hear_msg;
}
Player HFOEnvironment::playerOnBall(){
return player_on_ball;
}
status_t HFOEnvironment::step() {
status_t game_status;
......@@ -328,14 +334,19 @@ status_t HFOEnvironment::step() {
say_msg.clear();
// Get the game status
if (recv(sockfd, &game_status, sizeof(status_t), 0) < 0) {
perror("[Agent Client] ERROR recieving from socket");
int full_status[3];
if (recv(sockfd, &(full_status[0]), 3 * sizeof(int), 0) < 0) {
perror("[Agent Client] ERROR receiving game status from socket");
close(sockfd);
exit(1);
}
game_status = (status_t)full_status[0];
player_on_ball.side = (SideID)full_status[1];
player_on_ball.unum = full_status[2];
// Get the next game state
if (recv(sockfd, &(feature_vec.front()), numFeatures * sizeof(float), 0) < 0) {
perror("[Agent Client] ERROR recieving state features from socket");
perror("[Agent Client] ERROR receiving state features from socket");
close(sockfd);
exit(1);
}
......@@ -345,7 +356,7 @@ status_t HFOEnvironment::step() {
// Message length
uint32_t msgLength;
if (recv(sockfd, &msgLength, sizeof(uint32_t), 0) < 0){
perror("[Agent Client] ERROR recieving hear message length from socket");
perror("[Agent Client] ERROR receiving hear message length from socket");
close(sockfd);
exit(1);
}
......@@ -354,7 +365,7 @@ status_t HFOEnvironment::step() {
std::vector<char> hearMsgBuffer;
hearMsgBuffer.resize(msgLength);
if (recv(sockfd, &hearMsgBuffer[0], msgLength, 0) < 0){
perror("[Agent Client] ERROR recieving hear message from socket");
perror("[Agent Client] ERROR receiving hear message from socket");
close(sockfd);
exit(1);
}
......
......@@ -52,6 +52,12 @@ enum status_t
OUT_OF_TIME // Trial has ended due to time limit
};
enum SideID {
RIGHT = -1,
NEUTRAL = 0,
LEFT = 1
};
// Configuration of the HFO domain including the team names and player
// numbers for each team. This struct is populated by ParseConfig().
struct Config {
......@@ -63,6 +69,11 @@ struct Config {
std::vector<int> defense_nums; // Defensive player numbers
};
struct Player {
SideID side;
int unum;
};
class HFOEnvironment {
public:
HFOEnvironment();
......@@ -92,6 +103,9 @@ class HFOEnvironment {
virtual void say(const std::string& message);
virtual std::string hear();
// Get the current player holding the ball
virtual Player playerOnBall();
// Indicates the agent is done and the environment should
// progress. Returns the game status after the step
virtual status_t step();
......@@ -103,6 +117,7 @@ class HFOEnvironment {
action_t requested_action; // Action requested
std::vector<float> action_params; // Action parameters
std::string say_msg, hear_msg; // Messages to hear/say
Player player_on_ball;
// Handshake with the agent server to ensure data is being correctly
// passed. Also sets the number of features to expect.
......
......@@ -364,28 +364,52 @@ FeatureExtractor* Agent::getFeatureExtractor(feature_set_t feature_set_indx,
}
}
status_t Agent::getGameStatus(const rcsc::AudioSensor& audio_sensor,
std::vector<int> Agent::getGameStatus(const rcsc::AudioSensor& audio_sensor,
long& lastTrainerMessageTime) {
std::vector<int> status;
status_t game_status = IN_GAME;
int playerIndex = -1; // Keeps track of which defender stopped the shot
int playerTeam = hfo::LEFT;
if (audio_sensor.trainerMessageTime().cycle() > lastTrainerMessageTime) {
const std::string& message = audio_sensor.trainerMessage();
bool recognized_message = true;
if (message.compare("GOAL") == 0) {
if (message.find("GOAL") != std::string::npos){
playerIndex = atoi((message.substr(message.find("-")+1)).c_str());
playerTeam = hfo::LEFT;
game_status = GOAL;
} else if (message.compare("CAPTURED_BY_DEFENSE") == 0) {
} else if (message.find("CAPTURED_BY_DEFENSE") != std::string::npos) {
playerIndex = atoi((message.substr(message.find("-")+1)).c_str());
playerTeam = hfo::RIGHT;
game_status = CAPTURED_BY_DEFENSE;
} else if (message.compare("OUT_OF_BOUNDS") == 0) {
game_status = OUT_OF_BOUNDS;
} else if (message.compare("OUT_OF_TIME") == 0) {
game_status = OUT_OF_TIME;
} else {
} else if (message.find("IN_GAME") != std::string::npos){
switch (message.at(message.find("-")+1)){
case 'L':
playerTeam = hfo::LEFT;
break;
case 'R':
playerTeam = hfo::RIGHT;
break;
case 'U':
playerTeam = hfo::NEUTRAL;
break;
}
playerIndex = atoi((message.substr(message.find("-")+2)).c_str());
}
else {
recognized_message = false;
}
if (recognized_message) {
lastTrainerMessageTime = audio_sensor.trainerMessageTime().cycle();
}
}
return game_status;
status.push_back(game_status);
status.push_back(playerTeam);
status.push_back(playerIndex);
return status;
}
/*!
......@@ -403,9 +427,9 @@ void Agent::actionImpl() {
}
// Update and send the game status
status_t game_status = getGameStatus(audioSensor(), lastTrainerMessageTime);
if (send(newsockfd, &game_status, sizeof(int), 0) < 0) {
perror("[Agent Server] ERROR sending from socket");
std::vector<int> game_status = getGameStatus(audioSensor(), lastTrainerMessageTime);
if (send(newsockfd, &(game_status.front()), game_status.size() * sizeof(int), 0) < 0){
perror("[Agent Server] ERROR sending game state from socket");
close(sockfd);
exit(1);
}
......@@ -416,7 +440,7 @@ void Agent::actionImpl() {
#ifdef ELOG
if (config().record()) {
elog.addText(Logger::WORLD, "GameStatus %d", game_status);
elog.addText(Logger::WORLD, "GameStatus %d", game_status[0]);
elog.flush();
feature_extractor->LogFeatures();
}
......
......@@ -42,8 +42,8 @@ public:
virtual ~Agent();
virtual FieldEvaluator::ConstPtr getFieldEvaluator() const;
// Get the current game status
static hfo::status_t getGameStatus(const rcsc::AudioSensor& audio_sensor,
// Get the current game status, and the side and uniform number of the player holding the ball
static std::vector<int> getGameStatus(const rcsc::AudioSensor& audio_sensor,
long& lastTrainerMessageTime);
// Returns the feature extractor corresponding to the feature_set_t
......
......@@ -269,9 +269,9 @@ SamplePlayer::actionImpl()
hfo::LOW_LEVEL_FEATURE_SET, num_teammates, num_opponents, playing_offense);
}
} else {
hfo::status_t game_status = Agent::getGameStatus(
std::vector<int> game_status = Agent::getGameStatus(
audioSensor(), lastTrainerMessageTime);
elog.addText(Logger::WORLD, "GameStatus %d", game_status);
elog.addText(Logger::WORLD, "GameStatus %d", game_status[0]);
elog.flush();
feature_extractor->ExtractFeatures(this->world());
feature_extractor->LogFeatures();
......
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