| … | … | @@ -0,0 +1,103 @@ |
| 1 | # ------------------------------------------------------------------------------------------------ |
| 2 | # Copyright (c) 2016 Microsoft Corporation |
| 3 | # |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and |
| 5 | # associated documentation files (the "Software"), to deal in the Software without restriction, |
| 6 | # including without limitation the rights to use, copy, modify, merge, publish, distribute, |
| 7 | # sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
| 8 | # furnished to do so, subject to the following conditions: |
| 9 | # |
| 10 | # The above copyright notice and this permission notice shall be included in all copies or |
| 11 | # substantial portions of the Software. |
| 12 | # |
| 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT |
| 14 | # NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 15 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| 16 | # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 17 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 18 | # ------------------------------------------------------------------------------------------------ |
| 19 | |
| 20 | from __future__ import print_function |
| 21 | |
| 22 | # Allow MalmoPython to be imported both from an installed |
| 23 | # malmo module and (as an override) separately as a native library. |
| 24 | try: |
| 25 | from rocca.malmo import MalmoPython |
| 26 | except ImportError: |
| 27 | import malmo.MalmoPython as MalmoPython |
| 28 | |
| 29 | import os |
| 30 | import sys |
| 31 | import errno |
| 32 | |
| 33 | def fix_print(): |
| 34 | # We want to flush the print output immediately, so that we can view test output as it happens. |
| 35 | # The way to do this changed completely between Python 2 and 3, with the result that setting this |
| 36 | # in a cross-compatible way requires a few lines of ugly code. |
| 37 | # Rather than include this mess in every single sample, it's nice to wrap it into a handy |
| 38 | # function - hence this. |
| 39 | if sys.version_info[0] == 2: |
| 40 | sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) # flush print output immediately |
| 41 | else: |
| 42 | import functools |
| 43 | # Have to assign to builtins or the change won't make it outside of this module's scope |
| 44 | import builtins |
| 45 | builtins.print = functools.partial(print, flush=True) |
| 46 | |
| 47 | def parse_command_line(agent_host, argv=None): |
| 48 | if argv is None: |
| 49 | argv = sys.argv |
| 50 | # Add standard options required by test suite: |
| 51 | agent_host.addOptionalStringArgument( "recording_dir,r", "Path to location for saving mission recordings", "" ) |
| 52 | agent_host.addOptionalFlag( "record_video,v", "Record video stream" ) |
| 53 | # Attempt to parse: |
| 54 | try: |
| 55 | agent_host.parse(argv) |
| 56 | except RuntimeError as e: |
| 57 | print('ERROR:',e) |
| 58 | print(agent_host.getUsage()) |
| 59 | exit(1) |
| 60 | if agent_host.receivedArgument("help"): |
| 61 | print(agent_host.getUsage()) |
| 62 | exit(0) |
| 63 | |
| 64 | |
| 65 | def get_video_xml(agent_host): |
| 66 | return '<VideoProducer><Width>860</Width><Height>480</Height></VideoProducer>' if agent_host.receivedArgument("record_video") else '' |
| 67 | |
| 68 | def get_default_recording_object(agent_host, filename): |
| 69 | # Convenience method for setting up a recording object - assuming the recording_dir and record_video |
| 70 | # flags were passed in as command line arguments (see parse_command_line above). |
| 71 | # (If no recording destination was passed in, we assume no recording is required.) |
| 72 | my_mission_record = MalmoPython.MissionRecordSpec() |
| 73 | recordingsDirectory = get_recordings_directory(agent_host) |
| 74 | if recordingsDirectory: |
| 75 | my_mission_record.setDestination(recordingsDirectory + "//" + filename + ".tgz") |
| 76 | my_mission_record.recordRewards() |
| 77 | my_mission_record.recordObservations() |
| 78 | my_mission_record.recordCommands() |
| 79 | if agent_host.receivedArgument("record_video"): |
| 80 | my_mission_record.recordMP4(24,2000000) |
| 81 | return my_mission_record |
| 82 | |
| 83 | def get_recordings_directory(agent_host): |
| 84 | # Check the dir passed in: |
| 85 | recordingsDirectory = agent_host.getStringArgument('recording_dir') |
| 86 | if recordingsDirectory: |
| 87 | # If we're running as an integration test, we want to send all our recordings |
| 88 | # to the central test location specified in the environment variable MALMO_TEST_RECORDINGS_PATH: |
| 89 | if agent_host.receivedArgument("test"): |
| 90 | try: |
| 91 | test_path = os.environ['MALMO_TEST_RECORDINGS_PATH'] |
| 92 | if test_path: |
| 93 | recordingsDirectory = os.path.join(test_path, recordingsDirectory) |
| 94 | except: |
| 95 | pass |
| 96 | # Now attempt to create the folder we want to write to: |
| 97 | try: |
| 98 | os.makedirs(recordingsDirectory) |
| 99 | except OSError as exception: |
| 100 | if exception.errno != errno.EEXIST: # ignore error if already existed |
| 101 | raise |
| 102 | return recordingsDirectory |
| 103 | |