From 1899e75d48e4d055c0b5be748e96b5e45c7a20fe Mon Sep 17 00:00:00 2001 From: Tucker Date: Mon, 11 Jul 2022 21:06:19 +0000 Subject: [PATCH 01/26] adding gif_recorder and recorder_wrapper into smarts.env.wrapper --- examples/SMARTS | 1 + smarts/env/wrappers/gif_recorder.py | 40 +++++++++++++++++ smarts/env/wrappers/recorder_wrapper.py | 60 +++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 160000 examples/SMARTS create mode 100644 smarts/env/wrappers/gif_recorder.py create mode 100644 smarts/env/wrappers/recorder_wrapper.py diff --git a/examples/SMARTS b/examples/SMARTS new file mode 160000 index 0000000000..9d97003351 --- /dev/null +++ b/examples/SMARTS @@ -0,0 +1 @@ +Subproject commit 9d97003351f8552a394255c25836aedfd840a3b5 diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py new file mode 100644 index 0000000000..fc84b611e6 --- /dev/null +++ b/smarts/env/wrappers/gif_recorder.py @@ -0,0 +1,40 @@ +import os + +from moviepy.editor import * +import gym.envs +import shutil + + +class GifRecorder: + def __init__(self, dir, env): + self.dir = dir + self.env = env + + try: + os.mkdir(self.dir) + except: + pass + + self.dir_name = None + if "/" not in dir: + self.dir_name = dir + else: + last_index = dir.rindex("/") + self.dir_name = dir[-(len(dir) - last_index - 1) :] + + def capture_frame(self, step_num): + image = self.env.render(mode="rgb_array") + + with ImageClip(image) as image_clip: + image_clip.save_frame(f"{self.dir}/{self.dir_name}_{step_num}.jpeg") + + def generate_gif(self): + with ImageSequenceClip(self.dir, fps=10) as clip: + clip.write_gif(f"videos/{self.dir_name}.gif") + clip.close() + + def close_recorder(self): + try: + shutil.rmtree(self.dir) + except: + pass diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py new file mode 100644 index 0000000000..2c2a2e5fd3 --- /dev/null +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -0,0 +1,60 @@ +import os + +from moviepy.editor import * +import gym +import gym.envs + +from smarts.env.wrappers.gif_recorder import GifRecorder + + +class RecorderWrapper(gym.Wrapper): + def __init__(self, dir, env): + + try: + os.mkdir("videos") + except: + pass + + super().__init__(env) + # assert "rgb_array" in env.metadata.get("render_modes", []) + self.dir = "videos/" + dir + self.gif_recorder = None + self.recording = False + self.current_frame = -1 + + def reset(self, **kwargs): + observations = super().reset(**kwargs) + if self.recording == False: + self.start_recording() + + return observations + + def start_recording(self): + if self.gif_recorder is None: + self.gif_recorder = GifRecorder(self.dir, self.env) + self.gif_recorder.capture_frame(self.next_frame_id()) + self.recording = True + + def stop_recording(self): + self.recording = False + + def step(self, action): + observations, rewards, dones, infos = super().step(action) + if self.recording == True: + self.gif_recorder.capture_frame(self.next_frame_id()) + + return observations, rewards, dones, infos + + def next_frame_id(self): + self.current_frame += 1 + return self.current_frame + + def close(self): + self.gif_recorder.close_recorder() + + def __del__(self): + self.gif_recorder.close_recorder() + + def close_recorder(self): + self.gif_recorder.generate_gif() + self.gif_recorder.close_recorder() From 12e99d8687d5aec4a41a72f662c9ad343523e7ff Mon Sep 17 00:00:00 2001 From: Tucker Date: Fri, 22 Jul 2022 18:11:34 +0000 Subject: [PATCH 02/26] add header to gif_recorder.py and recorder_wrapper.py. --- smarts/env/wrappers/gif_recorder.py | 41 +++++++++++++++++-------- smarts/env/wrappers/recorder_wrapper.py | 39 ++++++++++++++++++----- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index fc84b611e6..ce71d1ba33 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -1,13 +1,37 @@ +# MIT License +# +# Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. import os from moviepy.editor import * import gym.envs import shutil +import time +from pathlib import Path class GifRecorder: def __init__(self, dir, env): - self.dir = dir + timestamp_str = time.strftime("%Y%m%d-%H%M%S") + self.dir = dir + "_" + timestamp_str self.env = env try: @@ -15,22 +39,15 @@ def __init__(self, dir, env): except: pass - self.dir_name = None - if "/" not in dir: - self.dir_name = dir - else: - last_index = dir.rindex("/") - self.dir_name = dir[-(len(dir) - last_index - 1) :] - - def capture_frame(self, step_num): - image = self.env.render(mode="rgb_array") + self._dir_name = str(Path(dir).name) + def capture_frame(self, step_num, image): with ImageClip(image) as image_clip: - image_clip.save_frame(f"{self.dir}/{self.dir_name}_{step_num}.jpeg") + image_clip.save_frame(f"{self.dir}/{self._dir_name}_{step_num}.jpeg") def generate_gif(self): with ImageSequenceClip(self.dir, fps=10) as clip: - clip.write_gif(f"videos/{self.dir_name}.gif") + clip.write_gif(f"videos/{self._dir_name}.gif") clip.close() def close_recorder(self): diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index 2c2a2e5fd3..cf78d7c6b3 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -1,3 +1,24 @@ +# MIT License +# +# Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. import os from moviepy.editor import * @@ -32,7 +53,8 @@ def reset(self, **kwargs): def start_recording(self): if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.dir, self.env) - self.gif_recorder.capture_frame(self.next_frame_id()) + image = super().render(mode="rgb_array") + self.gif_recorder.capture_frame(self.next_frame_id(),image) self.recording = True def stop_recording(self): @@ -41,7 +63,8 @@ def stop_recording(self): def step(self, action): observations, rewards, dones, infos = super().step(action) if self.recording == True: - self.gif_recorder.capture_frame(self.next_frame_id()) + image = super().render(mode="rgb_array") + self.gif_recorder.capture_frame(self.next_frame_id(),image) return observations, rewards, dones, infos @@ -50,11 +73,11 @@ def next_frame_id(self): return self.current_frame def close(self): - self.gif_recorder.close_recorder() + if self.gif_recorder is not None: + self.gif_recorder.generate_gif() + self.gif_recorder.close_recorder() + self.gif_recorder = None + self.recording = False def __del__(self): - self.gif_recorder.close_recorder() - - def close_recorder(self): - self.gif_recorder.generate_gif() - self.gif_recorder.close_recorder() + self.close() From d75e8f25aa7c400379735f31a072253f7cd67fc6 Mon Sep 17 00:00:00 2001 From: Tucker Date: Fri, 22 Jul 2022 18:24:30 +0000 Subject: [PATCH 03/26] delete duplicated SMARTS inside example. --- examples/SMARTS | 1 - 1 file changed, 1 deletion(-) delete mode 160000 examples/SMARTS diff --git a/examples/SMARTS b/examples/SMARTS deleted file mode 160000 index 9d97003351..0000000000 --- a/examples/SMARTS +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9d97003351f8552a394255c25836aedfd840a3b5 From ab9a08df14f9d52153fda56e5bf39c8ee62f6d79 Mon Sep 17 00:00:00 2001 From: Tucker Date: Fri, 22 Jul 2022 19:13:04 +0000 Subject: [PATCH 04/26] add docstring the gif_recorder.py and recorder_wrapper.py. --- setup.py | 1 + smarts/env/wrappers/gif_recorder.py | 16 ++++++++++++++-- smarts/env/wrappers/recorder_wrapper.py | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a55ab0485b..b6249d9a38 100644 --- a/setup.py +++ b/setup.py @@ -69,6 +69,7 @@ "sphinxcontrib-apidoc>=0.3.0", ], "extras": ["pynput>=1.7.4"], # Used by HumanKeyboardAgent + "gym": ["moviepy = 1.0.3"] "remote_agent": ["grpcio==1.32.0"], "rllib": [ "opencv-python==4.1.2.30", diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index ce71d1ba33..fab2fd2628 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -21,8 +21,8 @@ # THE SOFTWARE. import os -from moviepy.editor import * -import gym.envs +from moviepy.editor import ImageClip +from moviepy.editor import ImageSequenceClip import shutil import time from pathlib import Path @@ -30,6 +30,9 @@ class GifRecorder: def __init__(self, dir, env): + """ + Use images(rgb_array) to create a gif file. + """ timestamp_str = time.strftime("%Y%m%d-%H%M%S") self.dir = dir + "_" + timestamp_str self.env = env @@ -42,15 +45,24 @@ def __init__(self, dir, env): self._dir_name = str(Path(dir).name) def capture_frame(self, step_num, image): + """ + Create image according to the rgb_array and store it with step number in the destinated folder + """ with ImageClip(image) as image_clip: image_clip.save_frame(f"{self.dir}/{self._dir_name}_{step_num}.jpeg") def generate_gif(self): + """ + Use the images in the same folder to create a gif file. + """ with ImageSequenceClip(self.dir, fps=10) as clip: clip.write_gif(f"videos/{self._dir_name}.gif") clip.close() def close_recorder(self): + """ + close the recorder by deleting the image folder. + """ try: shutil.rmtree(self.dir) except: diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index cf78d7c6b3..b562c439ae 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -29,6 +29,9 @@ class RecorderWrapper(gym.Wrapper): + """ + A Wrapper that interacts the gym environment with the GifRecorder to record video step by step. + """ def __init__(self, dir, env): try: @@ -44,6 +47,9 @@ def __init__(self, dir, env): self.current_frame = -1 def reset(self, **kwargs): + """ + Reset the gym environment and restart recording. + """ observations = super().reset(**kwargs) if self.recording == False: self.start_recording() @@ -51,6 +57,9 @@ def reset(self, **kwargs): return observations def start_recording(self): + """ + Start the gif recorder and capture the first frame. + """ if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.dir, self.env) image = super().render(mode="rgb_array") @@ -58,9 +67,15 @@ def start_recording(self): self.recording = True def stop_recording(self): + """ + Stop recording. + """ self.recording = False def step(self, action): + """ + Step the environment using the action and record the next frame. + """ observations, rewards, dones, infos = super().step(action) if self.recording == True: image = super().render(mode="rgb_array") @@ -69,10 +84,16 @@ def step(self, action): return observations, rewards, dones, infos def next_frame_id(self): + """ + Get the id for next frame. + """ self.current_frame += 1 return self.current_frame def close(self): + """ + Close the recorder by deleting the image folder and generate the gif file. + """ if self.gif_recorder is not None: self.gif_recorder.generate_gif() self.gif_recorder.close_recorder() From 9cefb8075cced0fa2e416996526d8272c14d0e55 Mon Sep 17 00:00:00 2001 From: Tucker Date: Mon, 11 Jul 2022 21:06:19 +0000 Subject: [PATCH 05/26] adding gif_recorder and recorder_wrapper into smarts.env.wrapper --- examples/SMARTS | 1 + smarts/env/wrappers/gif_recorder.py | 40 +++++++++++++++++ smarts/env/wrappers/recorder_wrapper.py | 60 +++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 160000 examples/SMARTS create mode 100644 smarts/env/wrappers/gif_recorder.py create mode 100644 smarts/env/wrappers/recorder_wrapper.py diff --git a/examples/SMARTS b/examples/SMARTS new file mode 160000 index 0000000000..9d97003351 --- /dev/null +++ b/examples/SMARTS @@ -0,0 +1 @@ +Subproject commit 9d97003351f8552a394255c25836aedfd840a3b5 diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py new file mode 100644 index 0000000000..fc84b611e6 --- /dev/null +++ b/smarts/env/wrappers/gif_recorder.py @@ -0,0 +1,40 @@ +import os + +from moviepy.editor import * +import gym.envs +import shutil + + +class GifRecorder: + def __init__(self, dir, env): + self.dir = dir + self.env = env + + try: + os.mkdir(self.dir) + except: + pass + + self.dir_name = None + if "/" not in dir: + self.dir_name = dir + else: + last_index = dir.rindex("/") + self.dir_name = dir[-(len(dir) - last_index - 1) :] + + def capture_frame(self, step_num): + image = self.env.render(mode="rgb_array") + + with ImageClip(image) as image_clip: + image_clip.save_frame(f"{self.dir}/{self.dir_name}_{step_num}.jpeg") + + def generate_gif(self): + with ImageSequenceClip(self.dir, fps=10) as clip: + clip.write_gif(f"videos/{self.dir_name}.gif") + clip.close() + + def close_recorder(self): + try: + shutil.rmtree(self.dir) + except: + pass diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py new file mode 100644 index 0000000000..2c2a2e5fd3 --- /dev/null +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -0,0 +1,60 @@ +import os + +from moviepy.editor import * +import gym +import gym.envs + +from smarts.env.wrappers.gif_recorder import GifRecorder + + +class RecorderWrapper(gym.Wrapper): + def __init__(self, dir, env): + + try: + os.mkdir("videos") + except: + pass + + super().__init__(env) + # assert "rgb_array" in env.metadata.get("render_modes", []) + self.dir = "videos/" + dir + self.gif_recorder = None + self.recording = False + self.current_frame = -1 + + def reset(self, **kwargs): + observations = super().reset(**kwargs) + if self.recording == False: + self.start_recording() + + return observations + + def start_recording(self): + if self.gif_recorder is None: + self.gif_recorder = GifRecorder(self.dir, self.env) + self.gif_recorder.capture_frame(self.next_frame_id()) + self.recording = True + + def stop_recording(self): + self.recording = False + + def step(self, action): + observations, rewards, dones, infos = super().step(action) + if self.recording == True: + self.gif_recorder.capture_frame(self.next_frame_id()) + + return observations, rewards, dones, infos + + def next_frame_id(self): + self.current_frame += 1 + return self.current_frame + + def close(self): + self.gif_recorder.close_recorder() + + def __del__(self): + self.gif_recorder.close_recorder() + + def close_recorder(self): + self.gif_recorder.generate_gif() + self.gif_recorder.close_recorder() From ece85c8f42eb99dc0ba6576d7c12a26856895d7b Mon Sep 17 00:00:00 2001 From: Tucker Date: Fri, 22 Jul 2022 18:11:34 +0000 Subject: [PATCH 06/26] add header to gif_recorder.py and recorder_wrapper.py. --- smarts/env/wrappers/gif_recorder.py | 41 +++++++++++++++++-------- smarts/env/wrappers/recorder_wrapper.py | 39 ++++++++++++++++++----- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index fc84b611e6..ce71d1ba33 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -1,13 +1,37 @@ +# MIT License +# +# Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. import os from moviepy.editor import * import gym.envs import shutil +import time +from pathlib import Path class GifRecorder: def __init__(self, dir, env): - self.dir = dir + timestamp_str = time.strftime("%Y%m%d-%H%M%S") + self.dir = dir + "_" + timestamp_str self.env = env try: @@ -15,22 +39,15 @@ def __init__(self, dir, env): except: pass - self.dir_name = None - if "/" not in dir: - self.dir_name = dir - else: - last_index = dir.rindex("/") - self.dir_name = dir[-(len(dir) - last_index - 1) :] - - def capture_frame(self, step_num): - image = self.env.render(mode="rgb_array") + self._dir_name = str(Path(dir).name) + def capture_frame(self, step_num, image): with ImageClip(image) as image_clip: - image_clip.save_frame(f"{self.dir}/{self.dir_name}_{step_num}.jpeg") + image_clip.save_frame(f"{self.dir}/{self._dir_name}_{step_num}.jpeg") def generate_gif(self): with ImageSequenceClip(self.dir, fps=10) as clip: - clip.write_gif(f"videos/{self.dir_name}.gif") + clip.write_gif(f"videos/{self._dir_name}.gif") clip.close() def close_recorder(self): diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index 2c2a2e5fd3..cf78d7c6b3 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -1,3 +1,24 @@ +# MIT License +# +# Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. import os from moviepy.editor import * @@ -32,7 +53,8 @@ def reset(self, **kwargs): def start_recording(self): if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.dir, self.env) - self.gif_recorder.capture_frame(self.next_frame_id()) + image = super().render(mode="rgb_array") + self.gif_recorder.capture_frame(self.next_frame_id(),image) self.recording = True def stop_recording(self): @@ -41,7 +63,8 @@ def stop_recording(self): def step(self, action): observations, rewards, dones, infos = super().step(action) if self.recording == True: - self.gif_recorder.capture_frame(self.next_frame_id()) + image = super().render(mode="rgb_array") + self.gif_recorder.capture_frame(self.next_frame_id(),image) return observations, rewards, dones, infos @@ -50,11 +73,11 @@ def next_frame_id(self): return self.current_frame def close(self): - self.gif_recorder.close_recorder() + if self.gif_recorder is not None: + self.gif_recorder.generate_gif() + self.gif_recorder.close_recorder() + self.gif_recorder = None + self.recording = False def __del__(self): - self.gif_recorder.close_recorder() - - def close_recorder(self): - self.gif_recorder.generate_gif() - self.gif_recorder.close_recorder() + self.close() From e8f0b4d6f4b9a321594ead484ea24e5a344878e1 Mon Sep 17 00:00:00 2001 From: Tucker Date: Fri, 22 Jul 2022 18:24:30 +0000 Subject: [PATCH 07/26] delete duplicated SMARTS inside example. --- examples/SMARTS | 1 - 1 file changed, 1 deletion(-) delete mode 160000 examples/SMARTS diff --git a/examples/SMARTS b/examples/SMARTS deleted file mode 160000 index 9d97003351..0000000000 --- a/examples/SMARTS +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9d97003351f8552a394255c25836aedfd840a3b5 From 0e381a2cc8d0e152f65f134220446f788cbb1b56 Mon Sep 17 00:00:00 2001 From: Tucker Date: Fri, 22 Jul 2022 19:13:04 +0000 Subject: [PATCH 08/26] add docstring the gif_recorder.py and recorder_wrapper.py. --- setup.py | 1 + smarts/env/wrappers/gif_recorder.py | 16 ++++++++++++++-- smarts/env/wrappers/recorder_wrapper.py | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a55ab0485b..b6249d9a38 100644 --- a/setup.py +++ b/setup.py @@ -69,6 +69,7 @@ "sphinxcontrib-apidoc>=0.3.0", ], "extras": ["pynput>=1.7.4"], # Used by HumanKeyboardAgent + "gym": ["moviepy = 1.0.3"] "remote_agent": ["grpcio==1.32.0"], "rllib": [ "opencv-python==4.1.2.30", diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index ce71d1ba33..fab2fd2628 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -21,8 +21,8 @@ # THE SOFTWARE. import os -from moviepy.editor import * -import gym.envs +from moviepy.editor import ImageClip +from moviepy.editor import ImageSequenceClip import shutil import time from pathlib import Path @@ -30,6 +30,9 @@ class GifRecorder: def __init__(self, dir, env): + """ + Use images(rgb_array) to create a gif file. + """ timestamp_str = time.strftime("%Y%m%d-%H%M%S") self.dir = dir + "_" + timestamp_str self.env = env @@ -42,15 +45,24 @@ def __init__(self, dir, env): self._dir_name = str(Path(dir).name) def capture_frame(self, step_num, image): + """ + Create image according to the rgb_array and store it with step number in the destinated folder + """ with ImageClip(image) as image_clip: image_clip.save_frame(f"{self.dir}/{self._dir_name}_{step_num}.jpeg") def generate_gif(self): + """ + Use the images in the same folder to create a gif file. + """ with ImageSequenceClip(self.dir, fps=10) as clip: clip.write_gif(f"videos/{self._dir_name}.gif") clip.close() def close_recorder(self): + """ + close the recorder by deleting the image folder. + """ try: shutil.rmtree(self.dir) except: diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index cf78d7c6b3..b562c439ae 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -29,6 +29,9 @@ class RecorderWrapper(gym.Wrapper): + """ + A Wrapper that interacts the gym environment with the GifRecorder to record video step by step. + """ def __init__(self, dir, env): try: @@ -44,6 +47,9 @@ def __init__(self, dir, env): self.current_frame = -1 def reset(self, **kwargs): + """ + Reset the gym environment and restart recording. + """ observations = super().reset(**kwargs) if self.recording == False: self.start_recording() @@ -51,6 +57,9 @@ def reset(self, **kwargs): return observations def start_recording(self): + """ + Start the gif recorder and capture the first frame. + """ if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.dir, self.env) image = super().render(mode="rgb_array") @@ -58,9 +67,15 @@ def start_recording(self): self.recording = True def stop_recording(self): + """ + Stop recording. + """ self.recording = False def step(self, action): + """ + Step the environment using the action and record the next frame. + """ observations, rewards, dones, infos = super().step(action) if self.recording == True: image = super().render(mode="rgb_array") @@ -69,10 +84,16 @@ def step(self, action): return observations, rewards, dones, infos def next_frame_id(self): + """ + Get the id for next frame. + """ self.current_frame += 1 return self.current_frame def close(self): + """ + Close the recorder by deleting the image folder and generate the gif file. + """ if self.gif_recorder is not None: self.gif_recorder.generate_gif() self.gif_recorder.close_recorder() From e48499dd0b15ac65cc5c6ea172d755214b3a29f2 Mon Sep 17 00:00:00 2001 From: Tucker Date: Mon, 25 Jul 2022 15:34:48 +0000 Subject: [PATCH 09/26] modified docstring and setup.py --- setup.py | 2 +- smarts/env/wrappers/gif_recorder.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index b6249d9a38..b8dc7e7d9b 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ "sphinxcontrib-apidoc>=0.3.0", ], "extras": ["pynput>=1.7.4"], # Used by HumanKeyboardAgent - "gym": ["moviepy = 1.0.3"] + "gym": ["moviepy = 1.0.3"], "remote_agent": ["grpcio==1.32.0"], "rllib": [ "opencv-python==4.1.2.30", diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index fab2fd2628..e72783b600 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -29,10 +29,10 @@ class GifRecorder: + """ + Use images(rgb_array) to create a gif file. + """ def __init__(self, dir, env): - """ - Use images(rgb_array) to create a gif file. - """ timestamp_str = time.strftime("%Y%m%d-%H%M%S") self.dir = dir + "_" + timestamp_str self.env = env From 7747b23bf27cd6aed72f8ed315bca8e4d75398a5 Mon Sep 17 00:00:00 2001 From: Tucker Date: Mon, 25 Jul 2022 17:20:37 +0000 Subject: [PATCH 10/26] modified setup.py. --- setup.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup.py b/setup.py index 2037970274..b8dc7e7d9b 100644 --- a/setup.py +++ b/setup.py @@ -69,11 +69,7 @@ "sphinxcontrib-apidoc>=0.3.0", ], "extras": ["pynput>=1.7.4"], # Used by HumanKeyboardAgent -<<<<<<< HEAD "gym": ["moviepy = 1.0.3"], -======= - "gym": ["moviepy = 1.0.3"] ->>>>>>> 0e381a2cc8d0e152f65f134220446f788cbb1b56 "remote_agent": ["grpcio==1.32.0"], "rllib": [ "opencv-python==4.1.2.30", From d8f66bb0a08feeb4c99f7297c502e1706c3c06f5 Mon Sep 17 00:00:00 2001 From: Tucker Date: Mon, 25 Jul 2022 17:26:17 +0000 Subject: [PATCH 11/26] modified setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b8dc7e7d9b..d02595a281 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ "sphinxcontrib-apidoc>=0.3.0", ], "extras": ["pynput>=1.7.4"], # Used by HumanKeyboardAgent - "gym": ["moviepy = 1.0.3"], + "gym": ["moviepy == 1.0.3"], "remote_agent": ["grpcio==1.32.0"], "rllib": [ "opencv-python==4.1.2.30", From 350c41b2b358655cba58ef5f03b6c6a85ee61408 Mon Sep 17 00:00:00 2001 From: Tucker Date: Mon, 25 Jul 2022 17:31:33 +0000 Subject: [PATCH 12/26] modified gif_recorder. --- smarts/env/wrappers/gif_recorder.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index fd94e8e5c7..e72783b600 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -29,17 +29,10 @@ class GifRecorder: -<<<<<<< HEAD """ Use images(rgb_array) to create a gif file. """ def __init__(self, dir, env): -======= - def __init__(self, dir, env): - """ - Use images(rgb_array) to create a gif file. - """ ->>>>>>> 0e381a2cc8d0e152f65f134220446f788cbb1b56 timestamp_str = time.strftime("%Y%m%d-%H%M%S") self.dir = dir + "_" + timestamp_str self.env = env From 788a37858a791457c3ec2e2cedf891b0df28ed0b Mon Sep 17 00:00:00 2001 From: Tucker Date: Wed, 27 Jul 2022 16:20:27 +0000 Subject: [PATCH 13/26] fixing import error --- smarts/env/wrappers/gif_recorder.py | 20 ++++++++++++++------ smarts/env/wrappers/recorder_wrapper.py | 15 +++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index e72783b600..c7b9ca9486 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -1,17 +1,17 @@ # MIT License -# +# # Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE @@ -20,9 +20,16 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os +import sys +import subprocess -from moviepy.editor import ImageClip -from moviepy.editor import ImageSequenceClip +try: + from moviepy.editor import ImageClip + from moviepy.editor import ImageSequenceClip +except: + subprocess.check_call([sys.executable, "-m", "pip", "install", "moviepy"]) + from moviepy.editor import ImageClip + from moviepy.editor import ImageSequenceClip import shutil import time from pathlib import Path @@ -32,6 +39,7 @@ class GifRecorder: """ Use images(rgb_array) to create a gif file. """ + def __init__(self, dir, env): timestamp_str = time.strftime("%Y%m%d-%H%M%S") self.dir = dir + "_" + timestamp_str diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index b562c439ae..06d9409b5b 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -1,17 +1,17 @@ # MIT License -# +# # Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE @@ -20,8 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os - -from moviepy.editor import * import gym import gym.envs @@ -32,6 +30,7 @@ class RecorderWrapper(gym.Wrapper): """ A Wrapper that interacts the gym environment with the GifRecorder to record video step by step. """ + def __init__(self, dir, env): try: @@ -63,7 +62,7 @@ def start_recording(self): if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.dir, self.env) image = super().render(mode="rgb_array") - self.gif_recorder.capture_frame(self.next_frame_id(),image) + self.gif_recorder.capture_frame(self.next_frame_id(), image) self.recording = True def stop_recording(self): @@ -79,7 +78,7 @@ def step(self, action): observations, rewards, dones, infos = super().step(action) if self.recording == True: image = super().render(mode="rgb_array") - self.gif_recorder.capture_frame(self.next_frame_id(),image) + self.gif_recorder.capture_frame(self.next_frame_id(), image) return observations, rewards, dones, infos From 20ee644acb03c462ea2f8e881b8ed5527bb70a8e Mon Sep 17 00:00:00 2001 From: Tucker Date: Wed, 27 Jul 2022 16:50:17 +0000 Subject: [PATCH 14/26] fixed import errors. --- smarts/env/wrappers/gif_recorder.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index c7b9ca9486..fc5224e10d 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -21,15 +21,15 @@ # THE SOFTWARE. import os import sys -import subprocess try: from moviepy.editor import ImageClip from moviepy.editor import ImageSequenceClip -except: - subprocess.check_call([sys.executable, "-m", "pip", "install", "moviepy"]) - from moviepy.editor import ImageClip - from moviepy.editor import ImageSequenceClip +except (ImportError, ModuleNotFoundError): + print(sys.exc_info()) + print( + "You may not have installed the [gym] dependencies required to capture the video. Install them first using the command `pip install -e .[gym]` at the source directory." + ) import shutil import time from pathlib import Path From 309f9043fdc1a65c8dcb9540836fcd2b02d0002d Mon Sep 17 00:00:00 2001 From: Changhe Chen Date: Tue, 16 Aug 2022 16:09:09 +0000 Subject: [PATCH 15/26] GitHub Actions: Update requirements.txt --- requirements.txt | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6922ef5f26..971f8f0f90 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ astunparse==1.6.3 async-timeout==4.0.2 asynctest==0.13.0 atari-py==0.2.6 -attrs==21.4.0 +attrs==22.1.0 Automat==20.2.0 beautifulsoup4==4.11.1 blessings==1.7 @@ -21,20 +21,20 @@ colorama==0.4.5 colorful==0.5.4 commonmark==0.9.1 constantly==15.1.0 -coverage==6.4.2 +coverage==6.4.4 cycler==0.11.0 dm-tree==0.1.7 eclipse-sumo==1.10.0 execnet==1.9.0 -filelock==3.7.1 +filelock==3.8.0 flatbuffers==1.12 -fonttools==4.34.4 -frozenlist==1.3.0 +fonttools==4.35.0 +frozenlist==1.3.1 future==0.18.2 gast==0.4.0 google==3.0.0 google-api-core==2.8.2 -google-auth==2.9.1 +google-auth==2.10.0 google-auth-oauthlib==0.4.6 google-pasta==0.2.0 googleapis-common-protos==1.56.4 @@ -51,21 +51,22 @@ incremental==21.3.0 iniconfig==1.1.1 jsonpatch==1.32 jsonpointer==2.3 -jsonschema==4.7.2 +jsonschema==4.10.0 keras==2.9.0 Keras-Preprocessing==1.1.2 kiwisolver==1.4.4 -libclang==14.0.1 -lz4==4.0.1 +libclang==14.0.6 +lz4==4.0.2 Markdown==3.4.1 -matplotlib==3.5.2 +MarkupSafe==2.1.1 +matplotlib==3.5.3 msgpack==1.0.4 multidict==6.0.2 numpy==1.21.6 nvidia-ml-py3==7.352.0 oauthlib==3.2.0 -opencensus==0.10.0 -opencensus-context==0.1.2 +opencensus==0.11.0 +opencensus-context==0.1.3 opencv-python==4.1.2.30 opencv-python-headless==4.1.2.30 opt-einsum==3.3.0 @@ -75,6 +76,7 @@ panda3d-gltf==0.13 panda3d-simplepbr==0.10 pandas==1.3.5 Pillow==9.2.0 +pkgutil_resolve_name==1.3.10 pluggy==1.0.0 prometheus-client==0.14.1 protobuf==3.19.4 @@ -85,7 +87,7 @@ py-spy==0.3.12 pyasn1==0.4.8 pyasn1-modules==0.2.8 pybullet==3.0.6 -Pygments==2.12.0 +Pygments==2.13.0 pyparsing==3.0.9 pyrsistent==0.18.1 pytest==7.1.2 @@ -94,9 +96,9 @@ pytest-cov==3.0.0 pytest-forked==1.4.0 pytest-xdist==2.5.0 python-dateutil==2.8.2 -pytz==2022.1 +pytz==2022.2.1 PyYAML==6.0 -pyzmq==23.2.0 +pyzmq==23.2.1 ray==1.0.1.post1 redis==3.4.1 requests==2.28.1 @@ -127,13 +129,13 @@ tornado==6.2 trimesh==3.9.29 Twisted==22.4.0 typing_extensions==4.3.0 -urllib3==1.26.10 +urllib3==1.26.11 visdom==0.1.8.9 wcwidth==0.2.5 websocket-client==1.3.3 -Werkzeug==2.1.2 +Werkzeug==2.2.2 wrapt==1.14.1 -yarl==1.7.2 +yarl==1.8.1 yattag==1.14.0 zipp==3.8.1 zope.interface==5.4.0 From bfd428e4d685bd250c70fe4307bbf0245f61d822 Mon Sep 17 00:00:00 2001 From: Changhe Chen Date: Tue, 16 Aug 2022 16:09:50 +0000 Subject: [PATCH 16/26] GitHub Actions: Format --- smarts/env/wrappers/gif_recorder.py | 3 +-- smarts/env/wrappers/recorder_wrapper.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index fc5224e10d..dcedbcea7d 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -23,8 +23,7 @@ import sys try: - from moviepy.editor import ImageClip - from moviepy.editor import ImageSequenceClip + from moviepy.editor import ImageClip, ImageSequenceClip except (ImportError, ModuleNotFoundError): print(sys.exc_info()) print( diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index 06d9409b5b..efa7ac98aa 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os + import gym import gym.envs From f4326a096b3a87683acc37f47917321e37fff6d7 Mon Sep 17 00:00:00 2001 From: Changhe Chen Date: Thu, 17 Nov 2022 15:38:53 +0000 Subject: [PATCH 17/26] GitHub Actions: Update requirements.txt --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index e38fa72425..34e5507080 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,7 +25,7 @@ coverage==6.5.0 cycler==0.11.0 dm-tree==0.1.7 eclipse-sumo==1.10.0 -exceptiongroup==1.0.3 +exceptiongroup==1.0.4 execnet==1.9.0 filelock==3.8.0 flatbuffers==22.10.26 @@ -38,7 +38,7 @@ google-api-core==2.10.2 google-auth==2.14.1 google-auth-oauthlib==0.4.6 google-pasta==0.2.0 -googleapis-common-protos==1.56.4 +googleapis-common-protos==1.57.0 gpustat==1.0.0 grpcio==1.50.0 gym==0.19.0 @@ -118,7 +118,7 @@ tensorboard==2.10.1 tensorboard-data-server==0.6.1 tensorboard-plugin-wit==1.8.1 tensorboardX==2.5.1 -tensorflow==2.10.0 +tensorflow==2.10.1 tensorflow-estimator==2.10.0 tensorflow-io-gcs-filesystem==0.27.0 termcolor==2.1.0 @@ -138,4 +138,4 @@ wrapt==1.14.1 yarl==1.8.1 yattag==1.14.0 zipp==3.10.0 -zope.interface==5.5.1 +zope.interface==5.5.2 From f6decd06a709694240fee85318fb498a9f7eb7fe Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Thu, 17 Nov 2022 14:32:19 -0500 Subject: [PATCH 18/26] modifying some class attributes names to be more clear, added documentation to clarify each path. --- smarts/env/wrappers/gif_recorder.py | 36 ++++++++++++++----------- smarts/env/wrappers/recorder_wrapper.py | 22 +++++++++------ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index dcedbcea7d..676bed6f4b 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -21,6 +21,9 @@ # THE SOFTWARE. import os import sys +import typing +import gym +import numpy as np try: from moviepy.editor import ImageClip, ImageSequenceClip @@ -39,38 +42,41 @@ class GifRecorder: Use images(rgb_array) to create a gif file. """ - def __init__(self, dir, env): + def __init__(self, video_name_folder: str, env: gym.Env): timestamp_str = time.strftime("%Y%m%d-%H%M%S") - self.dir = dir + "_" + timestamp_str + self.frame_folder = ( + video_name_folder + "_" + timestamp_str + ) # folder that uses to contain temporary frame images, will be deleted after the gif is created. self.env = env - try: - os.mkdir(self.dir) - except: - pass + Path.mkdir( + Path(self.frame_folder), exist_ok=True + ) # create temporary frame images folder if not exists. - self._dir_name = str(Path(dir).name) + self._video_root_path = str( + Path(video_name_folder).parent + ) # path of the video file + self._video_name = str(Path(video_name_folder).name) # name of the video - def capture_frame(self, step_num, image): + def capture_frame(self, step_num: int, image: np.ndarray): """ Create image according to the rgb_array and store it with step number in the destinated folder """ with ImageClip(image) as image_clip: - image_clip.save_frame(f"{self.dir}/{self._dir_name}_{step_num}.jpeg") + image_clip.save_frame( + f"{self.frame_folder}/{self._video_name}_{step_num}.jpeg" + ) def generate_gif(self): """ Use the images in the same folder to create a gif file. """ - with ImageSequenceClip(self.dir, fps=10) as clip: - clip.write_gif(f"videos/{self._dir_name}.gif") + with ImageSequenceClip(self.frame_folder, fps=10) as clip: + clip.write_gif(f"{self._video_root_path}/{self._video_name}.gif") clip.close() def close_recorder(self): """ close the recorder by deleting the image folder. """ - try: - shutil.rmtree(self.dir) - except: - pass + shutil.rmtree(self.frame_folder, ignore_errors=True) diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index efa7ac98aa..2569ab54e2 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -20,10 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os +import typing import gym import gym.envs +from pathlib import Path from smarts.env.wrappers.gif_recorder import GifRecorder @@ -32,16 +34,20 @@ class RecorderWrapper(gym.Wrapper): A Wrapper that interacts the gym environment with the GifRecorder to record video step by step. """ - def __init__(self, dir, env): + def __init__(self, video_name: str, env: gym.Env): - try: - os.mkdir("videos") - except: - pass + root_path = Path(__file__).parents[3] # smarts main repo path + video_folder = os.path.join( + root_path, "videos" + ) # video folder for all video recording file (.gif) + Path.mkdir( + Path(video_folder), exist_ok=True + ) # create video folder if not exist super().__init__(env) - # assert "rgb_array" in env.metadata.get("render_modes", []) - self.dir = "videos/" + dir + self.video_name_folder = os.path.join( + video_folder, video_name + ) # frames folder that uses to contain temporary frame images, will be created using video name and current time stamp in gif_recorder when recording starts self.gif_recorder = None self.recording = False self.current_frame = -1 @@ -61,7 +67,7 @@ def start_recording(self): Start the gif recorder and capture the first frame. """ if self.gif_recorder is None: - self.gif_recorder = GifRecorder(self.dir, self.env) + self.gif_recorder = GifRecorder(self.video_name_folder, self.env) image = super().render(mode="rgb_array") self.gif_recorder.capture_frame(self.next_frame_id(), image) self.recording = True From e5c8c8fc2f409ae41f74d3f167674becdaf84050 Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Thu, 17 Nov 2022 17:24:22 -0500 Subject: [PATCH 19/26] modified import error notification in gif_recorder.py --- smarts/env/wrappers/gif_recorder.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index 676bed6f4b..ba9909fed1 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -19,19 +19,21 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -import os import sys -import typing +import logging import gym import numpy as np try: from moviepy.editor import ImageClip, ImageSequenceClip except (ImportError, ModuleNotFoundError): - print(sys.exc_info()) - print( - "You may not have installed the [gym] dependencies required to capture the video. Install them first using the command `pip install -e .[gym]` at the source directory." + logging.warning(sys.exc_info()) + logging.warning( + "You may not have installed the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras." ) + + raise + import shutil import time from pathlib import Path From 111d9c5361ed682661097aa9b369bb0ce2f8d4dc Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Mon, 21 Nov 2022 10:40:10 -0500 Subject: [PATCH 20/26] added changedlog. --- CHANGELOG.md | 1 + ... first with the `smarts[gym]` extras.\":q" | 248 ++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 "talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" diff --git a/CHANGELOG.md b/CHANGELOG.md index d323f76a8d..9ecbe6b9f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Copy and pasting the git commit messages is __NOT__ enough. ## [Unreleased] ### Added - Added single vehicle `Trip` into type. +- Added new video record ultility using moviepy. ### Deprecated ### Changed ### Removed diff --git "a/talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" "b/talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" new file mode 100644 index 0000000000..a8f78adcdd --- /dev/null +++ "b/talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" @@ -0,0 +1,248 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ESC-u Undo (toggle) search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines + --------------------------------------------------- + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_> + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-M_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + :d Delete the current file from the command line list. + = ^G :f Print current file name. + --------------------------------------------------------------------------- + + MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS + + -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. + --_<_n_a_m_e_> Toggle a command line option, by name. + __<_f_l_a_g_> Display the setting of a command line option. + ___<_n_a_m_e_> Display the setting of an option, by name. + +_c_m_d Execute the less cmd each time a new file is examined. + + !_c_o_m_m_a_n_d Execute the shell command with $SHELL. + |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. + s _f_i_l_e Save input to a file. + v Edit the current file with $VISUAL or $EDITOR. + V Print version number of "less". + --------------------------------------------------------------------------- + + OOPPTTIIOONNSS + + Most options may be changed either on the command line, + or from within less by using the - or -- command. + Options may be given in one of two forms: either a single + character preceded by a -, or a name preceded by --. + + -? ........ --help + Display help (from command line). + -a ........ --search-skip-screen + Search skips current screen. + -A ........ --SEARCH-SKIP-SCREEN + Search starts just after target line. + -b [_N] .... --buffers=[_N] + Number of buffers. + -B ........ --auto-buffers + Don't automatically allocate buffers for pipes. + -c ........ --clear-screen + Repaint by clearing rather than scrolling. + -d ........ --dumb + Dumb terminal. + -D [_x_n_._n] . --color=_x_n_._n + Set screen colors. (MS-DOS only) + -e -E .... --quit-at-eof --QUIT-AT-EOF + Quit at end of file. + -f ........ --force + Force open non-regular files. + -F ........ --quit-if-one-screen + Quit if entire file fits on first screen. + -g ........ --hilite-search + Highlight only last match for searches. + -G ........ --HILITE-SEARCH + Don't highlight any matches for searches. + -h [_N] .... --max-back-scroll=[_N] + Backward scroll limit. + -i ........ --ignore-case + Ignore case in searches that do not contain uppercase. + -I ........ --IGNORE-CASE + Ignore case in all searches. + -j [_N] .... --jump-target=[_N] + Screen position of target lines. + -J ........ --status-column + Display a status column at left edge of screen. + -k [_f_i_l_e] . --lesskey-file=[_f_i_l_e] + Use a lesskey file. + -K ........ --quit-on-intr + Exit less in response to ctrl-C. + -L ........ --no-lessopen + Ignore the LESSOPEN environment variable. + -m -M .... --long-prompt --LONG-PROMPT + Set prompt style. + -n -N .... --line-numbers --LINE-NUMBERS + Don't use line numbers. + -o [_f_i_l_e] . --log-file=[_f_i_l_e] + Copy to log file (standard input only). + -O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e] + Copy to log file (unconditionally overwrite). + -p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n] + Start at pattern (from command line). + -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] + Define new prompt. + -q -Q .... --quiet --QUIET --silent --SILENT + Quiet the terminal bell. + -r -R .... --raw-control-chars --RAW-CONTROL-CHARS + Output "raw" control characters. + -s ........ --squeeze-blank-lines + Squeeze multiple blank lines. + -S ........ --chop-long-lines + Chop (truncate) long lines rather than wrapping. + -t [_t_a_g] .. --tag=[_t_a_g] + Find a tag. + -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] + Use an alternate tags file. + -u -U .... --underline-special --UNDERLINE-SPECIAL + Change handling of backspaces. + -V ........ --version + Display the version number of "less". + -w ........ --hilite-unread + Highlight first new line after forward-screen. + -W ........ --HILITE-UNREAD + Highlight first new line after any forward movement. + -x [_N[,...]] --tabs=[_N[,...]] + Set tab stops. + -X ........ --no-init + Don't use termcap init/deinit strings. + -y [_N] .... --max-forw-scroll=[_N] + Forward scroll limit. + -z [_N] .... --window=[_N] + Set size of window. + -" [_c[_c]] . --quotes=[_c[_c]] + Set shell quote characters. + -~ ........ --tilde + Don't display tildes after end of file. + -# [_N] .... --shift=[_N] + Horizontal scroll amount (0 = one half screen width) + --follow-name + The F command changes files if the input file is renamed. + --mouse + Enable mouse input. + --no-keypad + Don't send termcap keypad init/deinit strings. + --no-histdups + Remove duplicates from command history. + --rscroll=C + Set the character used to mark truncated lines. + --save-marks + Retain marks across invocations of less. + --use-backslash + Subsequent options use backslash as escape char. + --wheel-lines=N + Each click of the mouse wheel moves N lines. + + + --------------------------------------------------------------------------- + + LLIINNEE EEDDIITTIINNGG + + These keys can be used to edit text being entered + on the "command line" at the bottom of the screen. + + RightArrow ..................... ESC-l ... Move cursor right one character. + LeftArrow ...................... ESC-h ... Move cursor left one character. + ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. + ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. + HOME ........................... ESC-0 ... Move cursor to start of line. + END ............................ ESC-$ ... Move cursor to end of line. + BACKSPACE ................................ Delete char to left of cursor. + DELETE ......................... ESC-x ... Delete char under cursor. + ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. + ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. + ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. + UpArrow ........................ ESC-k ... Retrieve previous command line. + DownArrow ...................... ESC-j ... Retrieve next command line. + TAB ...................................... Complete filename & cycle. + SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. + ctrl-L ................................... Complete filename, list all. + + From 43c4a3b067e64c1b0c8b1c9bfef62c892201876c Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Mon, 21 Nov 2022 10:44:38 -0500 Subject: [PATCH 21/26] deleted unwanted file. --- ... first with the `smarts[gym]` extras.\":q" | 248 ------------------ 1 file changed, 248 deletions(-) delete mode 100644 "talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" diff --git "a/talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" "b/talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" deleted file mode 100644 index a8f78adcdd..0000000000 --- "a/talled the [gym] dependencies required to capture the video. Install them first with the `smarts[gym]` extras.\":q" +++ /dev/null @@ -1,248 +0,0 @@ - - SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS - - Commands marked with * may be preceded by a number, _N. - Notes in parentheses indicate the behavior if _N is given. - A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. - - h H Display this help. - q :q Q :Q ZZ Exit. - --------------------------------------------------------------------------- - - MMOOVVIINNGG - - e ^E j ^N CR * Forward one line (or _N lines). - y ^Y k ^K ^P * Backward one line (or _N lines). - f ^F ^V SPACE * Forward one window (or _N lines). - b ^B ESC-v * Backward one window (or _N lines). - z * Forward one window (and set window to _N). - w * Backward one window (and set window to _N). - ESC-SPACE * Forward one window, but don't stop at end-of-file. - d ^D * Forward one half-window (and set half-window to _N). - u ^U * Backward one half-window (and set half-window to _N). - ESC-) RightArrow * Right one half screen width (or _N positions). - ESC-( LeftArrow * Left one half screen width (or _N positions). - ESC-} ^RightArrow Right to last column displayed. - ESC-{ ^LeftArrow Left to first column. - F Forward forever; like "tail -f". - ESC-F Like F but stop when search pattern is found. - r ^R ^L Repaint screen. - R Repaint screen, discarding buffered input. - --------------------------------------------------- - Default "window" is the screen height. - Default "half-window" is half of the screen height. - --------------------------------------------------------------------------- - - SSEEAARRCCHHIINNGG - - /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. - ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. - n * Repeat previous search (for _N-th occurrence). - N * Repeat previous search in reverse direction. - ESC-n * Repeat previous search, spanning files. - ESC-N * Repeat previous search, reverse dir. & spanning files. - ESC-u Undo (toggle) search highlighting. - &_p_a_t_t_e_r_n * Display only matching lines - --------------------------------------------------- - A search pattern may begin with one or more of: - ^N or ! Search for NON-matching lines. - ^E or * Search multiple files (pass thru END OF FILE). - ^F or @ Start search at FIRST file (for /) or last file (for ?). - ^K Highlight matches, but don't move (KEEP position). - ^R Don't use REGULAR EXPRESSIONS. - --------------------------------------------------------------------------- - - JJUUMMPPIINNGG - - g < ESC-< * Go to first line in file (or line _N). - G > ESC-> * Go to last line in file (or line _N). - p % * Go to beginning of file (or _N percent into file). - t * Go to the (_N-th) next tag. - T * Go to the (_N-th) previous tag. - { ( [ * Find close bracket } ) ]. - } ) ] * Find open bracket { ( [. - ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. - ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_> - --------------------------------------------------- - Each "find close bracket" command goes forward to the close bracket - matching the (_N-th) open bracket in the top line. - Each "find open bracket" command goes backward to the open bracket - matching the (_N-th) close bracket in the bottom line. - - m_<_l_e_t_t_e_r_> Mark the current top line with . - M_<_l_e_t_t_e_r_> Mark the current bottom line with . - '_<_l_e_t_t_e_r_> Go to a previously marked position. - '' Go to the previous position. - ^X^X Same as '. - ESC-M_<_l_e_t_t_e_r_> Clear a mark. - --------------------------------------------------- - A mark is any upper-case or lower-case letter. - Certain marks are predefined: - ^ means beginning of the file - $ means end of the file - --------------------------------------------------------------------------- - - CCHHAANNGGIINNGG FFIILLEESS - - :e [_f_i_l_e] Examine a new file. - ^X^V Same as :e. - :n * Examine the (_N-th) next file from the command line. - :p * Examine the (_N-th) previous file from the command line. - :x * Examine the first (or _N-th) file from the command line. - :d Delete the current file from the command line list. - = ^G :f Print current file name. - --------------------------------------------------------------------------- - - MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS - - -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. - --_<_n_a_m_e_> Toggle a command line option, by name. - __<_f_l_a_g_> Display the setting of a command line option. - ___<_n_a_m_e_> Display the setting of an option, by name. - +_c_m_d Execute the less cmd each time a new file is examined. - - !_c_o_m_m_a_n_d Execute the shell command with $SHELL. - |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. - s _f_i_l_e Save input to a file. - v Edit the current file with $VISUAL or $EDITOR. - V Print version number of "less". - --------------------------------------------------------------------------- - - OOPPTTIIOONNSS - - Most options may be changed either on the command line, - or from within less by using the - or -- command. - Options may be given in one of two forms: either a single - character preceded by a -, or a name preceded by --. - - -? ........ --help - Display help (from command line). - -a ........ --search-skip-screen - Search skips current screen. - -A ........ --SEARCH-SKIP-SCREEN - Search starts just after target line. - -b [_N] .... --buffers=[_N] - Number of buffers. - -B ........ --auto-buffers - Don't automatically allocate buffers for pipes. - -c ........ --clear-screen - Repaint by clearing rather than scrolling. - -d ........ --dumb - Dumb terminal. - -D [_x_n_._n] . --color=_x_n_._n - Set screen colors. (MS-DOS only) - -e -E .... --quit-at-eof --QUIT-AT-EOF - Quit at end of file. - -f ........ --force - Force open non-regular files. - -F ........ --quit-if-one-screen - Quit if entire file fits on first screen. - -g ........ --hilite-search - Highlight only last match for searches. - -G ........ --HILITE-SEARCH - Don't highlight any matches for searches. - -h [_N] .... --max-back-scroll=[_N] - Backward scroll limit. - -i ........ --ignore-case - Ignore case in searches that do not contain uppercase. - -I ........ --IGNORE-CASE - Ignore case in all searches. - -j [_N] .... --jump-target=[_N] - Screen position of target lines. - -J ........ --status-column - Display a status column at left edge of screen. - -k [_f_i_l_e] . --lesskey-file=[_f_i_l_e] - Use a lesskey file. - -K ........ --quit-on-intr - Exit less in response to ctrl-C. - -L ........ --no-lessopen - Ignore the LESSOPEN environment variable. - -m -M .... --long-prompt --LONG-PROMPT - Set prompt style. - -n -N .... --line-numbers --LINE-NUMBERS - Don't use line numbers. - -o [_f_i_l_e] . --log-file=[_f_i_l_e] - Copy to log file (standard input only). - -O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e] - Copy to log file (unconditionally overwrite). - -p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n] - Start at pattern (from command line). - -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] - Define new prompt. - -q -Q .... --quiet --QUIET --silent --SILENT - Quiet the terminal bell. - -r -R .... --raw-control-chars --RAW-CONTROL-CHARS - Output "raw" control characters. - -s ........ --squeeze-blank-lines - Squeeze multiple blank lines. - -S ........ --chop-long-lines - Chop (truncate) long lines rather than wrapping. - -t [_t_a_g] .. --tag=[_t_a_g] - Find a tag. - -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] - Use an alternate tags file. - -u -U .... --underline-special --UNDERLINE-SPECIAL - Change handling of backspaces. - -V ........ --version - Display the version number of "less". - -w ........ --hilite-unread - Highlight first new line after forward-screen. - -W ........ --HILITE-UNREAD - Highlight first new line after any forward movement. - -x [_N[,...]] --tabs=[_N[,...]] - Set tab stops. - -X ........ --no-init - Don't use termcap init/deinit strings. - -y [_N] .... --max-forw-scroll=[_N] - Forward scroll limit. - -z [_N] .... --window=[_N] - Set size of window. - -" [_c[_c]] . --quotes=[_c[_c]] - Set shell quote characters. - -~ ........ --tilde - Don't display tildes after end of file. - -# [_N] .... --shift=[_N] - Horizontal scroll amount (0 = one half screen width) - --follow-name - The F command changes files if the input file is renamed. - --mouse - Enable mouse input. - --no-keypad - Don't send termcap keypad init/deinit strings. - --no-histdups - Remove duplicates from command history. - --rscroll=C - Set the character used to mark truncated lines. - --save-marks - Retain marks across invocations of less. - --use-backslash - Subsequent options use backslash as escape char. - --wheel-lines=N - Each click of the mouse wheel moves N lines. - - - --------------------------------------------------------------------------- - - LLIINNEE EEDDIITTIINNGG - - These keys can be used to edit text being entered - on the "command line" at the bottom of the screen. - - RightArrow ..................... ESC-l ... Move cursor right one character. - LeftArrow ...................... ESC-h ... Move cursor left one character. - ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. - ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. - HOME ........................... ESC-0 ... Move cursor to start of line. - END ............................ ESC-$ ... Move cursor to end of line. - BACKSPACE ................................ Delete char to left of cursor. - DELETE ......................... ESC-x ... Delete char under cursor. - ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. - ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. - ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. - UpArrow ........................ ESC-k ... Retrieve previous command line. - DownArrow ...................... ESC-j ... Retrieve next command line. - TAB ...................................... Complete filename & cycle. - SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. - ctrl-L ................................... Complete filename, list all. - - From 6b4ddf39807ccfe723ab6ce74520dae37d490837 Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Mon, 21 Nov 2022 15:30:24 -0500 Subject: [PATCH 22/26] modified workflows. --- .github/workflows/ci-base-tests-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-base-tests-linux.yml b/.github/workflows/ci-base-tests-linux.yml index f5b831a899..29d01f53f3 100644 --- a/.github/workflows/ci-base-tests-linux.yml +++ b/.github/workflows/ci-base-tests-linux.yml @@ -39,7 +39,7 @@ jobs: . ${{env.venv_dir}}/bin/activate pip install --upgrade pip pip install --upgrade wheel - pip install -e .[camera-obs,opendrive,rllib,test,test-notebook,torch,train] + pip install -e .[camera-obs,opendrive,rllib,test,test-notebook,torch,train,gym] - name: Run smoke tests run: | . ${{env.venv_dir}}/bin/activate From a543bb850416c6177edac4e881c03b091b9574bd Mon Sep 17 00:00:00 2001 From: Changhe Chen Date: Mon, 21 Nov 2022 20:35:40 +0000 Subject: [PATCH 23/26] GitHub Actions: Update requirements.txt --- requirements.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 34e5507080..f22b314408 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,8 +53,7 @@ iniconfig==1.1.1 jsonpatch==1.32 jsonpointer==2.3 jsonschema==4.17.0 -keras==2.10.0 -Keras-Preprocessing==1.1.2 +keras==2.11.0 kiwisolver==1.4.4 libclang==14.0.6 lz4==4.0.2 @@ -114,14 +113,14 @@ six==1.16.0 soupsieve==2.3.2.post1 tableprint==0.9.1 tabulate==0.9.0 -tensorboard==2.10.1 +tensorboard==2.11.0 tensorboard-data-server==0.6.1 tensorboard-plugin-wit==1.8.1 tensorboardX==2.5.1 -tensorflow==2.10.1 -tensorflow-estimator==2.10.0 +tensorflow==2.11.0 +tensorflow-estimator==2.11.0 tensorflow-io-gcs-filesystem==0.27.0 -termcolor==2.1.0 +termcolor==2.1.1 tomli==2.0.1 torch==1.4.0 torchvision==0.5.0 From 6c3a0ef342c25ee98fde84e5c421335b3c177be6 Mon Sep 17 00:00:00 2001 From: Changhe Chen Date: Mon, 21 Nov 2022 20:36:29 +0000 Subject: [PATCH 24/26] GitHub Actions: Format --- smarts/env/wrappers/gif_recorder.py | 3 ++- smarts/env/wrappers/recorder_wrapper.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/smarts/env/wrappers/gif_recorder.py b/smarts/env/wrappers/gif_recorder.py index ba9909fed1..a39e0b3c70 100644 --- a/smarts/env/wrappers/gif_recorder.py +++ b/smarts/env/wrappers/gif_recorder.py @@ -19,8 +19,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -import sys import logging +import sys + import gym import numpy as np diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index 2569ab54e2..10b4eab5c1 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -21,11 +21,11 @@ # THE SOFTWARE. import os import typing +from pathlib import Path import gym import gym.envs -from pathlib import Path from smarts.env.wrappers.gif_recorder import GifRecorder From b30cf4192743d4fa5efe7fdfa354f99c40798e42 Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Mon, 21 Nov 2022 15:59:45 -0500 Subject: [PATCH 25/26] moved import gif_recorder inside start_recording function to pass the test. --- .github/workflows/ci-base-tests-linux.yml | 2 +- smarts/env/wrappers/recorder_wrapper.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-base-tests-linux.yml b/.github/workflows/ci-base-tests-linux.yml index 29d01f53f3..f5b831a899 100644 --- a/.github/workflows/ci-base-tests-linux.yml +++ b/.github/workflows/ci-base-tests-linux.yml @@ -39,7 +39,7 @@ jobs: . ${{env.venv_dir}}/bin/activate pip install --upgrade pip pip install --upgrade wheel - pip install -e .[camera-obs,opendrive,rllib,test,test-notebook,torch,train,gym] + pip install -e .[camera-obs,opendrive,rllib,test,test-notebook,torch,train] - name: Run smoke tests run: | . ${{env.venv_dir}}/bin/activate diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index 10b4eab5c1..fbb44f43e8 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -26,8 +26,6 @@ import gym import gym.envs -from smarts.env.wrappers.gif_recorder import GifRecorder - class RecorderWrapper(gym.Wrapper): """ @@ -66,6 +64,8 @@ def start_recording(self): """ Start the gif recorder and capture the first frame. """ + from smarts.env.wrappers.gif_recorder import GifRecorder + if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.video_name_folder, self.env) image = super().render(mode="rgb_array") From 741cc6c411645034c8aaed75f4db16b53ff663f4 Mon Sep 17 00:00:00 2001 From: AisenGinn Date: Mon, 21 Nov 2022 16:11:18 -0500 Subject: [PATCH 26/26] revert changing. --- .github/workflows/ci-base-tests-linux.yml | 2 +- smarts/env/wrappers/recorder_wrapper.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-base-tests-linux.yml b/.github/workflows/ci-base-tests-linux.yml index f5b831a899..29d01f53f3 100644 --- a/.github/workflows/ci-base-tests-linux.yml +++ b/.github/workflows/ci-base-tests-linux.yml @@ -39,7 +39,7 @@ jobs: . ${{env.venv_dir}}/bin/activate pip install --upgrade pip pip install --upgrade wheel - pip install -e .[camera-obs,opendrive,rllib,test,test-notebook,torch,train] + pip install -e .[camera-obs,opendrive,rllib,test,test-notebook,torch,train,gym] - name: Run smoke tests run: | . ${{env.venv_dir}}/bin/activate diff --git a/smarts/env/wrappers/recorder_wrapper.py b/smarts/env/wrappers/recorder_wrapper.py index fbb44f43e8..10b4eab5c1 100644 --- a/smarts/env/wrappers/recorder_wrapper.py +++ b/smarts/env/wrappers/recorder_wrapper.py @@ -26,6 +26,8 @@ import gym import gym.envs +from smarts.env.wrappers.gif_recorder import GifRecorder + class RecorderWrapper(gym.Wrapper): """ @@ -64,8 +66,6 @@ def start_recording(self): """ Start the gif recorder and capture the first frame. """ - from smarts.env.wrappers.gif_recorder import GifRecorder - if self.gif_recorder is None: self.gif_recorder = GifRecorder(self.video_name_folder, self.env) image = super().render(mode="rgb_array")