Skip to content

Commit

Permalink
Project import generated by Copybara.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 261857820
  • Loading branch information
qstanczyk committed Aug 6, 2019
1 parent 5faba9c commit 325516e
Show file tree
Hide file tree
Showing 34 changed files with 314 additions and 351 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ Numbering scheme:
Each environment release number is of the form vX.Y. X is the major version
number, Y is the minor version number. Experiment results within the same X
should not change, as modifications made to the environment are either
new features or backward compatible bug fixes. We will maintain vX branches
pointing at the most recent vX.Y
new features or backward compatible bug fixes. We will maintain vX branches
pointing at the most recent vX.Y.

v1.2
- Reduction of memory usage by the environment (https://github.com/google-research/football/issues/47).
- Reduction of memory usage during compilation (https://github.com/google-research/football/issues/49).
- Elimination of --no-pie compilation flag (https://github.com/google-research/football/issues/53).
- Fix for broken wrappers.py (https://github.com/google-research/football/issues/54).

v1.1
- Add support for running multiple environment instances in a single process.
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ are controlled by the following set of flags:
If rendering is disabled (`render` config flag), the video contains a simple
episode animation.

There are following scripts provided to operate on trace dumps:

- `dump_to_txt.py` - converts trace dump to human-readable form.
- `dump_to_video.py` - converts trace dump to a 2D representation video.
- `replay.py` - replays a given trace dump using environment.

## Frequent Problems & Solutions

### Rendering not working / "OpenGL version not equal to or higher than 3.2"
Expand Down
2 changes: 1 addition & 1 deletion gfootball/build_game_engine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
set -e
# Delete pre-existing version of CMakeCache.txt to make 'pip3 install' work.
rm -f third_party/gfootball_engine/CMakeCache.txt
pushd third_party/gfootball_engine && cmake . && make -j && popd
pushd third_party/gfootball_engine && cmake . && make -j `nproc` && popd
pushd third_party/gfootball_engine && ln -sf libgame.so _gameplayfootball.so && popd
23 changes: 11 additions & 12 deletions gfootball/dump_to_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,36 @@
# See the License for the specific language governing permissions and
# limitations under the License.


"""Script converting dump file to human readable format.
Example usage:
python dump_to_txt.py --dump=/tmp/input.dump --output=/tmp/output.txt
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from gfootball.env import script_helpers

from absl import app
from absl import flags

import six.moves.cPickle

FLAGS = flags.FLAGS

flags.DEFINE_string('dump', '', 'Trace file to convert')
flags.DEFINE_string('output', '', 'Output txt file')
flags.DEFINE_string('trace_file', None, 'Trace file to convert')
flags.DEFINE_string('output', None, 'Output txt file')
flags.DEFINE_bool('include_debug', True,
'Include debug information for each step')
flags.mark_flag_as_required('trace_file')
flags.mark_flag_as_required('output')


def main(_):
with open(FLAGS.dump, 'rb') as f:
replay = six.moves.cPickle.load(f)
if not FLAGS.include_debug:
for s in replay:
if 'debug' in s:
del s['debug']
with open(FLAGS.output, 'w') as f:
f.write(str(replay))
script_helpers.ScriptHelpers().dump_to_txt(FLAGS.trace_file, FLAGS.output,
FLAGS.include_debug)


if __name__ == '__main__':
Expand Down
20 changes: 5 additions & 15 deletions gfootball/render_dump.py → gfootball/dump_to_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,16 @@

from absl import app
from absl import flags
from gfootball.env import config
from gfootball.env import observation_processor

import six.moves.cPickle
from gfootball.env import script_helpers

FLAGS = flags.FLAGS
flags.DEFINE_string('file', '', 'Dump file to render')
flags.DEFINE_string('trace_file', None, 'Trace file to render')
flags.mark_flag_as_required('trace_file')


def main(_):
cfg = config.Config()
cfg['dump_full_episodes'] = True
cfg['write_video'] = True
cfg['display_game_stats'] = True
with open(FLAGS.file, 'rb') as f:
dump = six.moves.cPickle.load(f)
processor = observation_processor.ObservationProcessor(cfg)
for frame in dump:
processor.update(frame)
processor.write_dump('episode_done')
script_helpers.ScriptHelpers().dump_to_video(FLAGS.trace_file)


if __name__ == '__main__':
app.run(main)
124 changes: 56 additions & 68 deletions gfootball/env/observation_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import six.moves.cPickle
import tensorflow as tf

REMOVED_FRAME = 'removed'

try:
import cv2
except ImportError:
Expand All @@ -48,13 +50,11 @@ class DumpConfig(object):
def __init__(self,
max_length=200,
max_count=1,
skip_visuals=False,
snapshot_delay=0,
min_frequency=10):
self._max_length = max_length
self._max_count = max_count
self._last_dump = 0
self._skip_visuals = skip_visuals
self._snapshot_delay = snapshot_delay
self._file_name = None
self._result = None
Expand Down Expand Up @@ -86,53 +86,54 @@ def write(self, text, scale_factor=1):
def get_frame(trace):
if 'frame' in trace._trace['observation']:
frame = trace._trace['observation']['frame']
else:
frame = np.uint8(np.zeros((600, 800, 3)))
corner1 = (0, 0)
corner2 = (799, 0)
corner3 = (799, 599)
corner4 = (0, 599)
line_color = (0, 255, 255)
cv2.line(frame, corner1, corner2, line_color)
cv2.line(frame, corner2, corner3, line_color)
cv2.line(frame, corner3, corner4, line_color)
cv2.line(frame, corner4, corner1, line_color)
cv2.line(frame, (399, 0), (399, 799), line_color)
if frame != REMOVED_FRAME:
return frame
frame = np.uint8(np.zeros((600, 800, 3)))
corner1 = (0, 0)
corner2 = (799, 0)
corner3 = (799, 599)
corner4 = (0, 599)
line_color = (0, 255, 255)
cv2.line(frame, corner1, corner2, line_color)
cv2.line(frame, corner2, corner3, line_color)
cv2.line(frame, corner3, corner4, line_color)
cv2.line(frame, corner4, corner1, line_color)
cv2.line(frame, (399, 0), (399, 799), line_color)
writer = TextWriter(
frame,
trace['ball'][0],
trace['ball'][1],
field_coords=True,
color=(255, 0, 0))
writer.write('B')
for player_idx, player_coord in enumerate(trace['left_team']):
writer = TextWriter(
frame,
player_coord[0],
player_coord[1],
field_coords=True,
color=(0, 255, 0))
letter = 'H'
if 'active' in trace and player_idx in trace['active']:
letter = 'X'
elif 'left_agent_controlled_player' in trace and player_idx in trace[
'left_agent_controlled_player']:
letter = 'X'
writer.write(letter)
for player_idx, player_coord in enumerate(trace['right_team']):
writer = TextWriter(
frame,
trace['ball'][0],
trace['ball'][1],
player_coord[0],
player_coord[1],
field_coords=True,
color=(255, 0, 0))
writer.write('B')
for player_idx, player_coord in enumerate(trace['left_team']):
writer = TextWriter(
frame,
player_coord[0],
player_coord[1],
field_coords=True,
color=(0, 255, 0))
letter = 'H'
if 'active' in trace and player_idx in trace['active']:
letter = 'X'
elif 'left_agent_controlled_player' in trace and player_idx in trace[
'left_agent_controlled_player']:
letter = 'X'
writer.write(letter)
for player_idx, player_coord in enumerate(trace['right_team']):
writer = TextWriter(
frame,
player_coord[0],
player_coord[1],
field_coords=True,
color=(0, 0, 255))
letter = 'A'
if 'opponent_active' in trace and player_idx in trace['opponent_active']:
letter = 'Y'
elif 'right_agent_controlled_player' in trace and player_idx in trace[
'right_agent_controlled_player']:
letter = 'Y'
writer.write(letter)
color=(0, 0, 255))
letter = 'A'
if 'opponent_active' in trace and player_idx in trace['opponent_active']:
letter = 'Y'
elif 'right_agent_controlled_player' in trace and player_idx in trace[
'right_agent_controlled_player']:
letter = 'Y'
writer.write(letter)
return frame


Expand Down Expand Up @@ -216,7 +217,7 @@ def write_dump(name, trace, skip_visuals=False, config={}):
for o in trace:
if 'frame' in o._trace['observation']:
temp_frames.append(o._trace['observation']['frame'])
o._trace['observation']['frame'] = 'removed'
o._trace['observation']['frame'] = REMOVED_FRAME
to_pickle.append(o._trace)
with tf.io.gfile.GFile(name + '.dump', 'wb') as f:
six.moves.cPickle.dump(to_pickle, f)
Expand All @@ -229,14 +230,6 @@ def write_dump(name, trace, skip_visuals=False, config={}):
return True


def logging_write_dump(name, trace, skip_visuals=False, config={}):
try:
write_dump(name, trace, skip_visuals=skip_visuals, config=config)
except Exception as e:
logging.info(traceback.format_exc())
raise


class ObservationState(object):

def __init__(self, trace):
Expand All @@ -245,7 +238,6 @@ def __init__(self, trace):
self._additional_frames = []
self._debugs = []
self._time = timeit.default_timer()
self._right_defence_max_x = -10

def __getitem__(self, key):
if key in self._trace:
Expand Down Expand Up @@ -290,21 +282,17 @@ def __init__(self, config):
max_length=200,
max_count=(100000 if config['dump_scores'] else 0),
min_frequency=600,
snapshot_delay=10,
skip_visuals=not config['write_video'])
snapshot_delay=10)
self._dump_config['lost_score'] = DumpConfig(
max_length=200,
max_count=(100000 if config['dump_scores'] else 0),
min_frequency=600,
snapshot_delay=10,
skip_visuals=not config['write_video'])
snapshot_delay=10)
self._dump_config['episode_done'] = DumpConfig(
max_length=(200 if HIGH_RES else 10000),
max_count=(100000 if config['dump_full_episodes'] else 0),
skip_visuals=not config['write_video'])
max_count=(100000 if config['dump_full_episodes'] else 0))
self._dump_config['shutdown'] = DumpConfig(
max_length=(200 if HIGH_RES else 10000),
skip_visuals=not config['write_video'])
max_length=(200 if HIGH_RES else 10000))
self._thread_pool = None
self._dump_directory = None
self._config = config
Expand All @@ -331,13 +319,13 @@ def __getitem__(self, key):
return self._trace[key]

def add_frame(self, frame):
if len(self._trace) > 0:
if len(self._trace) > 0 and self._config['write_video']:
self._trace[-1].add_frame(frame)

@cfg.log
def update(self, trace):
self._frame += 1
if not self._config['write_video'] and 'frame' in trace:
if not self._config['write_video'] and 'frame' in trace['observation']:
# Don't record frame in the trace if we don't write video - full episode
# consumes over 8G.
no_video_trace = trace
Expand Down Expand Up @@ -385,11 +373,11 @@ def process_pending_dumps(self, finish):
if finish or config._trigger_step <= self._frame:
logging.info('Start dump %s', name)
trace = list(self._trace)[-config._max_length:]
write_dump(config._file_name, trace, config._skip_visuals,
write_dump(config._file_name, trace, self._config['write_video'],
self._config)
config._file_name = None
if config._result:
assert not config._file_name
if config._result.ready() or finish:
config._result.get()
config._result = None
config._result = None
Loading

0 comments on commit 325516e

Please sign in to comment.