IncreasingLoss commited on
Commit
8ecd0b4
·
verified ·
1 Parent(s): 7e2a90d

Upload 3 files

Browse files
Files changed (1) hide show
  1. app.py +47 -18
app.py CHANGED
@@ -27,7 +27,10 @@ SIMULATION_FPS = 120 # Fixed simulation FPS, matching training
27
  RENDER_FPS = 30
28
  DT = 1.0 / SIMULATION_FPS # Fixed time step
29
  DT_DISPLAY = 1/RENDER_FPS
30
- DIFFICULTY = 1
 
 
 
31
 
32
  class AdaptiveFrameQueue:
33
  def __init__(self, maxsize=3):
@@ -87,7 +90,8 @@ def point_to_line_distance(point, line_p0, line_p1):
87
  class TrainingEnvironment:
88
  def __init__(self, action_space=8):
89
  self.action_space = action_space
90
- self.map_generator = MapGenerator(SCREEN_WIDTH, SCREEN_HEIGHT, DIFFICULTY, 18) # Difficulty 2 = lvl 3 in training
 
91
 
92
  # Initialize a dummy display for headless operation
93
  try:
@@ -124,7 +128,16 @@ class TrainingEnvironment:
124
  self.last_ray_update_time = 0
125
  self.reset()
126
 
 
 
 
 
 
 
 
127
  def generate_new_map(self):
 
 
128
  start_pos, start_dir = self.map_generator.update()
129
  self.start_pos = pygame.math.Vector2(start_pos)
130
  self.start_dir = pygame.math.Vector2(start_dir).normalize()
@@ -150,7 +163,8 @@ class TrainingEnvironment:
150
  self.last_action = 0
151
 
152
  def reset(self):
153
- self.map_generator.difficulty = 2 # Ensure difficulty matches training
 
154
  self.generate_new_map()
155
  self.reset_car()
156
 
@@ -401,11 +415,12 @@ class TrainingEnvironment:
401
 
402
  def optimized_game_loop():
403
  """Ultra-optimized game loop with 120 FPS simulation and 30 FPS rendering"""
 
404
  try:
405
  # Initialize without display
406
  screen = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
407
- env = TrainingEnvironment(ACTION_SPACE)
408
- env.reset()
409
  agent = PPOAgent(state_size, ACTION_SPACE)
410
 
411
  # Check if model file exists before loading
@@ -440,15 +455,15 @@ def optimized_game_loop():
440
  simulation_start = time.perf_counter()
441
 
442
  # Game logic
443
- state = env.get_state()
444
  action, _ = agent.select_action(state)
445
  action_int = int(action)
446
 
447
- env.execute_action_dispatch(action_int, simulation_dt)
448
- reward, collision, all_goals_completed = env.calculate_reward()
449
 
450
  if collision or all_goals_completed:
451
- env.reset()
452
 
453
  last_simulation_time = current_time
454
  simulation_counter += 1
@@ -465,16 +480,16 @@ def optimized_game_loop():
465
  screen.fill((255, 255, 255))
466
 
467
  # Draw environment components
468
- env.map_generator.draw(screen)
469
- env.car.draw(screen)
470
 
471
  # Optimized ray drawing - draw to separate surface first
472
  ray_surface.fill((0, 0, 0, 0)) # Clear with transparency
473
  for i, (angle, offset) in enumerate(zip([-60, -30, -15, 0, 15, 30, 60], [14, 22, 27, 26, 27, 22, 14])):
474
- if i < len(env.rays.last_collisions):
475
- ray_dir = env.car.direction.rotate(angle).normalize()
476
- origin = env.car.pos + ray_dir * offset
477
- end_point = env.rays.last_collisions[i]
478
  pygame.draw.line(ray_surface, (255, 255, 0),
479
  (int(origin.x), int(origin.y)),
480
  (int(end_point.x), int(end_point.y)), 2)
@@ -537,9 +552,16 @@ css = """#game-image {
537
  }"""
538
 
539
  def update_difficulty(input_diff_lvl):
540
- global DIFFICULTY
 
541
  DIFFICULTY = input_diff_lvl
542
- print(f"Difficulty updated to: {DIFFICULTY}")
 
 
 
 
 
 
543
 
544
  def execute_interference():
545
  game_thread = threading.Thread(target=optimized_game_loop)
@@ -550,7 +572,14 @@ def execute_interference():
550
  with gr.Column():
551
  img = gr.Image(type="pil", label="Game Stream", elem_id="game-image", scale=1, min_width=0)
552
  difficulty_slider = gr.Slider(minimum=1, maximum=2, step=1, value=2, label="Difficulty Level")
553
- difficulty_slider.change(fn=update_difficulty, inputs=difficulty_slider)
 
 
 
 
 
 
 
554
 
555
  timer = gr.Timer(value=DT_DISPLAY) # ~30 FPS
556
  timer.tick(fn=get_frame_for_gradio, inputs=None, outputs=img)
 
27
  RENDER_FPS = 30
28
  DT = 1.0 / SIMULATION_FPS # Fixed time step
