neuralworm commited on
Commit
1423a2e
·
verified ·
1 Parent(s): f56fc73

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -41
app.py CHANGED
@@ -194,7 +194,7 @@ async def websocket_endpoint(websocket: WebSocket):
194
 
195
  # Wait for session init
196
  while not system.ready:
197
- await asyncio.sleep(system.tick_delay)
198
 
199
  # Send initial history
200
  history_msgs = [
@@ -205,43 +205,66 @@ async def websocket_endpoint(websocket: WebSocket):
205
 
206
  async def _emit_state():
207
  # --- ADAPTIVE NETWORK THROTTLE ---
208
- # Startwert: Konservativ (2 FPS)
209
  current_broadcast_interval = 0.5
210
  last_broadcast_time = 0
211
 
 
 
 
 
 
 
 
212
  while True:
213
  if not system.ready:
214
- await asyncio.sleep(system.tick_delay)
215
  continue
216
 
217
  try:
218
- # 1. PHYSIK SCHRITT (Hochfrequent, läuft immer)
219
- # ---------------------------------------------
220
- bg_noise = system.noise.get_blended_noise(size=40*40)
221
- stats = system.noise.get_source_stats()
222
- base_ntp = stats.get('ntp_offset', 0.0)
223
- off = system.sync_config['offset']
224
- total_offset = base_ntp + off
225
 
226
- current_braid = system.text_comm.last_text_unitary if system.text_comm else 0.0
227
- coupling = system.sync_config['coupling']
228
-
229
- system.holo.step(bg_noise, current_braid * coupling, ntp_offset=total_offset)
230
 
231
- if isinstance(system.text_comm.last_text_unitary, torch.Tensor):
232
- system.text_comm.last_text_unitary *= 0.95
 
233
 
234
- # 2. NETZWERK SCHRITT (Adaptiv)
235
- # -----------------------------
236
- now = time.time()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
- # Prüfen, ob wir wieder senden dürfen
239
  if now - last_broadcast_time > current_broadcast_interval:
240
 
241
- # MESSUNG STARTEN
242
  send_start_time = time.time()
243
 
244
- # --- Daten vorbereiten (Teuer!) ---
245
  metrics_raw = system.holo.get_metrics()
246
  phases = system.holo.phases.tolist()
247
  maps = system.holo.get_maps()
@@ -260,7 +283,6 @@ async def websocket_endpoint(websocket: WebSocket):
260
  "top": system.vocab.get_top_terms(5) if system.vocab else []
261
  }
262
 
