Skip to content

Commit 61694bf

Browse files
committed
Use Ctrl+S to save camera configuration
1 parent 760146c commit 61694bf

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

mujoco_viewer/callbacks.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import glfw
33
import numpy as np
44
import imageio
5+
import yaml
56
from threading import Lock
67

78

@@ -54,7 +55,7 @@ def _key_callback(self, window, key, scancode, action, mods):
5455
self._advance_by_one_step = True
5556
self._paused = True
5657
# Slows down simulation
57-
elif key == glfw.KEY_S:
58+
elif key == glfw.KEY_S and mods != glfw.MOD_CONTROL:
5859
self._run_speed /= 2.0
5960
# Speeds up simulation
6061
elif key == glfw.KEY_F:
@@ -121,6 +122,22 @@ def _key_callback(self, window, key, scancode, action, mods):
121122
# Geom group visibility
122123
elif key in (glfw.KEY_0, glfw.KEY_1, glfw.KEY_2, glfw.KEY_3, glfw.KEY_4, glfw.KEY_5):
123124
self.vopt.geomgroup[key - glfw.KEY_0] ^= 1
125+
elif key == glfw.KEY_S and mods == glfw.MOD_CONTROL:
126+
cam_config = {
127+
"type": self.cam.type,
128+
"fixedcamid": self.cam.fixedcamid,
129+
"trackbodyid": self.cam.trackbodyid,
130+
"lookat": self.cam.lookat.tolist(),
131+
"distance": self.cam.distance,
132+
"azimuth": self.cam.azimuth,
133+
"elevation": self.cam.elevation
134+
}
135+
try:
136+
with open(self.CONFIG_PATH, "w") as f:
137+
yaml.dump(cam_config, f)
138+
print("Camera config saved at {}".format(self.CONFIG_PATH))
139+
except Exception as e:
140+
print(e)
124141
# Quit
125142
if key == glfw.KEY_ESCAPE:
126143
print("Pressed ESC")

mujoco_viewer/mujoco_viewer.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import glfw
33
import numpy as np
44
import time
5+
import pathlib
6+
import yaml
57
from .callbacks import Callbacks
68

79

@@ -27,6 +29,9 @@ def __init__(
2729
# keep true while running
2830
self.is_alive = True
2931

32+
self.CONFIG_PATH = pathlib.Path.joinpath(
33+
pathlib.Path.home(), ".config/mujoco_viewer/config.yaml")
34+
3035
# glfw init
3136
glfw.init()
3237

@@ -68,6 +73,43 @@ def __init__(
6873
self.ctx = mujoco.MjrContext(
6974
self.model, mujoco.mjtFontScale.mjFONTSCALE_150.value)
7075

76+
# load camera from configuration (if available)
77+
pathlib.Path(
78+
self.CONFIG_PATH.parent).mkdir(
79+
parents=True,
80+
exist_ok=True)
81+
pathlib.Path(self.CONFIG_PATH).touch(exist_ok=True)
82+
with open(self.CONFIG_PATH, "r") as f:
83+
try:
84+
cam_config = {
85+
"type": self.cam.type,
86+
"fixedcamid": self.cam.fixedcamid,
87+
"trackbodyid": self.cam.trackbodyid,
88+
"lookat": self.cam.lookat.tolist(),
89+
"distance": self.cam.distance,
90+
"azimuth": self.cam.azimuth,
91+
"elevation": self.cam.elevation
92+
}
93+
load_config = yaml.safe_load(f)
94+
if isinstance(load_config, dict):
95+
for key, val in load_config.items():
96+
if key in cam_config.keys():
97+
cam_config[key] = val
98+
if cam_config["type"] == mujoco.mjtCamera.mjCAMERA_FIXED:
99+
if cam_config["fixedcamid"] < self.model.ncam:
100+
self.cam.type = cam_config["type"]
101+
self.cam.fixedcamid = cam_config["fixedcamid"]
102+
if cam_config["type"] == mujoco.mjtCamera.mjCAMERA_TRACKING:
103+
if cam_config["trackbodyid"] < self.model.nbody:
104+
self.cam.type = cam_config["type"]
105+
self.cam.trackbodyid = cam_config["trackbodyid"]
106+
self.cam.lookat = np.array(cam_config["lookat"])
107+
self.cam.distance = cam_config["distance"]
108+
self.cam.azimuth = cam_config["azimuth"]
109+
self.cam.elevation = cam_config["elevation"]
110+
except yaml.YAMLError as e:
111+
print(e)
112+
71113
# get viewport
72114
self.viewport = mujoco.MjrRect(
73115
0, 0, framebuffer_width, framebuffer_height)

0 commit comments

Comments
 (0)