29
  DT_DISPLAY = 1/RENDER_FPS
30
+ DIFFICULTY = 2
31
+
32
+ # Global variable to store the training environment instance
33
+ training_env = None
34
 
35
  class AdaptiveFrameQueue:
36
  def __init__(self, maxsize=3):
 
90
  class TrainingEnvironment:
91
  def __init__(self, action_space=8):
92
  self.action_space = action_space
93
+ self.current_difficulty = DIFFICULTY # Store current difficulty
94
+ self.map_generator = MapGenerator(SCREEN_WIDTH, SCREEN_HEIGHT, self.current_difficulty, 18)
95
 
96
  # Initialize a dummy display for headless operation
97
  try:
 
128
  self.last_ray_update_time = 0
129
  self.reset()
130
 
131
+ def update_difficulty(self, new_difficulty):
132
+ """Update difficulty and regenerate map if needed"""
133
+ if self.current_difficulty != new_difficulty:
134
+ self.current_difficulty = new_difficulty
135
+ self.map_generator.difficulty = new_difficulty
136
+ print(f"Environment difficulty updated to: {new_difficulty}")
137
+
138
  def generate_new_map(self):
139
+ # Update difficulty before generating new map
140
+ self.map_generator.difficulty = self.current_difficulty
141
  start_pos, start_dir = self.map_generator.update()
142
  self.start_pos = pygame.math.Vector2(start_pos)
143
  self.start_dir = pygame.math.Vector2(start_dir).normalize()
 
163
  self.last_action = 0
164
 
165
  def reset(self):
166
+ # Use current difficulty instead of hardcoding
167
+ self.map_generator.difficulty = self.current_difficulty
168
  self.generate_new_map()
169
  self.reset_car()
170
 
 
415
 
416
  def optimized_game_loop():
417
  """Ultra-optimized game loop with 120 FPS simulation and 30 FPS rendering"""
418
+ global training_env
419
  try:
420
  # Initialize without display
421
  screen = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
422
+ training_env = TrainingEnvironment(ACTION_SPACE) # Store globally
423
+ training_env.reset()
424
  agent = PPOAgent(state_size, ACTION_SPACE)
425
 
426
  # Check if model file exists before loading
 
455
  simulation_start = time.perf_counter()
456
 
457
  # Game logic
458
+ state = training_env.get_state()
459
  action, _ = agent.select_action(state)
460
  action_int = int(action)
461
 
462
+ training_env.execute_action_dispatch(action_int, simulation_dt)
463
+ reward, collision, all_goals_completed = training_env.calculate_reward()
464
 
465
  if collision or all_goals_completed:
466
+ training_env.reset()
467
 
468
  last_simulation_time = current_time
469
  simulation_counter += 1
 
480
  screen.fill((255, 255, 255))
481
 
482
  # Draw environment components
483
+ training_env.map_generator.draw(screen)
484
+ training_env.car.draw(screen)
485
 
486
  # Optimized ray drawing - draw to separate surface first
487
  ray_surface.fill((0, 0, 0, 0)) # Clear with transparency
488
  for i, (angle, offset) in enumerate(zip([-60, -30, -15, 0, 15, 30, 60], [14, 22, 27, 26, 27, 22, 14])):
489
+ if i < len(training_env.rays.last_collisions):
490
+ ray_dir = training_env.car.direction.rotate(angle).normalize()
491
+ origin = training_env.car.pos + ray_dir * offset
492
+ end_point = training_env.rays.last_collisions[i]
493
  pygame.draw.line(ray_surface, (255, 255, 0),
494
  (int(origin.x), int(origin.y)),
495
  (int(end_point.x), int(end_point.y)), 2)
 
552
  }"""
553
 
554
  def update_difficulty(input_diff_lvl):
555
+ """Updated difficulty function that communicates with the running environment"""
556
+ global DIFFICULTY, training_env
557
  DIFFICULTY = input_diff_lvl
558
+
559
+ # Update the running environment's difficulty
560
+ if training_env is not None:
561
+ training_env.update_difficulty(input_diff_lvl)
562
+
563
+ print(f"Difficulty updated to: {input_diff_lvl}")
564
+ return f"Difficulty set to: {input_diff_lvl} (will apply on next track)"
565
 
566
  def execute_interference():
567
  game_thread = threading.Thread(target=optimized_game_loop)
 
572
  with gr.Column():
573
  img = gr.Image(type="pil", label="Game Stream", elem_id="game-image", scale=1, min_width=0)
574
  difficulty_slider = gr.Slider(minimum=1, maximum=2, step=1, value=2, label="Difficulty Level")
575
+ difficulty_output = gr.Textbox(label="Status", interactive=False)
576
+
577
+ # Connect the slider to the update function with output
578
+ difficulty_slider.change(
579
+ fn=update_difficulty,
580
+ inputs=difficulty_slider,
581
+ outputs=difficulty_output
582
+ )
583
 
584
  timer = gr.Timer(value=DT_DISPLAY) # ~30 FPS
585
  timer.tick(fn=get_frame_for_gradio, inputs=None, outputs=img)