start.py 5.02 KB
Newer Older
Matthew Hausknecht's avatar
Matthew Hausknecht committed
1 2 3
#!/usr/bin/env python
# encoding: utf-8

4
import subprocess, os, time, numpy, sys
5
from signal import SIGKILL
Matthew Hausknecht's avatar
Matthew Hausknecht committed
6

7 8 9
# Global list of all/essential running processes
processes, necProcesses = [], []
# Command to run the rcssserver. Edit as needed.
10
SERVER_CMD = 'rcssserver'
11
# Command to run the monitor. Edit as needed.
Matthew Hausknecht's avatar
Matthew Hausknecht committed
12 13
MONITOR_CMD = 'rcssmonitor'

14 15
def getAgentDirCmd(binary_dir, teamname, server_port=6000, coach_port=6002,
                   logDir='log', record=False):
16
  """ Returns the team name, command, and directory to run a team. """
17 18
  cmd = 'start.sh -t %s -p %i -P %i --log-dir %s'%(teamname, server_port,
                                                   coach_port, logDir)
19 20
  if record:
    cmd += ' --record'
21 22
  cmd = os.path.join(binary_dir, cmd)
  return teamname, cmd
Matthew Hausknecht's avatar
Matthew Hausknecht committed
23

24 25
def launch(cmd, necessary=True, supressOutput=True, name='Unknown'):
  """Launch a process.
Matthew Hausknecht's avatar
Matthew Hausknecht committed
26

27 28
  Appends to list of processes and (optionally) necProcesses if
  necessary flag is True.
Matthew Hausknecht's avatar
Matthew Hausknecht committed
29

30
  Returns: The launched process.
Matthew Hausknecht's avatar
Matthew Hausknecht committed
31

32
  """
Matthew Hausknecht's avatar
Matthew Hausknecht committed
33 34 35 36 37 38 39 40 41
  kwargs = {}
  if supressOutput:
    kwargs = {'stdout':open('/dev/null','w'),'stderr':open('/dev/null','w')}
  p = subprocess.Popen(cmd.split(' '),shell=False,**kwargs)
  processes.append(p)
  if necessary:
    necProcesses.append([p,name])
  return p

42
def main(args, team1='left', team2='right', rng=numpy.random.RandomState()):
43 44 45
  """Sets up the teams, launches the server and monitor, starts the
  trainer.
  """
46 47 48
  if not os.path.exists(args.logDir):
    os.makedirs(args.logDir)
  binary_dir   = os.path.dirname(os.path.realpath(__file__))
49 50 51
  server_port  = args.port + 1
  coach_port   = args.port + 2
  olcoach_port = args.port + 3
52 53 54 55 56
  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)
57
  if args.sync:
Matthew Hausknecht's avatar
Matthew Hausknecht committed
58
    serverOptions += ' server::synch_mode=on'
59 60 61 62
  team1, team1Cmd = getAgentDirCmd(binary_dir, team1, server_port, coach_port,
                                   args.logDir, args.record)
  team2, team2Cmd = getAgentDirCmd(binary_dir, team2, server_port, coach_port,
                                   args.logDir, args.record)
Matthew Hausknecht's avatar
Matthew Hausknecht committed
63
  try:
64
    # Launch the Server
65
    server = launch(SERVER_CMD + serverOptions, name='server')
Matthew Hausknecht's avatar
Matthew Hausknecht committed
66
    time.sleep(0.2)
67 68
    assert server.poll() is None,\
      'Failed to launch Server with command: \"%s\"'%(SERVER_CMD)
69
    if not args.headless:
70 71
      monitorOptions = ' --port=%i'%(server_port)
      launch(MONITOR_CMD + monitorOptions, name='monitor')
72
    # Launch the Trainer
Matthew Hausknecht's avatar
Matthew Hausknecht committed
73
    from Trainer import Trainer
74
    trainer = Trainer(args=args, rng=rng)
Matthew Hausknecht's avatar
Matthew Hausknecht committed
75
    trainer.initComm()
76
    # Start Team1
Matthew Hausknecht's avatar
Matthew Hausknecht committed
77 78
    launch(team1Cmd,False)
    trainer.waitOnTeam(True) # wait to make sure of team order
79
    # Start Team2
Matthew Hausknecht's avatar
Matthew Hausknecht committed
80 81
    launch(team2Cmd,False)
    trainer.waitOnTeam(False)
82
    # Make sure all players are connected
Matthew Hausknecht's avatar
Matthew Hausknecht committed
83 84
    trainer.checkIfAllPlayersConnected()
    trainer.setTeams()
85
    # Run HFO
Matthew Hausknecht's avatar
Matthew Hausknecht committed
86 87
    trainer.run(necProcesses)
  except KeyboardInterrupt:
88
    print '[start.py] Exiting for CTRL-C'
Matthew Hausknecht's avatar
Matthew Hausknecht committed
89 90 91
  finally:
    for p in processes:
      try:
92
        p.send_signal(SIGKILL)
Matthew Hausknecht's avatar
Matthew Hausknecht committed
93 94
      except:
        pass
95
      time.sleep(0.1)
Matthew Hausknecht's avatar
Matthew Hausknecht committed
96

97
def parseArgs(args=None):
98 99 100 101 102 103 104 105 106
  import argparse
  p = argparse.ArgumentParser(description='Start Half Field Offense.')
  p.add_argument('--headless', dest='headless', action='store_true',
                 help='Run without a monitor')
  p.add_argument('--trials', dest='numTrials', type=int, default=-1,
                 help='Number of trials to run')
  p.add_argument('--frames', dest='numFrames', type=int, default=-1,
                 help='Number of frames to run for')
  p.add_argument('--offense', dest='numOffense', type=int, default=4,
107
                 choices=xrange(1,11), help='Number of offensive players')
108
  p.add_argument('--defense', dest='numDefense', type=int, default=4,
109
                 choices=xrange(0,12), help='Number of defensive players')
110 111 112 113 114 115 116
  p.add_argument('--play-defense', dest='play_offense',
                 action='store_false', default=True,
                 help='Put the learning agent on defensive team')
  p.add_argument('--no-agent', dest='no_agent', action='store_true',
                 help='Don\'t use a learning agent.')
  p.add_argument('--no-sync', dest='sync', action='store_false', default=True,
                 help='Run server in non-sync mode')
117 118 119
  p.add_argument('--port', dest='port', type=int, default=6000,
                 help='Agent server\'s port. rcssserver, coach, and ol_coach'\
                 ' will be incrementally allocated the following ports.')
120 121
  p.add_argument('--log-dir', dest='logDir', default='log/',
                 help='Directory to store logs.')
122 123 124 125
  p.add_argument('--record', dest='record', action='store_true',
                 help='Record logs of states and actions.')
  p.add_argument('--agent-on-ball', dest='agent_on_ball', action='store_true',
                 help='Agent starts with the ball.')
126 127 128 129
  return p.parse_args(args=args)

if __name__ == '__main__':
  main(parseArgs())