Skip to content

Commit 325516e

Browse files
committed
Project import generated by Copybara.
PiperOrigin-RevId: 261857820
1 parent 5faba9c commit 325516e

34 files changed

Lines changed: 314 additions & 351 deletions

CHANGELOG

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@ Numbering scheme:
22
Each environment release number is of the form vX.Y. X is the major version
33
number, Y is the minor version number. Experiment results within the same X
44
should not change, as modifications made to the environment are either
5-
new features or backward compatible bug fixes. We will maintain vX branches
6-
pointing at the most recent vX.Y
5+
new features or backward compatible bug fixes. We will maintain vX branches
6+
pointing at the most recent vX.Y.
7+
8+
v1.2
9+
- Reduction of memory usage by the environment (https://github.com/google-research/football/issues/47).
10+
- Reduction of memory usage during compilation (https://github.com/google-research/football/issues/49).
11+
- Elimination of --no-pie compilation flag (https://github.com/google-research/football/issues/53).
12+
- Fix for broken wrappers.py (https://github.com/google-research/football/issues/54).
713

814
v1.1
915
- Add support for running multiple environment instances in a single process.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ are controlled by the following set of flags:
263263
If rendering is disabled (`render` config flag), the video contains a simple
264264
episode animation.
265265

266+
There are following scripts provided to operate on trace dumps:
267+
268+
- `dump_to_txt.py` - converts trace dump to human-readable form.
269+
- `dump_to_video.py` - converts trace dump to a 2D representation video.
270+
- `replay.py` - replays a given trace dump using environment.
271+
266272
## Frequent Problems & Solutions
267273

268274
### Rendering not working / "OpenGL version not equal to or higher than 3.2"

gfootball/build_game_engine.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
set -e
1616
# Delete pre-existing version of CMakeCache.txt to make 'pip3 install' work.
1717
rm -f third_party/gfootball_engine/CMakeCache.txt
18-
pushd third_party/gfootball_engine && cmake . && make -j && popd
18+
pushd third_party/gfootball_engine && cmake . && make -j `nproc` && popd
1919
pushd third_party/gfootball_engine && ln -sf libgame.so _gameplayfootball.so && popd

gfootball/dump_to_txt.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,36 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
1516
"""Script converting dump file to human readable format.
1617
1718
Example usage:
1819
python dump_to_txt.py --dump=/tmp/input.dump --output=/tmp/output.txt
1920
2021
"""
2122

23+
from __future__ import absolute_import
24+
from __future__ import division
25+
from __future__ import print_function
2226

27+
from gfootball.env import script_helpers
2328

2429
from absl import app
2530
from absl import flags
2631

27-
import six.moves.cPickle
28-
2932
FLAGS = flags.FLAGS
3033

31-
flags.DEFINE_string('dump', '', 'Trace file to convert')
32-
flags.DEFINE_string('output', '', 'Output txt file')
34+
flags.DEFINE_string('trace_file', None, 'Trace file to convert')
35+
flags.DEFINE_string('output', None, 'Output txt file')
3336
flags.DEFINE_bool('include_debug', True,
3437
'Include debug information for each step')
38+
flags.mark_flag_as_required('trace_file')
39+
flags.mark_flag_as_required('output')
3540

3641

3742
def main(_):
38-
with open(FLAGS.dump, 'rb') as f:
39-
replay = six.moves.cPickle.load(f)
40-
if not FLAGS.include_debug:
41-
for s in replay:
42-
if 'debug' in s:
43-
del s['debug']
44-
with open(FLAGS.output, 'w') as f:
45-
f.write(str(replay))
43+
script_helpers.ScriptHelpers().dump_to_txt(FLAGS.trace_file, FLAGS.output,
44+
FLAGS.include_debug)
4645

4746

4847
if __name__ == '__main__':
Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,16 @@
1616

1717
from absl import app
1818
from absl import flags
19-
from gfootball.env import config
20-
from gfootball.env import observation_processor
21-
22-
import six.moves.cPickle
19+
from gfootball.env import script_helpers
2320

2421
FLAGS = flags.FLAGS
25-
flags.DEFINE_string('file', '', 'Dump file to render')
22+
flags.DEFINE_string('trace_file', None, 'Trace file to render')
23+
flags.mark_flag_as_required('trace_file')
2624

2725

2826
def main(_):
29-
cfg = config.Config()
30-
cfg['dump_full_episodes'] = True
31-
cfg['write_video'] = True
32-
cfg['display_game_stats'] = True
33-
with open(FLAGS.file, 'rb') as f:
34-
dump = six.moves.cPickle.load(f)
35-
processor = observation_processor.ObservationProcessor(cfg)
36-
for frame in dump:
37-
processor.update(frame)
38-
processor.write_dump('episode_done')
27+
script_helpers.ScriptHelpers().dump_to_video(FLAGS.trace_file)
28+
3929

4030
if __name__ == '__main__':
4131
app.run(main)

gfootball/env/observation_processor.py

Lines changed: 56 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import six.moves.cPickle
3737
import tensorflow as tf
3838

39+
REMOVED_FRAME = 'removed'
40+
3941
try:
4042
import cv2
4143
except ImportError:
@@ -48,13 +50,11 @@ class DumpConfig(object):
4850
def __init__(self,
4951
max_length=200,
5052
max_count=1,
51-
skip_visuals=False,
5253
snapshot_delay=0,
5354
min_frequency=10):
5455
self._max_length = max_length
5556
self._max_count = max_count
5657
self._last_dump = 0
57-
self._skip_visuals = skip_visuals
5858
self._snapshot_delay = snapshot_delay
5959
self._file_name = None
6060
self._result = None
@@ -86,53 +86,54 @@ def write(self, text, scale_factor=1):
8686
def get_frame(trace):
8787
if 'frame' in trace._trace['observation']:
8888
frame = trace._trace['observation']['frame']
89-
else:
90-
frame = np.uint8(np.zeros((600, 800, 3)))
91-
corner1 = (0, 0)
92-
corner2 = (799, 0)
93-
corner3 = (799, 599)
94-
corner4 = (0, 599)
95-
line_color = (0, 255, 255)
96-
cv2.line(frame, corner1, corner2, line_color)
97-
cv2.line(frame, corner2, corner3, line_color)
98-
cv2.line(frame, corner3, corner4, line_color)
99-
cv2.line(frame, corner4, corner1, line_color)
100-
cv2.line(frame, (399, 0), (399, 799), line_color)
89+
if frame != REMOVED_FRAME:
90+
return frame
91+
frame = np.uint8(np.zeros((600, 800, 3)))
92+
corner1 = (0, 0)
93+
corner2 = (799, 0)
94+
corner3 = (799, 599)
95+
corner4 = (0, 599)
96+
line_color = (0, 255, 255)
97+
cv2.line(frame, corner1, corner2, line_color)
98+
cv2.line(frame, corner2, corner3, line_color)
99+
cv2.line(frame, corner3, corner4, line_color)
100+
cv2.line(frame, corner4, corner1, line_color)
101+
cv2.line(frame, (399, 0), (399, 799), line_color)
102+
writer = TextWriter(
103+
frame,
104+
trace['ball'][0],
105+
trace['ball'][1],
106+
field_coords=True,
107+
color=(255, 0, 0))
108+
writer.write('B')
109+
for player_idx, player_coord in enumerate(trace['left_team']):
110+
writer = TextWriter(
111+
frame,
112+
player_coord[0],
113+
player_coord[1],
114+
field_coords=True,
115+
color=(0, 255, 0))
116+
letter = 'H'
117+
if 'active' in trace and player_idx in trace['active']:
118+
letter = 'X'
119+
elif 'left_agent_controlled_player' in trace and player_idx in trace[
120+
'left_agent_controlled_player']:
121+
letter = 'X'
122+
writer.write(letter)
123+
for player_idx, player_coord in enumerate(trace['right_team']):
101124
writer = TextWriter(
102125
frame,
103-
trace['ball'][0],
104-
trace['ball'][1],
126+
player_coord[0],
127+
player_coord[1],
105128
field_coords=True,
106-
color=(255, 0, 0))
107-
writer.write('B')
108-
for player_idx, player_coord in enumerate(trace['left_team']):
109-
writer = TextWriter(
110-
frame,
111-
player_coord[0],
112-
player_coord[1],
113-
field_coords=True,
114-
color=(0, 255, 0))
115-
letter = 'H'
116-
if 'active' in trace and player_idx in trace['active']:
117-
letter = 'X'
118-
elif 'left_agent_controlled_player' in trace and player_idx in trace[
119-
'left_agent_controlled_player']:
120-
letter = 'X'
121-
writer.write(letter)
122-
for player_idx, player_coord in enumerate(trace['right_team']):
123-
writer = TextWriter(
124-
frame,
125-
player_coord[0],
126-
player_coord[1],
127-
field_coords=True,
128-
color=(0, 0, 255))
129-
letter = 'A'
130-
if 'opponent_active' in trace and player_idx in trace['opponent_active']:
131-
letter = 'Y'
132-
elif 'right_agent_controlled_player' in trace and player_idx in trace[
133-
'right_agent_controlled_player']:
134-
letter = 'Y'
135-
writer.write(letter)
129+
color=(0, 0, 255))
130+
letter = 'A'
131+
if 'opponent_active' in trace and player_idx in trace['opponent_active']:
132+
letter = 'Y'
133+
elif 'right_agent_controlled_player' in trace and player_idx in trace[
134+
'right_agent_controlled_player']:
135+
letter = 'Y'
136+
writer.write(letter)
136137
return frame
137138

138139

@@ -216,7 +217,7 @@ def write_dump(name, trace, skip_visuals=False, config={}):
216217
for o in trace:
217218
if 'frame' in o._trace['observation']:
218219
temp_frames.append(o._trace['observation']['frame'])
219-
o._trace['observation']['frame'] = 'removed'
220+
o._trace['observation']['frame'] = REMOVED_FRAME
220221
to_pickle.append(o._trace)
221222
with tf.io.gfile.GFile(name + '.dump', 'wb') as f:
222223
six.moves.cPickle.dump(to_pickle, f)
@@ -229,14 +230,6 @@ def write_dump(name, trace, skip_visuals=False, config={}):
229230
return True
230231

231232

232-
def logging_write_dump(name, trace, skip_visuals=False, config={}):
233-
try:
234-
write_dump(name, trace, skip_visuals=skip_visuals, config=config)
235-
except Exception as e:
236-
logging.info(traceback.format_exc())
237-
raise
238-
239-
240233
class ObservationState(object):
241234

242235
def __init__(self, trace):
@@ -245,7 +238,6 @@ def __init__(self, trace):
245238
self._additional_frames = []
246239
self._debugs = []
247240
self._time = timeit.default_timer()
248-
self._right_defence_max_x = -10
249241

250242
def __getitem__(self, key):
251243
if key in self._trace:
@@ -290,21 +282,17 @@ def __init__(self, config):
290282
max_length=200,
291283
max_count=(100000 if config['dump_scores'] else 0),
292284
min_frequency=600,
293-
snapshot_delay=10,
294-
skip_visuals=not config['write_video'])
285+
snapshot_delay=10)
295286
self._dump_config['lost_score'] = DumpConfig(
296287
max_length=200,
297288
max_count=(100000 if config['dump_scores'] else 0),
298289
min_frequency=600,
299-
snapshot_delay=10,
300-
skip_visuals=not config['write_video'])
290+
snapshot_delay=10)
301291
self._dump_config['episode_done'] = DumpConfig(
302292
max_length=(200 if HIGH_RES else 10000),
303-
max_count=(100000 if config['dump_full_episodes'] else 0),
304-
skip_visuals=not config['write_video'])
293+
max_count=(100000 if config['dump_full_episodes'] else 0))
305294
self._dump_config['shutdown'] = DumpConfig(
306-
max_length=(200 if HIGH_RES else 10000),
307-
skip_visuals=not config['write_video'])
295+
max_length=(200 if HIGH_RES else 10000))
308296
self._thread_pool = None
309297
self._dump_directory = None
310298
self._config = config
@@ -331,13 +319,13 @@ def __getitem__(self, key):
331319
return self._trace[key]
332320

333321
def add_frame(self, frame):
334-
if len(self._trace) > 0:
322+
if len(self._trace) > 0 and self._config['write_video']:
335323
self._trace[-1].add_frame(frame)
336324

337325
@cfg.log
338326
def update(self, trace):
339327
self._frame += 1
340-
if not self._config['write_video'] and 'frame' in trace:
328+
if not self._config['write_video'] and 'frame' in trace['observation']:
341329
# Don't record frame in the trace if we don't write video - full episode
342330
# consumes over 8G.
343331
no_video_trace = trace
@@ -385,11 +373,11 @@ def process_pending_dumps(self, finish):
385373
if finish or config._trigger_step <= self._frame:
386374
logging.info('Start dump %s', name)
387375
trace = list(self._trace)[-config._max_length:]
388-
write_dump(config._file_name, trace, config._skip_visuals,
376+
write_dump(config._file_name, trace, self._config['write_video'],
389377
self._config)
390378
config._file_name = None
391379
if config._result:
392380
assert not config._file_name
393381
if config._result.ready() or finish:
394382
config._result.get()
395-
config._result = None
383+
config._result = None

0 commit comments

Comments
 (0)