SemSorter commited on
Commit
cca7c61
·
1 Parent(s): 0f9a8f0

Fix Render Server Crash: Switch to osmesa and lower memory usage

Browse files
Dockerfile CHANGED
@@ -10,6 +10,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
10
  libglx0 \
11
  libx11-6 \
12
  libopengl0 \
 
 
 
13
  wget \
14
  git \
15
  && apt-get clean \
@@ -32,8 +35,8 @@ RUN git clone --depth 1 --filter=blob:none --sparse https://github.com/google-de
32
  && rm -rf .git
33
 
34
  # ── MuJoCo environment ────────────────────────────────────────────────────────
35
- ENV MUJOCO_GL=egl
36
- ENV PYOPENGL_PLATFORM=egl
37
 
38
  # ── Expose port ───────────────────────────────────────────────────────────────
39
  EXPOSE 8000
 
10
  libglx0 \
11
  libx11-6 \
12
  libopengl0 \
13
+ libosmesa6 \
14
+ libegl-mesa0 \
15
+ libgl1-mesa-dri \
16
  wget \
17
  git \
18
  && apt-get clean \
 
35
  && rm -rf .git
36
 
37
  # ── MuJoCo environment ────────────────────────────────────────────────────────
38
+ ENV MUJOCO_GL=osmesa
39
+ ENV PYOPENGL_PLATFORM=osmesa
40
 
41
  # ── Expose port ───────────────────────────────────────────────────────────────
42
  EXPOSE 8000
SemSorter/server/agent_bridge.py CHANGED
@@ -160,7 +160,7 @@ def get_simulation():
160
  global _sim
161
  with _sim_lock:
162
  if _sim is None:
163
- os.environ.setdefault("MUJOCO_GL", "egl")
164
  from controller import SemSorterSimulation
165
  logger.info("Initialising MuJoCo simulation…")
166
  _sim = SemSorterSimulation()
@@ -417,7 +417,7 @@ def render_frame(camera: str = "overview"):
417
  """
418
  with _sim_lock:
419
  sim = get_simulation()
420
- return sim.render_frame(camera=camera, width=960, height=540)
421
 
422
 
423
  def get_latest_frame_jpeg() -> Optional[bytes]:
 
160
  global _sim
161
  with _sim_lock:
162
  if _sim is None:
163
+ os.environ.setdefault("MUJOCO_GL", "osmesa")
164
  from controller import SemSorterSimulation
165
  logger.info("Initialising MuJoCo simulation…")
166
  _sim = SemSorterSimulation()
 
417
  """
418
  with _sim_lock:
419
  sim = get_simulation()
420
+ return sim.render_frame(camera=camera, width=sim._stream_width, height=sim._stream_height)
421
 
422
 
423
  def get_latest_frame_jpeg() -> Optional[bytes]:
SemSorter/simulation/controller.py CHANGED
@@ -113,8 +113,8 @@ class SemSorterSimulation:
113
  self._stream_fps_busy = float(
114
  os.environ.get("SEMSORTER_STREAM_FPS_BUSY", "30.0")
115
  )
116
- self._stream_width = int(os.environ.get("SEMSORTER_STREAM_WIDTH", "960"))
117
- self._stream_height = int(os.environ.get("SEMSORTER_STREAM_HEIGHT", "540"))
118
  self._freeze_conveyor_when_busy = (
119
  os.environ.get("SEMSORTER_FREEZE_CONVEYOR_WHEN_BUSY", "1").strip()
120
  in {"1", "true", "yes", "on"}
@@ -167,8 +167,8 @@ class SemSorterSimulation:
167
  spec.modelname = "semsorter"
168
 
169
  # Set offscreen framebuffer size for rendering (lowered to save RAM on Render Free Tier)
170
- spec.visual.global_.offwidth = 960
171
- spec.visual.global_.offheight = 540
172
 
173
  # ─── Add additional lights ───────────────────────────────────────
174
  world = spec.worldbody
@@ -229,6 +229,9 @@ class SemSorterSimulation:
229
 
230
  # ─── Compile the model ──────────────────────────────────────────
231
  self.model = spec.compile()
 
 
 
232
  self.data = mujoco.MjData(self.model)
233
 
234
  # Keep floor contacts in the environment collision group (not robot group).
 
113
  self._stream_fps_busy = float(
114
  os.environ.get("SEMSORTER_STREAM_FPS_BUSY", "30.0")
115
  )
116
+ self._stream_width = int(os.environ.get("SEMSORTER_STREAM_WIDTH", "480"))
117
+ self._stream_height = int(os.environ.get("SEMSORTER_STREAM_HEIGHT", "270"))
118
  self._freeze_conveyor_when_busy = (
119
  os.environ.get("SEMSORTER_FREEZE_CONVEYOR_WHEN_BUSY", "1").strip()
120
  in {"1", "true", "yes", "on"}
 
167
  spec.modelname = "semsorter"
168
 
169
  # Set offscreen framebuffer size for rendering (lowered to save RAM on Render Free Tier)
170
+ spec.visual.global_.offwidth = self._stream_width
171
+ spec.visual.global_.offheight = self._stream_height
172
 
173
  # ─── Add additional lights ───────────────────────────────────────
174
  world = spec.worldbody
 
229
 
230
  # ─── Compile the model ──────────────────────────────────────────
231
  self.model = spec.compile()
232
+ # Further reduce runtime memory allocations by explicitly dropping large arrays
233
+ self.model.opt.disableflags |= mujoco.mjtDisableBit.mjDSBL_EULERDAMP
234
+ self.model.opt.disableflags |= mujoco.mjtDisableBit.mjDSBL_MIDPHASE
235
  self.data = mujoco.MjData(self.model)
236
 
237
  # Keep floor contacts in the environment collision group (not robot group).
requirements-server.txt CHANGED
@@ -9,7 +9,6 @@ numpy==1.26.4
9
 
10
  # MuJoCo (headless, EGL)
11
  mujoco==3.5.0
12
- PyOpenGL-accelerate==3.1.7
13
 
14
  # Google Gemini (legacy + new SDK — both used for compatibility)
15
  google-generativeai==0.8.3
 
9
 
10
  # MuJoCo (headless, EGL)
11
  mujoco==3.5.0
 
12
 
13
  # Google Gemini (legacy + new SDK — both used for compatibility)
14
  google-generativeai==0.8.3