Commit 3bc47bf6 authored by Matthew Hausknecht's avatar Matthew Hausknecht

Refactor hard paths in startup scripts. Added setup.py to make hfo into an...

Refactor hard paths in startup scripts. Added setup.py to make hfo into an installable python library.
parent 41b461a0
...@@ -33,6 +33,9 @@ class Trainer(object): ...@@ -33,6 +33,9 @@ class Trainer(object):
""" """
def __init__(self, args, rng=numpy.random.RandomState()): def __init__(self, args, rng=numpy.random.RandomState()):
self._rng = rng # The Random Number Generator self._rng = rng # The Random Number Generator
self._serverPort = args.basePort # The port the server is listening on
self._coachPort = args.basePort + 1 # The coach port to talk with the server
self._logDir = args.logDir # Directory to store logs
self._numOffense = args.numOffense # Number offensive players self._numOffense = args.numOffense # Number offensive players
self._numDefense = args.numDefense # Number defensive players self._numDefense = args.numDefense # Number defensive players
self._maxTrials = args.numTrials # Maximum number of trials to play self._maxTrials = args.numTrials # Maximum number of trials to play
...@@ -63,7 +66,7 @@ class Trainer(object): ...@@ -63,7 +66,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 self._agentServerPort = args.basePort + 8 # 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,16 +100,23 @@ class Trainer(object): ...@@ -97,16 +100,23 @@ class Trainer(object):
numOpponents = self._numDefense - 1 numOpponents = self._numDefense - 1
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'\ binary_dir = os.path.dirname(os.path.realpath(__file__))
agentCmd = 'start_agent.sh -t %s -u %i -p %i -P %i --log-dir %s'\
' --numTeammates %i --numOpponents %i'\
' --playingOffense %i --serverPort %i'\ ' --playingOffense %i --serverPort %i'\
%(self._agentTeam, self._agentNumExt, numTeammates, numOpponents, %(self._agentTeam, self._agentNumExt, self._serverPort,
self._coachPort, self._logDir, numTeammates, numOpponents,
self._agent_play_offense, self._agentServerPort) self._agent_play_offense, self._agentServerPort)
agentCmd = os.path.join(binary_dir, agentCmd)
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: pid_file = os.path.join(self._logDir, 'start%i'%p.pid)
print '[Trainer] Parsing agent\'s pid from file:', pid_file
assert os.path.isfile(pid_file)
with open(pid_file,'r') as f:
output = f.read() output = f.read()
pid = int(re.findall('PID: (\d+)',output)[0]) pid = int(re.findall('PID: (\d+)',output)[0])
return DummyPopen(pid) return DummyPopen(pid)
...@@ -184,9 +194,9 @@ class Trainer(object): ...@@ -184,9 +194,9 @@ class Trainer(object):
def initComm(self): def initComm(self):
""" Initialize communication to server. """ """ Initialize communication to server. """
self._comm = ClientCommunicator(port=6001) self._comm = ClientCommunicator(port=self._coachPort)
self.send('(init (version 8.0))') self.send('(init (version 8.0))')
self.checkMsg('(init ok)',retryCount=5) self.checkMsg('(init ok)', retryCount=5)
# self.send('(eye on)') # self.send('(eye on)')
self.send('(ear on)') self.send('(ear on)')
...@@ -243,7 +253,7 @@ class Trainer(object): ...@@ -243,7 +253,7 @@ class Trainer(object):
print >>sys.stderr,'[Trainer] Error with message' print >>sys.stderr,'[Trainer] Error with message'
print >>sys.stderr,' expected: %s' % expectedMsg print >>sys.stderr,' expected: %s' % expectedMsg
print >>sys.stderr,' received: %s' % msg print >>sys.stderr,' received: %s' % msg
print >>sys.stderr,len(expectedMsg),len(msg) # print >>sys.stderr,len(expectedMsg),len(msg)
raise ValueError raise ValueError
def extractPoint(self, msg): def extractPoint(self, msg):
......
...@@ -7,17 +7,16 @@ from signal import SIGKILL ...@@ -7,17 +7,16 @@ from signal import SIGKILL
# Global list of all/essential running processes # Global list of all/essential running processes
processes, necProcesses = [], [] processes, necProcesses = [], []
# Command to run the rcssserver. Edit as needed. # Command to run the rcssserver. Edit as needed.
SERVER_CMD = 'rcssserver server::port=6000 server::coach_port=6001 \ SERVER_CMD = 'rcssserver'
server::olcoach_port=6002 server::coach=1 server::game_log_dir=log \
server::text_log_dir=log'
# Command to run the monitor. Edit as needed. # Command to run the monitor. Edit as needed.
MONITOR_CMD = 'rcssmonitor' MONITOR_CMD = 'rcssmonitor'
def getAgentDirCmd(name, first): def getAgentDirCmd(binary_dir, teamname, server_port=6000, coach_port=6002, logDir='/tmp'):
""" Returns the team name, command, and directory to run a team. """ """ Returns the team name, command, and directory to run a team. """
cmd = './start.sh -t %s' % name cmd = 'start.sh -t %s -p %i -P %i --log-dir %s'%(teamname, server_port,
dir = os.path.dirname(os.path.realpath(__file__)) coach_port, logDir)
return name, cmd, dir cmd = os.path.join(binary_dir, cmd)
return teamname, cmd
def launch(cmd, necessary=True, supressOutput=True, name='Unknown'): def launch(cmd, necessary=True, supressOutput=True, name='Unknown'):
"""Launch a process. """Launch a process.
...@@ -41,13 +40,21 @@ def main(args, team1='left', team2='right', rng=numpy.random.RandomState()): ...@@ -41,13 +40,21 @@ def main(args, team1='left', team2='right', rng=numpy.random.RandomState()):
"""Sets up the teams, launches the server and monitor, starts the """Sets up the teams, launches the server and monitor, starts the
trainer. trainer.
""" """
serverOptions = '' if not os.path.exists(args.logDir):
os.makedirs(args.logDir)
binary_dir = os.path.dirname(os.path.realpath(__file__))
server_port = args.basePort
coach_port = args.basePort + 1
olcoach_port = args.basePort + 2
serverOptions = ' server::port=%i server::coach_port=%i ' \
'server::olcoach_port=%i server::coach=1 ' \
'server::game_log_dir=%s server::text_log_dir=%s' \
%(server_port, coach_port, olcoach_port,
args.logDir, args.logDir)
if args.sync: if args.sync:
serverOptions += ' server::synch_mode=on' serverOptions += ' server::synch_mode=on'
team1, team1Cmd, team1Dir = getAgentDirCmd(team1, True) team1, team1Cmd = getAgentDirCmd(binary_dir, team1, server_port, coach_port, args.logDir)
team2, team2Cmd, team2Dir = getAgentDirCmd(team2, False) team2, team2Cmd = getAgentDirCmd(binary_dir, team2, server_port, coach_port, args.logDir)
assert os.path.isdir(team1Dir)
assert os.path.isdir(team2Dir)
try: try:
# Launch the Server # Launch the Server
server = launch(SERVER_CMD + serverOptions, name='server') server = launch(SERVER_CMD + serverOptions, name='server')
...@@ -55,17 +62,15 @@ def main(args, team1='left', team2='right', rng=numpy.random.RandomState()): ...@@ -55,17 +62,15 @@ def main(args, team1='left', team2='right', rng=numpy.random.RandomState()):
assert server.poll() is None,\ assert server.poll() is None,\
'Failed to launch Server with command: \"%s\"'%(SERVER_CMD) 'Failed to launch Server with command: \"%s\"'%(SERVER_CMD)
if not args.headless: if not args.headless:
launch(MONITOR_CMD,name='monitor') launch(MONITOR_CMD, name='monitor')
# Launch the Trainer # Launch the Trainer
from Trainer import Trainer from Trainer import Trainer
trainer = Trainer(args=args, rng=rng) trainer = Trainer(args=args, rng=rng)
trainer.initComm() trainer.initComm()
# Start Team1 # Start Team1
os.chdir(team1Dir)
launch(team1Cmd,False) launch(team1Cmd,False)
trainer.waitOnTeam(True) # wait to make sure of team order trainer.waitOnTeam(True) # wait to make sure of team order
# Start Team2 # Start Team2
os.chdir(team2Dir)
launch(team2Cmd,False) launch(team2Cmd,False)
trainer.waitOnTeam(False) trainer.waitOnTeam(False)
# Make sure all players are connected # Make sure all players are connected
...@@ -103,8 +108,11 @@ def parseArgs(args=None): ...@@ -103,8 +108,11 @@ 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, p.add_argument('--base-port', dest='basePort', type=int, default=6000,
help='Port to run agent server on.') help='Base port for communications. rcssserver will use this \
port and all other ports will be allocated incrementally.')
p.add_argument('--log-dir', dest='logDir', default='log/',
help='Directory to store logs.')
return p.parse_args(args=args) return p.parse_args(args=args)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -347,6 +347,7 @@ do ...@@ -347,6 +347,7 @@ do
exit 1 exit 1
fi fi
debugopt="${debugopt} --log_dir ${2}" debugopt="${debugopt} --log_dir ${2}"
LOG_DIR=${2}
shift 1 shift 1
;; ;;
...@@ -445,7 +446,7 @@ while [ $i -le ${number} ] ; do ...@@ -445,7 +446,7 @@ while [ $i -le ${number} ] ; do
cmd="${player} ${opt} ${opts} ${offline_number} ${goalie} --reconnect $i" cmd="${player} ${opt} ${opts} ${offline_number} ${goalie} --reconnect $i"
if [ X"${use_gdb}" = X'' ]; then if [ X"${use_gdb}" = X'' ]; then
${cmd} & ${cmd} &
echo "PID: $!" > /tmp/start$BASHPID echo "PID: $!" > ${LOG_DIR}/start$BASHPID
else else
gdb -ex run --args ${cmd} gdb -ex run --args ${cmd}
fi fi
......
...@@ -10,7 +10,7 @@ int main() { ...@@ -10,7 +10,7 @@ int main() {
// Create the HFO environment // Create the HFO environment
HFOEnvironment hfo; HFOEnvironment hfo;
// Connect the agent's server // Connect the agent's server
hfo.connectToAgentServer(); hfo.connectToAgentServer(12008);
// Play 5 episodes // Play 5 episodes
for (int episode=0; episode<5; episode++) { for (int episode=0; episode<5; episode++) {
hfo_status_t status = IN_GAME; hfo_status_t status = IN_GAME;
......
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
import imp
# First Start the server: $> bin/start.py # First Start the server: $> bin/start.py
if __name__ == '__main__': if __name__ == '__main__':
# Load the HFO library
try: try:
hfo_module = imp.load_source('HFO', '../HFO.py') from hfo import *
except: except:
hfo_module = imp.load_source('HFO', 'HFO.py') print 'Failed to import hfo. To install hfo, in the HFO directory'\
# Get the possible actions ' run: \"pip install .\"'
HFO_Actions = hfo_module.HFO_Actions exit()
# Get the possible outcomes
HFO_Status = hfo_module.HFO_Status
# Create the HFO Environment # Create the HFO Environment
hfo = hfo_module.HFOEnvironment() hfo = hfo.HFOEnvironment()
# Connect to the agent server # Connect to the agent server
hfo.connectToAgentServer() hfo.connectToAgentServer()
# Play 5 episodes # Play 5 episodes
......
from hfo import *
import os
import setuptools
setuptools.setup(
name='hfo',
version='0.1.1',
packages=setuptools.find_packages(),
author='Matthew Hausknecht',
author_email='matthew.hausknecht@gmail.com',
description='Transparent cluster execution.',
license='MIT',
keywords=('Robocup '
'Half-field-offense '
),
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
)
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