Commit 2af17db4 authored by sanmit's avatar sanmit

Added support for 3rd party binaries to be used as NPCs

parent 0104ff75
...@@ -28,12 +28,14 @@ def launch(cmd, name = 'Unknown', necessary = True, supressOutput = True): ...@@ -28,12 +28,14 @@ def launch(cmd, name = 'Unknown', necessary = True, supressOutput = True):
necProcesses.append([p,name]) necProcesses.append([p,name])
return p return p
def main(args, team1='left', team2='right'): def main(args):
"""Sets up the teams, launches the server and monitor, starts the trainer. """Sets up the teams, launches the server and monitor, starts the trainer.
""" """
if args.logging and not os.path.exists(args.logDir): if args.logging and not os.path.exists(args.logDir):
os.makedirs(args.logDir) os.makedirs(args.logDir)
num_agents = args.offenseAgents + args.defenseAgents num_agents = args.offenseAgents + args.defenseAgents
team1 = args.offenseTeam
team2 = args.defenseTeam
binary_dir = os.path.dirname(os.path.realpath(__file__)) binary_dir = os.path.dirname(os.path.realpath(__file__))
server_port = args.port + num_agents server_port = args.port + num_agents
coach_port = args.port + num_agents + 1 coach_port = args.port + num_agents + 1
...@@ -118,6 +120,10 @@ def parseArgs(): ...@@ -118,6 +120,10 @@ def parseArgs():
help='Number of offensive uncontrolled players. Default: 0.') help='Number of offensive uncontrolled players. Default: 0.')
p.add_argument('--defense-npcs', dest='defenseNPCs', type=int, default=0, p.add_argument('--defense-npcs', dest='defenseNPCs', type=int, default=0,
help='Number of defensive uncontrolled players. Default: 0.') help='Number of defensive uncontrolled players. Default: 0.')
p.add_argument('--offense-team', dest='offenseTeam', type=str, default='left',
help='Team name to pull offensive NPCs from. Default: left.')
p.add_argument('--defense-team', dest='defenseTeam', type=str, default='right',
help='Team name to pull defensive NPCs from. Default: right')
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('--port', dest='port', type=int, default=6000, p.add_argument('--port', dest='port', type=int, default=6000,
......
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
import sys, numpy, time, os, subprocess import sys, numpy, time, os, subprocess, teams
from Communicator import ClientCommunicator, TimeoutError from Communicator import ClientCommunicator, TimeoutError
class DoneError(Exception): class DoneError(Exception):
...@@ -157,15 +157,30 @@ class Trainer(object): ...@@ -157,15 +157,30 @@ class Trainer(object):
""" Adds a team to the team list""" """ Adds a team to the team list"""
self._teams.append(team_name) self._teams.append(team_name)
def setTeams(self): def createTeam(self, name):
teamDir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'teams')
if 'HELIOS' in name:
print 'Creating team HELIOS'
return teams.Helios(name, os.path.join(teamDir, 'helios', 'helios-13Eindhoven'), os.path.join(teamDir, 'helios', 'local', 'lib'), 'helios_player', host='localhost', port=self._serverPort)
# Agent2d (base) is the default
else:
print 'Creating team Agent2d (base)'
return teams.Agent2d(name, os.path.join(teamDir, 'base'), None, 'sample_player', self._logDir, self._record, host='localhost', port=self._serverPort)
def getTeams(self):
""" Sets the offensive and defensive teams and player rosters. """ """ Sets the offensive and defensive teams and player rosters. """
self._offenseTeamInd = 0 self._offenseTeamInd = 0
self._offenseTeamName = self._teams[self._offenseTeamInd] self._offenseTeamName = self._teams[self._offenseTeamInd]
self._defenseTeamName = self._teams[1-self._offenseTeamInd] self._defenseTeamName = self._teams[1-self._offenseTeamInd]
offensive_roster = self.getOffensiveRoster(self._offenseTeamName) # set up offense
defensive_roster = self.getDefensiveRoster(self._defenseTeamName) offenseTeam = self.createTeam(self._offenseTeamName)
self._offenseOrder = [1] + offensive_roster # 1 for goalie # set up defense
self._defenseOrder = [1] + defensive_roster # 1 for goalie defenseTeam = self.createTeam(self._defenseTeamName)
# offensive_roster = self.getOffensiveRoster(self._offenseTeamName)
# defensive_roster = self.getDefensiveRoster(self._defenseTeamName)
self._offenseOrder = [1] + offenseTeam._offense_order # 1 for goalie
self._defenseOrder = [1] + defenseTeam._defense_order # 1 for goalie
return (offenseTeam, defenseTeam)
def teamToInd(self, team_name): def teamToInd(self, team_name):
""" Returns the index of a given team. """ """ Returns the index of a given team. """
...@@ -429,7 +444,7 @@ class Trainer(object): ...@@ -429,7 +444,7 @@ class Trainer(object):
def run(self, necProcesses): def run(self, necProcesses):
""" Run the trainer """ """ Run the trainer """
try: try:
self.setTeams() (offenseTeam, defenseTeam) = self.getTeams()
offense_unums = self._offenseOrder[1: self._numOffense + 1] offense_unums = self._offenseOrder[1: self._numOffense + 1]
sorted_offense_agent_unums = sorted(self._offenseOrder[1:self._offenseAgents+1]) sorted_offense_agent_unums = sorted(self._offenseOrder[1:self._offenseAgents+1])
defense_unums = self._defenseOrder[: self._numDefense] defense_unums = self._defenseOrder[: self._numDefense]
...@@ -446,7 +461,8 @@ class Trainer(object): ...@@ -446,7 +461,8 @@ class Trainer(object):
necProcesses.append([agent, 'offense_agent_' + str(agent_num)]) necProcesses.append([agent, 'offense_agent_' + str(agent_num)])
agent_num += 1 agent_num += 1
else: else:
player = self.launch_npc(player_num, play_offense=True) player = offenseTeam.launch_npc(player_num)
self.waitOnPlayer(player_num, True)
if player_num in offense_unums: if player_num in offense_unums:
self._npcPopen.append(player) self._npcPopen.append(player)
necProcesses.append([player, 'offense_npc_' + str(player_num)]) necProcesses.append([player, 'offense_npc_' + str(player_num)])
...@@ -464,7 +480,8 @@ class Trainer(object): ...@@ -464,7 +480,8 @@ class Trainer(object):
necProcesses.append([agent, 'defense_agent_' + str(agent_num)]) necProcesses.append([agent, 'defense_agent_' + str(agent_num)])
agent_num += 1 agent_num += 1
else: else:
player = self.launch_npc(player_num, play_offense=False) player = defenseTeam.launch_npc(player_num)
self.waitOnPlayer(player_num, False)
if player_num in defense_unums: if player_num in defense_unums:
self._npcPopen.append(player) self._npcPopen.append(player)
necProcesses.append([player, 'defense_npc_' + str(player_num)]) necProcesses.append([player, 'defense_npc_' + str(player_num)])
......
#!/usr/bin/env python
# encoding: utf-8
import os, subprocess
class Team(object):
""" Abstract class. Handles launching players from 3rd party binaries.
"""
def __init__(self, name, binaryPath, libDir, options, offenseOrder, defenseOrder):
"""
Creates a team
name: name of the team
binaryPath: absolute path of the executable
libDir: library dependencies directory
options: team-specific parameters for executable in string format
offenseOrder: order to prioritize offensive unums (do not include 0)
defenseOrder: order to prioritize defensive unums (do not include 0)
"""
self._name = name
self._binary_path = binaryPath
self._lib_dir = libDir
self._options = options
self._offense_order = offenseOrder
self._defense_order = defenseOrder
def launch_npc(self, launchOpts=None):
"""Launches a player using the team-specific binary
launchOpts should be used to append player specific options
(e.g., helios uses '-g' to signify launching a goalie )
Returns a Popen process object
"""
print 'Launch npc %s' % (self._name)
player_cmd = self._binary_path
player_cmd += ' %s' % (self._options)
if launchOpts != None:
player_cmd += ' %s' % (launchOpts)
kwargs = {'stdout':open('/dev/null', 'w'),
'stderr':open('/dev/null', 'w')}
env = dict(os.environ)
if self._lib_dir != None:
env['LD_LIBRARY_PATH'] = self._lib_dir
p = subprocess.Popen(player_cmd.split(' '), env=env, shell = False, **kwargs)
return p
class Agent2d(Team):
def __init__(self, name, baseDir, libDir, binaryName, logDir, record, host='localhost', port=6000):
binaryPath = os.path.join(baseDir, binaryName)
options = '-t %s -p %i --config_dir %s/config/formations-dt --log_dir %s --player-config %s/config/player.conf' % (name, port, baseDir, logDir, baseDir)
if record:
options += ' --record'
offenseOrder = [11,7,8,9,10,6,3,2,4,5]
defenseOrder = [2,3,4,5,6,7,8,11,9,10]
super(Agent2d, self).__init__(name, binaryPath, libDir, options, offenseOrder, defenseOrder)
def launch_npc(self, player_num):
launchOpts = None
if player_num == 1:
launchOpts = '-g'
return super(Agent2d, self).launch_npc(launchOpts)
class Helios(Team):
def __init__(self, name, baseDir, libDir, binaryName, host='localhost', port=6000):
binaryPath = os.path.join(baseDir, binaryName)
options = '--player-config %s/player.conf -h %s -t %s --formation-conf-dir %s/data/formations --role-conf %s/data/role.conf --ball-table %s/data/ball_table.dat --chain-search-method BestFirstSearch --evaluator-name Default --max-chain-length 4 --max-evaluate-size 1000 --sirm-evaluator-param-dir %s/data/sirm_evaluator/ --goalie-position-dir %s/data/goalie_position/ --intercept-conf-dir %s/data/intercept_probability/ --opponent-data-dir %s/data/opponent_data/ -p %d' % (baseDir, host, name, baseDir, baseDir, baseDir, baseDir, baseDir, baseDir, baseDir, port)
offenseOrder = [11,7,8,9,10,6,3,2,4,5]
defenseOrder = [2,3,4,5,6,7,8,11,9,10]
super(Helios, self).__init__(name, binaryPath, libDir, options, offenseOrder, defenseOrder)
def launch_npc(self, player_num):
launchOpts = None
if player_num == 1:
launchOpts = '-g'
return super(Helios, self).launch_npc(launchOpts)
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