Commit b146090a authored by Matthew Hausknecht's avatar Matthew Hausknecht

Major overhaul - agents now connect directly to server.

parent 45572095
......@@ -85,7 +85,7 @@ set(PLAYER_CPP bhv_basic_move.cpp bhv_basic_offensive_kick.cpp
role_side_back.cpp role_side_forward.cpp role_side_half.cpp
role_keepaway_keeper.cpp role_keepaway_taker.cpp
sample_communication.cpp keepaway_communication.cpp
sample_field_evaluator.cpp sample_player.cpp strategy.cpp)
sample_field_evaluator.cpp sample_player.cpp strategy.cpp agent.cpp)
foreach(src ${PLAYER_CPP})
list(APPEND PLAYER_SOURCES ${SOURCE_DIR}/${src})
......@@ -95,7 +95,7 @@ file(GLOB CHAIN_ACTION_SOURCES ${SOURCE_DIR}/chain_action/*.cpp)
list(APPEND LINK_LIBS rcsc_agent rcsc_geom rcsc_param rcsc_ann
rcsc_net rcsc_gz rcsc_time rcsc_rcg)
add_library(player_chain_action STATIC ${PLAYER_SOURCES} ${CHAIN_ACTION_SOURCES})
add_library(player_chain_action SHARED ${PLAYER_SOURCES} ${CHAIN_ACTION_SOURCES})
add_executable(sample_coach ${SOURCE_DIR}/main_coach.cpp ${SOURCE_DIR}/sample_coach.cpp)
add_executable(sample_player ${SOURCE_DIR}/HFO.cpp ${SOURCE_DIR}/main_player.cpp ${SOURCE_DIR}/sample_player.cpp ${SOURCE_DIR}/agent.cpp)
add_executable(sample_trainer ${SOURCE_DIR}/main_trainer.cpp ${SOURCE_DIR}/sample_trainer.cpp)
......@@ -110,18 +110,25 @@ add_library(hfo-lib SHARED ${SOURCE_DIR}/HFO.hpp ${SOURCE_DIR}/HFO.cpp)
set_target_properties(hfo-lib PROPERTIES OUTPUT_NAME hfo)
set_target_properties(hfo-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_library(hfo-c-lib SHARED ${CMAKE_CURRENT_SOURCE_DIR}/hfo/hfo_c_wrapper.cpp ${SOURCE_DIR}/HFO.cpp)
set_target_properties(hfo-c-lib PROPERTIES OUTPUT_NAME hfo_c)
set_target_properties(hfo-c-lib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/hfo)
add_dependencies(player_chain_action librcsc)
add_dependencies(sample_coach librcsc)
add_dependencies(sample_player librcsc)
add_dependencies(sample_trainer librcsc)
add_dependencies(agent librcsc)
add_dependencies(hfo-lib librcsc)
add_dependencies(hfo-lib player_chain_action)
add_dependencies(hfo-c-lib player_chain_action)
target_link_libraries(player_chain_action ${LINK_LIBS})
target_link_libraries(sample_coach ${LINK_LIBS})
target_link_libraries(sample_player ${LINK_LIBS} player_chain_action)
target_link_libraries(sample_trainer ${LINK_LIBS})
target_link_libraries(agent ${LINK_LIBS} player_chain_action)
target_link_libraries(hfo-lib ${LINK_LIBS} player_chain_action)
target_link_libraries(hfo-c-lib ${LINK_LIBS} player_chain_action)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_executable(hfo_example_agent ${CMAKE_CURRENT_SOURCE_DIR}/example/hfo_example_agent.cpp)
......
......@@ -35,9 +35,9 @@ def main(args):
os.makedirs(args.logDir)
num_agents = args.offenseAgents + args.defenseAgents
binary_dir = os.path.dirname(os.path.realpath(__file__))
server_port = args.port + num_agents
coach_port = args.port + num_agents + 1
olcoach_port = args.port + num_agents + 2
server_port = args.port
coach_port = args.port + 1
olcoach_port = args.port + 2
serverCommand = os.path.join(binary_dir, SERVER_BIN)
serverOptions = ' server::port=%i server::coach_port=%i ' \
'server::olcoach_port=%i server::coach=1 ' \
......
......@@ -47,7 +47,7 @@ class Trainer(object):
self._done = False # Are we finished?
self._agentPopen = [] # Agent's processes
self._npcPopen = [] # NPC's processes
self._connectedPlayers = []
self._connectedPlayers = [] # List of connected players
self.initMsgHandlers()
def launch_agent(self, agent_num, agent_ext_num, play_offense, port, wait_until_join=True):
......@@ -55,8 +55,6 @@ class Trainer(object):
Returns a Popen process object
"""
print 'Launch agent %s-%d'%(self._offenseTeamName if play_offense
else self._defenseTeamName, agent_num)
if play_offense:
assert self._numOffense > 0
team_name = self._offenseTeamName
......@@ -64,37 +62,24 @@ class Trainer(object):
# First offense number is reserved for inactive offensive goalie
internal_player_num = agent_num + 1
self._agentNumInt.append(internal_player_num)
numTeammates = self._numOffense - 1
numOpponents = self._numDefense
else:
assert self._numDefense > 0
team_name = self._defenseTeamName
self._agentTeams.append(team_name)
internal_player_num = agent_num
self._agentNumInt.append(internal_player_num)
numTeammates = self._numDefense - 1
numOpponents = self._numOffense
binary_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'teams', 'base')
binary_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'teams', 'base')
config_dir = os.path.join(binary_dir, 'config/formations-dt')
player_conf = os.path.join(binary_dir, '/config/player.conf')
agent_cmd = os.path.join(binary_dir, 'agent')
agent_cmd += ' -t %s -p %i --numTeammates %i --numOpponents %i' \
' --playingOffense %i --serverPort %i --log_dir %s' \
' --player-config %s --config_dir %s' \
%(team_name, self._serverPort, numTeammates,
numOpponents, play_offense, port, self._logDir,
player_conf, config_dir)
if agent_ext_num == 1:
agent_cmd += ' -g'
if self._record:
agent_cmd += ' --record'
# Comment next two lines to show output from agent.cpp and the server
kwargs = {'stdout':open('/dev/null', 'w'),
'stderr':open('/dev/null', 'w')}
p = subprocess.Popen(agent_cmd.split(' '), shell = False, **kwargs)
print("Waiting for player-controlled agent %s-%d: config_dir=%s, "\
"uniform_number=%d, server_port=%d, server_addr=%s, team_name=%s, "\
"play_goalie=%r"
% (self._offenseTeamName if play_offense else self._defenseTeamName,
agent_num, config_dir, agent_ext_num, self._serverPort, "localhost",
team_name, agent_ext_num==1))
if wait_until_join:
self.waitOnPlayer(agent_ext_num, play_offense)
return p
return None
def createTeam(self, requested_team_name, play_offense):
""" Given a team name, returns the team object. """
......@@ -198,6 +183,7 @@ class Trainer(object):
(self._numGoals, self._numTrials, self._frame, event)
self._numFrames += self._frame - self._lastTrialStart
self._lastTrialStart = self._frame
self.getConnectedPlayers()
def _hear(self, body):
""" Handle a hear message. """
......@@ -319,46 +305,37 @@ class Trainer(object):
def disconnectPlayer(self, player, player_num, on_offense):
"""Wait on a launched player to disconnect from the server. """
# print 'Disconnect %s-%d'%(self._offenseTeamName if on_offense
# else self._defenseTeamName, player_num)
team_name = self._offenseTeamName if on_offense else self._defenseTeamName
self.send('(disconnect_player %s %d)'%(team_name, player_num))
player.kill()
def waitOnPlayer(self, player_num, on_offense):
"""Wait on a launched player to connect and be reported by the
server.
"""
def getConnectedPlayers(self):
""" Get the list of connected players. Populates self._connectedPlayers. """
self._gotLook = False
self.send('(look)')
partial = ['ok','look']
self._numPlayers = 0
def f(body):
self._gotLook = True
del self._connectedPlayers[:]
for i in xrange(4, len(body)):
_,team,num = body[i][0][:3]
if (team, num) not in self._connectedPlayers:
self._connectedPlayers.append((team,num))
self.registerMsgHandler(f,*partial,quiet=True)
team_name = self._offenseTeamName if on_offense else self._defenseTeamName
while (team_name, str(player_num)) not in self._connectedPlayers:
while not self._gotLook:
self.listenAndProcess()
self.send('(look)')
self.ignoreMsg(*partial,quiet=True)
def checkIfAllPlayersConnected(self):
""" Returns true if all players are connected. """
print 'Checking all players are connected'
self.send('(look)')
partial = ['ok','look']
self._numPlayers = 0
def f(x):
self._numPlayers = len(x) - 4 # -4 for time, ball, goal_l, and goal_r
self.send('(look)')
self.registerMsgHandler(f,*partial,quiet=True)
while self._numPlayers != self._numOffense + self._numDefense:
self.listenAndProcess()
self.ignoreMsg(*partial,quiet=True)
def waitOnPlayer(self, player_num, on_offense):
""" Wait on a launched player to connect and be reported by the server. """
team_name = self._offenseTeamName if on_offense else self._defenseTeamName
while (team_name, str(player_num)) not in self._connectedPlayers:
self.getConnectedPlayers()
def allPlayersConnected(self):
""" Returns true all players are connected. """
return len(self._connectedPlayers) == self._numOffense + self._numDefense
def startGame(self):
""" Starts a game of HFO. """
......@@ -382,7 +359,7 @@ class Trainer(object):
"""
for p,name in necProcesses:
if p.poll() is not None:
if p is not None and p.poll() is not None:
print 'Something necessary closed (%s), exiting' % name
return False
return True
......@@ -434,15 +411,9 @@ class Trainer(object):
else:
self.disconnectPlayer(player, player_num, on_offense=False)
self.checkIfAllPlayersConnected()
if self._numAgents > 0:
print 'Agents awaiting your connections'
necOff = set([(self._offenseTeamName,str(x)) for x in sorted_offense_agent_unums])
necDef = set([(self._defenseTeamName,str(x)) for x in sorted_defense_agent_unums])
necAgents = necOff.union(necDef)
while self.checkLive(necProcesses) and self._agentReady != necAgents:
self.listenAndProcess()
print 'Checking all players connected'
while not self.allPlayersConnected():
self.getConnectedPlayers()
# Broadcast the HFO configuration
offense_nums = ' '.join([str(self.convertToExtPlayer(self._offenseTeamName, i))
......@@ -456,7 +427,7 @@ class Trainer(object):
offense_nums, defense_nums))
print 'Starting game'
self.startGame()
while self.checkLive(necProcesses) and not self._done:
while self.allPlayersConnected() and self.checkLive(necProcesses) and not self._done:
prevFrame = self._frame
self.listenAndProcess()
except TimeoutError:
......
......@@ -5,44 +5,72 @@
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
using namespace hfo;
// Before running this program, first Start HFO server:
// $./bin/HFO --offense-agents 1
// This agent is intended to be run as a part of the passing_agents.sh script
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = HIGH_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
#define PI 3.14159265
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
port = atoi(argv[1]);
if (argc > 2) {
unum = atoi(argv[1]);
port = atoi(argv[2]);
}
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(port, HIGH_LEVEL_FEATURE_SET);
// Play 5 episodes
for (int episode=0; ; episode++) {
int step = 0;
// Connect to the server and request feature set. See manual for
// more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
for (int episode=0; episode<10; episode++) {
int agent_on_ball = 7;
status_t status = IN_GAME;
while (status == IN_GAME) {
// Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState();
// Get any incoming communication
std::string msg = hfo.hear();
// Do something with incoming communication
cout << "HEARD: " << msg.c_str() << endl;
float target_x = sin((step % 360) * PI/180);
float target_y = cos((step % 360) * PI/180);
hfo.act(DRIBBLE_TO, target_x, target_y);
// Do something with outgoing communication
hfo.say("Message");
if (!msg.empty()) {
cout << "Agent-" << unum << " HEARD: " << msg.c_str() << endl;
if (msg == "Pass") {
agent_on_ball = unum;
}
}
float x_pos = feature_vec[0];
float y_pos = feature_vec[1];
float target_x = 0;
float target_y = unum == 11 ? .3 : -.3;
bool in_position = (pow(x_pos-target_x, 2) + pow(y_pos-target_y,2)) < .0005;
bool able_to_kick = feature_vec[5] > 0;
if (agent_on_ball == unum && in_position && able_to_kick) {
int teammate_unum = unum == 11 ? 7 : 11;
float teammate_x_pos = 0;
float teammate_y_pos = -target_y;
hfo.act(KICK_TO, teammate_x_pos, teammate_y_pos, 2.0);
hfo.say("Pass");
agent_on_ball = teammate_unum;
} else {
float dist_to_ball = feature_vec[3];
float dist_to_teammate = feature_vec[13];
action_t action = unum == agent_on_ball ? DRIBBLE_TO : MOVE_TO;
hfo.act(action, target_x, target_y);
}
// Advance the environment and get the game status
status = hfo.step();
step+=2;
}
// Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;;
}
hfo.act(QUIT);
};
#!/usr/bin/env python
# encoding: utf-8
import sys
# Before running this program, first Start HFO server:
# $> ./bin/HFO --offense-agents 1
# First Start the server: $> bin/start.py
import sys
from hfo import *
if __name__ == '__main__':
port = 6000
if len(sys.argv) > 1:
port = int(sys.argv[1])
try:
from hfo import *
except:
print 'Failed to import hfo. To install hfo, in the HFO directory'\
' run: \"pip install .\"'
exit()
# Create the HFO Environment
hfo_env = hfo.HFOEnvironment()
# Connect to the agent server on port 6000 with the specified
hfo = hfo.HFOEnvironment()
# Connect to the server with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
hfo_env.connectToAgentServer(port, HFO_Features.HIGH_LEVEL_FEATURE_SET)
# Play 5 episodes
for episode in xrange(5):
status = HFO_Status.IN_GAME
while status == HFO_Status.IN_GAME:
hfo.connectToServer(HIGH_LEVEL_FEATURE_SET,
'bin/teams/base/config/formations-dt', 11, 6000,
'localhost', 'base_left', False)
for episode in xrange(10):
status = IN_GAME
while status == IN_GAME:
# Grab the state features from the environment
features = hfo_env.getState()
features = hfo.getState()
# Get any incoming communication
msg = hfo_env.hear()
msg = hfo.hear()
# Do something with incoming communication
print 'Heard: ', msg
# Take an action and get the current game status
hfo_env.act(HFO_Actions.DASH, 20.0, 0)
hfo.act(DASH, 20.0, 0)
# Do something with outgoing communication
hfo_env.say('Message')
status = hfo_env.step()
print 'Episode', episode, 'ended with',
# Check what the outcome of the episode was
if status == HFO_Status.GOAL:
print 'goal', hfo.playerOnBall().unum
elif status == HFO_Status.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:
print 'out of time'
else:
print 'Unknown status', status
exit()
# Cleanup when finished
hfo_env.cleanup()
hfo.say('Message')
status = hfo.step()
print 'Episode', episode, 'ended with', hfo.statusToString(status)
#!/usr/bin/env python
# encoding: utf-8
# First Start the server: $> bin/start.py
import random, threading, argparse
try:
from hfo import *
except:
print 'Failed to import hfo. To install hfo, in the HFO directory'\
' run: \"pip install .\"'
exit()
# Before running this program, first Start HFO server:
# $> ./bin/HFO --offense-agents 1
def get_random_action():
"""Returns a random high-level action. Pass is omitted for simplicity."""
high_lv_actions = [HFO_Actions.SHOOT, HFO_Actions.DRIBBLE]
return random.choice(high_lv_actions)
def play_hfo(num):
""" Method called by a thread to play 5 games of HFO """
hfo_env = hfo.HFOEnvironment()
hfo_env.connectToAgentServer(6000 + num, HFO_Features.HIGH_LEVEL_FEATURE_SET)
try:
for episode in xrange(5):
status = HFO_Status.IN_GAME
while status == HFO_Status.IN_GAME:
state = hfo_env.getState()
if state[5] == 1: #state[5] is 1 when player has the ball
hfo_env.act(get_random_action())
else:
hfo_env.act(HFO_Actions.MOVE)
status = hfo_env.step()
except:
pass
finally:
print "Agent " + str(num) + " exiting."
hfo_env.cleanup()
import random
from hfo import *
def main():
parser = argparse.ArgumentParser()
parser.add_argument('num_agents', type=int, help='Number of agents to start. '\
'NOTE: server must be started with this number of agents.')
args = parser.parse_args()
for i in xrange(args.num_agents):
t = threading.Thread(target=play_hfo, args=(i,))
t.start()
# Create the HFO Environment
hfo = HFOEnvironment()
# Connect to the server with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
hfo.connectToServer(HIGH_LEVEL_FEATURE_SET,
'bin/teams/base/config/formations-dt', 11, 6000,
'localhost', 'base_left', False)
for episode in xrange(10):
status = IN_GAME
while status == IN_GAME:
state = hfo.getState()
if state[5] == 1: # State[5] is 1 when the player can kick the ball
hfo.act(random.choice([SHOOT, DRIBBLE]))
else:
hfo.act(MOVE)
status = hfo.step()
print 'Episode', episode, 'ended with', hfo.statusToString(status)
if __name__ == '__main__':
main()
......@@ -7,14 +7,24 @@ using namespace std;
using namespace hfo;
// Before running this program, first Start HFO server:
// $./bin/start.py --offense-agents 1
// $> ./bin/HFO --offense-agents 1
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = LOW_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
int main() {
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(6000, LOW_LEVEL_FEATURE_SET);
// Connect to the server and request low-level feature set. See
// manual for more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
// Play 5 episodes
for (int episode=0; episode<5; episode++) {
status_t status = IN_GAME;
......@@ -27,23 +37,8 @@ int main() {
status = hfo.step();
}
// Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: ";
switch (status) {
case GOAL:
cout << "goal" << endl;
break;
case CAPTURED_BY_DEFENSE:
cout << "captured by defense" << 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);
}
cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;;
}
hfo.act(QUIT);
};
#!/usr/bin/env python
# encoding: utf-8
import sys
# Before running this program, first Start HFO server:
# $> ./bin/HFO --offense-agents 1
from hfo import *
# First Start the server: $> bin/start.py
if __name__ == '__main__':
port = 6000
if len(sys.argv) > 1:
port = int(sys.argv[1])
try:
from hfo import *
except:
print 'Failed to import hfo. To install hfo, in the HFO directory'\
' run: \"pip install .\"'
exit()
# Create the HFO Environment
hfo = hfo.HFOEnvironment()
# Connect to the agent server on port 6000 with the specified
hfo = HFOEnvironment()
# Connect to the server with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
hfo.connectToAgentServer(port, HFO_Features.HIGH_LEVEL_FEATURE_SET)
# Play 100 episodes
for episode in xrange(100):
status = HFO_Status.IN_GAME
while status == HFO_Status.IN_GAME:
hfo.connectToServer(LOW_LEVEL_FEATURE_SET,
'bin/teams/base/config/formations-dt', 11, 6000,
'localhost', 'base_left', False)
for episode in xrange(10):
status = IN_GAME
while 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.act(DASH, 20.0, 0)
status = hfo.step()
print 'Episode', episode, 'ended with',
# Check what the outcome of the episode was
if status == HFO_Status.GOAL:
print 'goal', hfo.playerOnBall().unum
elif status == HFO_Status.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:
print 'out of time'
else:
print 'Unknown status', status
exit()
# Cleanup when finished
hfo.cleanup()
print 'Episode', episode, 'ended with', hfo.statusToString(status)
......@@ -9,6 +9,15 @@ using namespace hfo;
// Before running this program, first Start HFO server:
// $./bin/HFO --offense-agents 1
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = HIGH_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
// Returns a random high-level action
action_t get_random_high_lv_action() {
action_t action_indx = (action_t) ((rand() % 5) + MOVE);
......@@ -16,17 +25,13 @@ action_t get_random_high_lv_action() {
}
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
port = atoi(argv[1]);
}
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(port, HIGH_LEVEL_FEATURE_SET);
// Play 5 episodes
for (int episode=0; ; episode++) {
// Connect to the server and request high-level feature set. See
// manual for more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
for (int episode=0; episode<10; episode++) {
status_t status = IN_GAME;
while (status == IN_GAME) {
// Get the vector of state features for the current state
......@@ -36,26 +41,9 @@ 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);
}
cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;
}
hfo.act(QUIT);
};
......@@ -9,6 +9,15 @@ using namespace hfo;
// Before running this program, first Start HFO server:
// $./bin/HFO --offense-agents 1
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = LOW_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
float arg1, arg2;
// Returns a random low-level action
......@@ -40,16 +49,12 @@ action_t get_random_low_lv_action() {
}
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
port = atoi(argv[1]);
}
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(port, LOW_LEVEL_FEATURE_SET);
// Play 5 episodes
// Connect to the server and request low-level feature set. See
// manual for more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
for (int episode=0; ; episode++) {
status_t status = IN_GAME;
while (status == IN_GAME) {
......@@ -57,8 +62,9 @@ int main(int argc, char** argv) {
const vector<float>& feature_vec = hfo.getState();
// Perform the action and recieve the current game status
hfo.act(get_random_low_lv_action(), arg1, arg2);
// Advance the environment and recieve current game status
status = hfo.step();
}
}
hfo.act(QUIT);
};
......@@ -7,23 +7,29 @@
using namespace std;
using namespace hfo;
#define PI 3.14159265
// This agent demonstrates the use of the DRIBBLE_TO action. Before
// running this program, first Start HFO server: $./bin/HFO
// --offense-agents 1
// running this program, first Start HFO server:
// $./bin/HFO --offense-agents 1
#define PI 3.14159265
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = HIGH_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
port = atoi(argv[1]);
}
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(port, HIGH_LEVEL_FEATURE_SET);
for (int episode=0; ; episode++) {
// Connect to the server and request low-level feature set. See
// manual for more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
for (int episode=0; episode<10; episode++) {
status_t status = IN_GAME;
int step = 0;
while (status == IN_GAME) {
......@@ -37,6 +43,9 @@ int main(int argc, char** argv) {
status = hfo.step();
step += 2;
}
// Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;;
}
hfo.act(QUIT);
};
......@@ -11,17 +11,23 @@ using namespace hfo;
// running this program, first Start HFO server: $./bin/HFO
// --offense-agents 1
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = HIGH_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
port = atoi(argv[1]);
}
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(port, HIGH_LEVEL_FEATURE_SET);
for (int episode=0; ; episode++) {
// Connect to the server and request low-level feature set. See
// manual for more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
for (int episode=0; episode < 10; episode++) {
status_t status = IN_GAME;
while (status == IN_GAME) {
// Get the vector of state features for the current state
......@@ -47,24 +53,8 @@ int main(int argc, char** argv) {
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);
}
cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;;
}
hfo.act(QUIT);
};
......@@ -9,19 +9,26 @@ using namespace hfo;
// This agent demonstrates the use of the MOVE_TO action to visit the
// corners of the play field. Before running this program, first Start
// HFO server: $./bin/HFO --offense-agents 1
// Server Connection Options. See printouts from bin/HFO.
feature_set_t features = HIGH_LEVEL_FEATURE_SET;
string config_dir = "bin/teams/base/config/formations-dt";
int unum = 11;
int port = 6001;
string server_addr = "localhost";
string team_name = "base_left";
bool goalie = false;
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
port = atoi(argv[1]);
}
// Create the HFO environment
HFOEnvironment hfo;
// Connect to the agent's server on port 6000 and request low-level
// feature set. See manual for more information on feature sets.
hfo.connectToAgentServer(port, HIGH_LEVEL_FEATURE_SET);
float target_x = 1.0;
float target_y = 1.0;
for (int episode=0; ; episode++) {
// Connect to the server and request feature set. See manual for
// more information on feature sets.
hfo.connectToServer(features, config_dir, unum, port, server_addr,
team_name, goalie);
float target_x = .82;
float target_y = .9;
for (int episode = 0; episode < 10; episode++) {
status_t status = IN_GAME;
if (episode % 2 != 0) {
target_x *= -1;
......@@ -37,6 +44,9 @@ 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: "
<< StatusToString(status) << std::endl;;
}
hfo.act(QUIT);
};
#!/bin/bash
./bin/HFO --offense-agents=2 --no-sync &
sleep 1
./example/communication_agent 7 6000 &
sleep 1
./example/communication_agent 11 6000 &
# The magic line
# $$ holds the PID for this script
# Negation means kill by process group id instead of PID
trap "kill -TERM -$$" SIGINT
wait
from hfo import *
from .hfo import *
This diff is collapsed.
#include "hfo_c_wrapper.h"
#ifndef __HFO_C_WRAPPER_H__
#define __HFO_C_WRAPPER_H__
#include <vector>
#include <HFO.hpp>
#include <common.hpp>
extern "C" {
hfo::HFOEnvironment* HFO_new() { return new hfo::HFOEnvironment(); }
void HFO_del(hfo::HFOEnvironment *hfo) { delete hfo; }
void connectToServer(hfo::HFOEnvironment *hfo,
hfo::feature_set_t feature_set,
char* config_dir,
int uniform_number,
int server_port,
char* server_addr,
char* team_name,
bool play_goalie) {
return hfo->connectToServer(feature_set, config_dir, uniform_number,
server_port, server_addr, team_name,
play_goalie);
}
int getStateSize(hfo::HFOEnvironment *hfo) { return hfo->getState().size(); }
void getState(hfo::HFOEnvironment *hfo, float *state_data) {
const float* state_features = hfo->getState().data();
memcpy(state_data, state_features, getStateSize(hfo) * sizeof(float));
}
void act(hfo::HFOEnvironment *hfo, hfo::action_t action, float* params) {
int n_params = NumParams(action);
std::vector<float> p(n_params);
for (int i=0; i<n_params; ++i) {
p[i] = params[i];
}
hfo->act(action, p);
}
void say(hfo::HFOEnvironment *hfo, const char *message) { hfo->say(message); }
const char* hear(hfo::HFOEnvironment *hfo) { return hfo->hear().c_str(); }
hfo::Player playerOnBall(hfo::HFOEnvironment *hfo) { return hfo->playerOnBall(); }
hfo::status_t step(hfo::HFOEnvironment *hfo) { return hfo->step(); }
int numParams(const hfo::action_t action) { return NumParams(action); }
const char* actionToString(const hfo::action_t action) {
return ActionToString(action).c_str();
}
const char* statusToString(const hfo::status_t status) {
return StatusToString(status).c_str();
}
}
#endif
import os
import setuptools
from distutils.core import setup, Extension
import os.path, sys
setuptools.setup(
name='hfo',
version='0.1.2',
packages=setuptools.find_packages(),
hfo_c_lib = 'hfo/libhfo_c.so'
if not os.path.isfile(hfo_c_lib):
print('ERROR: Unable to find required library: %s.'%(hfo_c_lib))
sys.exit()
module1 = Extension('hfo.hfo_c_wrapper',
libraries = ['hfo_c'],
include_dirs = ['src','src/chain_action','build/librcsc-prefix/src/librcsc'],
library_dirs = ['hfo'],
extra_compile_args=['-D__STDC_CONSTANT_MACROS'],
sources=['hfo/hfo_c_wrapper.cpp'])
setup(name = 'hfo',
version='0.1.5',
author='Matthew Hausknecht',
author_email='matthew.hausknecht@gmail.com',
description='Half Field Offense in 2D RoboCup Soccer.',
license='MIT',
ext_modules = [module1],
keywords=('Robocup '
'Half-field-offense '
),
......@@ -18,4 +28,7 @@ setuptools.setup(
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
)
# packages=find_packages(),
packages=['hfo'],
package_dir={'hfo': 'hfo'},
package_data={'hfo': ['libhfo_c.so']})
This diff is collapsed.
......@@ -3,101 +3,45 @@
#include <string>
#include <vector>
#include <rcsc/common/basic_client.h>
#include <rcsc/player/player_config.h>
#include <rcsc/player/world_model.h>
#include "agent.h"
#include "common.hpp"
namespace hfo {
// For descriptions of the different feature sets see
// https://github.com/mhauskn/HFO/blob/master/doc/manual.pdf
enum feature_set_t
{
LOW_LEVEL_FEATURE_SET,
HIGH_LEVEL_FEATURE_SET
};
// The actions available to the agent
enum action_t
{
DASH, // [Low-Level] Dash(power [0,100], direction [-180,180])
TURN, // [Low-Level] Turn(direction [-180,180])
TACKLE, // [Low-Level] Tackle(direction [-180,180])
KICK, // [Low-Level] Kick(power [0,100], direction [-180,180])
KICK_TO, // [Mid-Level] Kick_To(target_x [-1,1], target_y [-1,1], speed [0,3])
MOVE_TO, // [Mid-Level] Move(target_x [-1,1], target_y [-1,1])
DRIBBLE_TO, // [Mid-Level] Dribble(target_x [-1,1], target_y [-1,1])
INTERCEPT, // [Mid-Level] Intercept(): Intercept the ball
MOVE, // [High-Level] Move(): Reposition player according to strategy
SHOOT, // [High-Level] Shoot(): Shoot the ball
PASS, // [High-Level] Pass(teammate_unum [0,11]): Pass to the most open teammate
DRIBBLE, // [High-Level] Dribble(): Offensive dribble
CATCH, // [High-Level] Catch(): Catch the ball (Goalie only!)
NOOP, // Do nothing
QUIT // Special action to quit the game
};
// An Action consists of the discreet action as well as required
// arguments (parameters).
struct Action {
action_t action;
float arg1;
float arg2;
};
// Status of a HFO game
enum status_t
{
IN_GAME, // Game is currently active
GOAL, // A goal has been scored by the offense
CAPTURED_BY_DEFENSE, // The defense has captured the ball
OUT_OF_BOUNDS, // Ball has gone out of bounds
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 {
std::string offense_team_name;
std::string defense_team_name;
int num_offense; // Number of offensive players
int num_defense; // Number of defensive players
std::vector<int> offense_nums; // Offensive player numbers
std::vector<int> defense_nums; // Defensive player numbers
};
struct Player {
SideID side;
int unum;
};
class HFOEnvironment {
public:
HFOEnvironment();
~HFOEnvironment();
// Returns a string representation of an action.
static std::string ActionToString(Action action);
// Get the number of parameters needed for a action.
static int NumParams(action_t action);
// Parse a Trainer message to populate config. Returns a bool
// indicating if the struct was correctly parsed.
static bool ParseConfig(const std::string& message, Config& config);
// Connect to the server that controls the agent on the specified port.
void connectToAgentServer(int server_port=6000,
feature_set_t feature_set=HIGH_LEVEL_FEATURE_SET);
HFOEnvironment() {};
virtual ~HFOEnvironment() {};
/**
* Connect to the server on the specified port. The
* following information is provided by the ./bin/HFO
*
* feature_set: High or low level state features
* config_dir: Config directory. Typically HFO/bin/teams/base/config/
* uniform_number: player's uniform number.
* server_port: port to connect to server on
* server_addr: address of server
* team_name: Name of team to join.
* play_goalie: is this player the goalie
*/
void connectToServer(feature_set_t feature_set=HIGH_LEVEL_FEATURE_SET,
std::string config_dir="bin/teams/base/config/formations-dt",
int uniform_number=11,
int server_port=6000,
std::string server_addr="localhost",
std::string team_name="base_left",
bool play_goalie=false);
// Get the current state of the domain. Returns a reference to feature_vec.
const std::vector<float>& getState();
// Specify action type to take followed by parameters for that action
virtual void act(action_t action, ...);
virtual void act(action_t action, const std::vector<float>& params);
// Send/receive communication from other agents
virtual void say(const std::string& message);
......@@ -111,17 +55,8 @@ class HFOEnvironment {
virtual status_t step();
protected:
int numFeatures; // The number of features in this domain
int sockfd; // Socket file desriptor for connection to agent server
std::vector<float> feature_vec; // Holds the features
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.
virtual void handshakeAgentServer(feature_set_t feature_set);
rcsc::BasicClient client;
Agent agent;
};
} // namespace hfo
......
This diff is collapsed.
// -*-c++-*-
/*
*Copyright:
Copyright (C) Hidehisa AKIYAMA
This code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this code; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*EndCopyright:
*/
/////////////////////////////////////////////////////////////////////
#ifndef AGENT_H
#define AGENT_H
#include "action_generator.h"
#include "field_evaluator.h"
#include "communication.h"
#include "HFO.hpp"
#include "feature_extractor.h"
#include "common.hpp"
#include <rcsc/player/player_agent.h>
#include <vector>
......@@ -42,10 +16,6 @@ public:
virtual ~Agent();
virtual FieldEvaluator::ConstPtr getFieldEvaluator() const;
// 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
static FeatureExtractor* getFeatureExtractor(hfo::feature_set_t feature_set,
int num_teammates,
......@@ -70,26 +40,38 @@ protected:
virtual FieldEvaluator::ConstPtr createFieldEvaluator() const;
virtual ActionGenerator::ConstPtr createActionGenerator() const;
// Start the server and listen for a connection.
void startServer(int server_port=6008);
void listenForConnection();
// Transmit information to the client and ensure it can recieve.
void clientHandshake();
protected:
FeatureExtractor* feature_extractor;
hfo::feature_set_t feature_set; // Requested feature set
FeatureExtractor* feature_extractor; // Extracts the features
long lastTrainerMessageTime; // Last time the trainer sent a message
long lastTeammateMessageTime; // Last time a teammate sent a message
int server_port; // Port to start the server on
bool client_connected; // Has the client connected and handshake?
int sockfd, newsockfd; // Server sockets
int num_teammates, num_opponents;
bool playing_offense;
long lastDecisionTime; // Last time we made a decision
hfo::status_t game_status; // Current status of the game
hfo::Player player_on_ball; // Player in posession of the ball
std::vector<float> state; // Vector of current state features
std::string say_msg, hear_msg; // Messages to/from teammates
hfo::action_t action; // Currently requested action
std::vector<float> params; // Parameters of current action
public:
inline const std::vector<float>& getState() { return state; }
inline hfo::status_t getGameStatus() { return game_status; }
inline const hfo::Player& getPlayerOnBall() { return player_on_ball; }
inline const std::string& getHearMsg() { return hear_msg; }
inline long cycle() { return world().time().cycle(); }
inline long getLastDecisionTime() { return lastDecisionTime; }
inline void setFeatureSet(hfo::feature_set_t fset) { feature_set = fset; }
inline std::vector<float>* mutable_params() { return &params; }
inline void setAction(hfo::action_t a) { action = a; }
inline void setSayMsg(const std::string& message) { say_msg = message; }
private:
bool doPreprocess();
bool doSmartKick();
bool doShoot();
bool doPass();
bool doPassTo(int receiver);
bool doDribble();
bool doMove();
bool doForceKick();
......
#ifndef __COMMON_HPP__
#define __COMMON_HPP__
#include <sstream>
namespace hfo {
// For descriptions of the different feature sets see
// https://github.com/mhauskn/HFO/blob/master/doc/manual.pdf
enum feature_set_t
{
LOW_LEVEL_FEATURE_SET,
HIGH_LEVEL_FEATURE_SET
};
// The actions available to the agent
enum action_t
{
DASH, // [Low-Level] Dash(power [0,100], direction [-180,180])
TURN, // [Low-Level] Turn(direction [-180,180])
TACKLE, // [Low-Level] Tackle(direction [-180,180])
KICK, // [Low-Level] Kick(power [0,100], direction [-180,180])
KICK_TO, // [Mid-Level] Kick_To(target_x [-1,1], target_y [-1,1], speed [0,3])
MOVE_TO, // [Mid-Level] Move(target_x [-1,1], target_y [-1,1])
DRIBBLE_TO, // [Mid-Level] Dribble(target_x [-1,1], target_y [-1,1])
INTERCEPT, // [Mid-Level] Intercept(): Intercept the ball
MOVE, // [High-Level] Move(): Reposition player according to strategy
SHOOT, // [High-Level] Shoot(): Shoot the ball
PASS, // [High-Level] Pass(teammate_unum [0,11]): Pass to the most open teammate
DRIBBLE, // [High-Level] Dribble(): Offensive dribble
CATCH, // [High-Level] Catch(): Catch the ball (Goalie only!)
NOOP, // Do nothing
QUIT // Special action to quit the game
};
// Status of a HFO game
enum status_t
{
IN_GAME, // Game is currently active
GOAL, // A goal has been scored by the offense
CAPTURED_BY_DEFENSE, // The defense has captured the ball
OUT_OF_BOUNDS, // Ball has gone out of bounds
OUT_OF_TIME, // Trial has ended due to time limit
SERVER_DOWN // Server is not alive
};
// Configuration of the HFO domain including the team names and player
// numbers for each team. This struct is populated by ParseConfig().
struct Config {
std::string offense_team_name;
std::string defense_team_name;
int num_offense; // Number of offensive players
int num_defense; // Number of defensive players
std::vector<int> offense_nums; // Offensive player numbers
std::vector<int> defense_nums; // Defensive player numbers
};
enum SideID {
RIGHT = -1,
NEUTRAL = 0,
LEFT = 1
};
// A Player is described by its uniform number and side
struct Player {
SideID side;
int unum;
};
/**
* Returns the number of parameters required for each action.
*/
inline int NumParams(const action_t action) {
switch (action) {
case DASH:
return 2;
case TURN:
return 1;
case TACKLE:
return 1;
case KICK:
return 2;
case KICK_TO:
return 3;
case MOVE_TO:
return 2;
case DRIBBLE_TO:
return 2;
case INTERCEPT:
return 0;
case MOVE:
return 0;
case SHOOT:
return 0;
case PASS:
return 1;
case DRIBBLE:
return 0;
case CATCH:
return 0;
case NOOP:
return 0;
case QUIT:
return 0;
}
std::cerr << "Unrecognized Action: " << action << std::endl;
return -1;
};
/**
* Returns a string representation of an action.
*/
inline std::string ActionToString(action_t action) {
switch (action) {
case DASH:
return "Dash";
case TURN:
return "Turn";
case TACKLE:
return "Tackle";
case KICK:
return "Kick";
case KICK_TO:
return "KickTo";
case MOVE_TO:
return "MoveTo";
case DRIBBLE_TO:
return "DribbleTo";
case INTERCEPT:
return "Intercept";
case MOVE:
return "Move";
case SHOOT:
return "Shoot";
case PASS:
return "Pass";
case DRIBBLE:
return "Dribble";
case CATCH:
return "Catch";
case NOOP:
return "No-op";
case QUIT:
return "Quit";
default:
return "Unknown";
}
};
/**
* Returns a string representation of a game_status.
*/
inline std::string StatusToString(status_t status) {
switch (status) {
case IN_GAME:
return "InGame";
case GOAL:
return "Goal";
case CAPTURED_BY_DEFENSE:
return "CapturedByDefense";
case OUT_OF_BOUNDS:
return "OutOfBounds";
case OUT_OF_TIME:
return "OutOfTime";
case SERVER_DOWN:
return "ServerDown";
default:
return "Unknown";
}
};
/**
* Parse a Trainer message to populate config. Returns a bool
* indicating if the struct was correctly parsed.
*/
inline bool ParseConfig(const std::string& message, Config& config) {
config.num_offense = -1;
config.num_defense = -1;
std::istringstream iss(message);
std::string header = "HFO_SETUP";
std::string key, val;
iss >> key;
if (header.compare(key) != 0) {
std::cerr << "Got unexpected message header: " << header;
return false;
}
while (iss >> key) {
if (key.compare("offense_name") == 0) {
iss >> config.offense_team_name;
} else if (key.compare("defense_name") == 0) {
iss >> config.defense_team_name;
} else if (key.compare("num_offense") == 0) {
iss >> val;
config.num_offense = strtol(val.c_str(), NULL, 0);
} else if (key.compare("num_defense") == 0) {
iss >> val;
config.num_defense = strtol(val.c_str(), NULL, 0);
} else if (key.compare("offense_nums") == 0) {
assert(config.num_offense >= 0);
for (int i=0; i<config.num_offense; ++i) {
iss >> val;
config.offense_nums.push_back(strtol(val.c_str(), NULL, 0));
}
} else if (key.compare("defense_nums") == 0) {
assert(config.num_defense >= 0);
for (int i=0; i<config.num_defense; ++i) {
iss >> val;
config.defense_nums.push_back(strtol(val.c_str(), NULL, 0));
}
} else {
std::cerr << "Unrecognized key: " << key << std::endl;
return false;
}
}
assert(config.offense_nums.size() == config.num_offense);
assert(config.defense_nums.size() == config.num_defense);
return true;
};
/**
* Parse a trainer message to extract the player on the ball
*/
inline bool ParsePlayerOnBall(const std::string& message, Player& player) {
if (message.find("GOAL") != std::string::npos){
player.unum = atoi((message.substr(message.find("-")+1)).c_str());
player.side = LEFT;
} else if (message.find("CAPTURED_BY_DEFENSE") != std::string::npos) {
player.unum = atoi((message.substr(message.find("-")+1)).c_str());
player.side = RIGHT;
} else if (message.find("IN_GAME") != std::string::npos){
switch (message.at(message.find("-")+1)){
case 'L':
player.side = LEFT;
break;
case 'R':
player.side = RIGHT;
break;
case 'U':
player.side = NEUTRAL;
break;
}
player.unum = atoi((message.substr(message.find("-")+2)).c_str());
} else {
return false;
}
return true;
};
/**
* Parse a trainer message to extract the game status
*/
inline bool ParseGameStatus(const std::string& message, status_t& status) {
status = IN_GAME;
if (message.find("GOAL") != std::string::npos){
status = GOAL;
} else if (message.find("CAPTURED_BY_DEFENSE") != std::string::npos) {
status = CAPTURED_BY_DEFENSE;
} else if (message.compare("OUT_OF_BOUNDS") == 0) {
status = OUT_OF_BOUNDS;
} else if (message.compare("OUT_OF_TIME") == 0) {
status = OUT_OF_TIME;
} else if (message.find("IN_GAME") != std::string::npos){
status = IN_GAME;
} else {
return false;
}
return true;
};
}
#endif
......@@ -233,7 +233,7 @@ bool SamplePlayer::getHFOConfig() {
const AudioSensor& audio_sensor = audioSensor();
if (audio_sensor.trainerMessageTime().cycle() > lastTrainerMessageTime) {
const std::string& message = audio_sensor.trainerMessage();
if (hfo::HFOEnvironment::ParseConfig(message, hfo_config)) {
if (hfo::ParseConfig(message, hfo_config)) {
lastTrainerMessageTime = audio_sensor.trainerMessageTime().cycle();
if (config().teamName().compare(hfo_config.offense_team_name) == 0) {
playing_offense = true;
......@@ -269,10 +269,15 @@ SamplePlayer::actionImpl()
hfo::LOW_LEVEL_FEATURE_SET, num_teammates, num_opponents, playing_offense);
}
} else {
std::vector<int> game_status = Agent::getGameStatus(
audioSensor(), lastTrainerMessageTime);
elog.addText(Logger::WORLD, "GameStatus %d", game_status[0]);
if (audioSensor().trainerMessageTime().cycle() > lastTrainerMessageTime) {
const std::string& message = audioSensor().trainerMessage();
hfo::status_t game_status;
if (hfo::ParseGameStatus(message, game_status)) {
elog.addText(Logger::WORLD, "GameStatus %d", game_status);
elog.flush();
}
lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle();
}
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