263
- # --- Senden (Kann blockieren!) ---
264
  await websocket.send_json({
265
  "type": "state",
266
  "metrics": metrics,
@@ -273,30 +295,18 @@ async def websocket_endpoint(websocket: WebSocket):
273
 
274
  last_broadcast_time = time.time()
275
 
276
- # MESSUNG BEENDET
277
  send_duration = last_broadcast_time - send_start_time
278
-
279
- # --- DYNAMISCHE ANPASSUNG ---
280
- # Regel: Das Senden soll maximal 20% der Zeit beanspruchen.
281
- # Wenn Senden 0.1s dauert, warten wir 0.5s Pause.
282
- # Wenn Senden 0.01s dauert, warten wir nur 0.05s Pause.
283
-
284
- target_interval = send_duration * 5.0
285
-
286
- # Clamping:
287
- # Nicht schneller als 10 FPS (0.1s)
288
- # Nicht langsamer als 0.5 FPS (2.0s) - damit man nicht denkt es sei abgestürzt
289
  current_broadcast_interval = max(0.1, min(target_interval, 2.0))
290
-
291
- # Optional: Debugging im Log (kannst du auskommentieren)
292
- # print(f"Net Load: {send_duration:.3f}s -> New Interval: {current_broadcast_interval:.3f}s")
293
 
294
  except Exception as e:
295
- # print(f"Emit Error: {e}")
296
  pass
297
 
298
- # Schlafen basierend auf Physik-Tuner (z.B. 30 FPS)
299
- await asyncio.sleep(system.tick_delay)
 
 
300
 
301
  async def _receive_messages():
302
  try:
 
194
 
195
  # Wait for session init
196
  while not system.ready:
197
+ await asyncio.sleep(0.1)
198
 
199
  # Send initial history
200
  history_msgs = [
 
205
 
206
  async def _emit_state():
207
  # --- ADAPTIVE NETWORK THROTTLE ---
 
208
  current_broadcast_interval = 0.5
209
  last_broadcast_time = 0
210
 
211
+ # --- PHYSICS TIMEKEEPING ---
212
+ # Wir merken uns, wann der letzte Physik-Schritt simuliert wurde
213
+ last_physics_update_time = time.time()
214
+
215
+ # Das Ziel: Ein Physik-Schritt entspricht genau dieser Zeitspanne in der Realität
216
+ target_dt = system.tick_delay # z.B. 0.033s (30 FPS) oder 0.05s (20 FPS)
217
+
218
  while True:
219
  if not system.ready:
220
+ await asyncio.sleep(0.1)
221
  continue
222
 
223
  try:
224
+ # --- 1. CATCH-UP LOGIC (Das behebt die Zeitlupe) ---
225
+ # Wie viel Zeit ist in der echten Welt vergangen?
226
+ now = time.time()
227
+ real_time_passed = now - last_physics_update_time
 
 
 
228
 
229
+ # Wie viele Schritte hätten wir machen müssen?
230
+ steps_to_catch_up = int(real_time_passed / target_dt)
 
 
231
 
232
+ # Sicherheits-Limit: Nicht mehr als 20 Schritte auf einmal nachholen,
233
+ # sonst hängt die CPU bei Lag ewig fest (Death Spiral).
234
+ steps_to_catch_up = min(steps_to_catch_up, 20)
235
 
236
+ if steps_to_catch_up > 0:
237
+ # Wir holen die verpasste Zeit nach!
238
+ # Bereite Inputs vor (bleiben für den Burst gleich)
239
+ bg_noise = system.noise.get_blended_noise(size=40*40)
240
+ stats = system.noise.get_source_stats()
241
+ base_ntp = stats.get('ntp_offset', 0.0)
242
+ off = system.sync_config['offset']
243
+ total_offset = base_ntp + off
244
+
245
+ current_braid = system.text_comm.last_text_unitary if system.text_comm else 0.0
246
+ coupling = system.sync_config['coupling']
247
+
248
+ # BURST MODE: Rechne die Physik schnell hintereinander
249
+ for _ in range(steps_to_catch_up):
250
+ system.holo.step(bg_noise, current_braid * coupling, ntp_offset=total_offset)
251
+
252
+ # Decay muss auch pro Schritt passieren
253
+ if isinstance(system.text_comm.last_text_unitary, torch.Tensor):
254
+ system.text_comm.last_text_unitary *= 0.95
255
+
256
+ # Zeitstempel aktualisieren
257
+ last_physics_update_time += (steps_to_catch_up * target_dt)
258
+
259
+ # 2. NETZWERK SCHRITT (Adaptiv & Entkoppelt)
260
+ # ------------------------------------------
261
+ # Wir senden nur den LETZTEN Stand nach dem Burst.
262
+ # Die Schritte dazwischen werden übersprungen (Frame Skipping), genau wie du wolltest.
263
 
 
264
  if now - last_broadcast_time > current_broadcast_interval:
265
 
 
266
  send_start_time = time.time()
267
 
 
268
  metrics_raw = system.holo.get_metrics()
269
  phases = system.holo.phases.tolist()
270
  maps = system.holo.get_maps()
 
283
  "top": system.vocab.get_top_terms(5) if system.vocab else []
284
  }
285
 
 
286
  await websocket.send_json({
287
  "type": "state",
288
  "metrics": metrics,
 
295
 
296
  last_broadcast_time = time.time()
297
 
298
+ # Adaptives Intervall berechnen
299
  send_duration = last_broadcast_time - send_start_time
300
+ target_interval = send_duration * 4.0 # 25% Load Target
 
 
 
 
 
 
 
 
 
 
301
  current_broadcast_interval = max(0.1, min(target_interval, 2.0))
 
 
 
302
 
303
  except Exception as e:
 
304
  pass
305
 
306
+ # Kurzer Sleep, um CPU nicht zu grillen.
307
+ # Da wir die Catch-Up Logik haben, ist die exakte Dauer hier egal.
308
+ # 0.01s gibt der CPU genug Zeit zum Atmen.
309
+ await asyncio.sleep(0.01)
310
 
311
  async def _receive_messages():
312
  try: