mahammadaftab commited on
Commit
8d03397
·
verified ·
1 Parent(s): 768c0e6

Updated app.py file

Browse files
Files changed (1) hide show
  1. app.py +187 -182
app.py CHANGED
@@ -124,113 +124,104 @@ def run_demo_episode(
124
  Returns:
125
  Tuple of (screenshot, metrics_text, grade_text)
126
  """
127
- # Check if we're in a headless environment (like HF Spaces)
128
- import os
129
- is_headless = os.environ.get('HF_SPACES') == '1' or not os.environ.get('DISPLAY', '')
130
-
131
- if is_headless:
132
- render_mode = None # Disable rendering in headless environments
133
-
134
- # Get configuration
135
- task_config = get_task_config(task_level)
136
-
137
- # Create environment
138
- env_config = EnvConfig(
139
- **task_config['config'],
140
- task_level=task_level,
141
- render_mode=render_mode,
142
- verbose=False,
143
- )
144
-
145
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  env = OpenEnv(config=env_config)
147
- except Exception as e:
148
- import traceback
149
- error_msg = f"Failed to create environment: {str(e)}\n\n{traceback.format_exc()}"
150
- print(error_msg)
151
- # Return placeholder image and error message
152
- placeholder = np.zeros((768, 1024, 3), dtype=np.uint8)
153
- return placeholder, "Error initializing environment", error_msg
154
-
155
- # Create grader
156
- grader = create_grader(task_level, task_config['grader'])
157
-
158
- # Reset
159
- obs, info = env.reset(seed=seed)
160
- grader.reset()
161
-
162
- # Run episode
163
- frames = []
164
- total_reward = 0.0
165
- steps = 0
166
- max_steps = 200 # Limit for demo
167
-
168
- prev_position = env.position.copy()
169
- optimal_distance = np.linalg.norm(env.target_position - env.position)
170
- grader.episode_data['optimal_distance'] = optimal_distance
171
-
172
- for step in range(max_steps):
173
- # Random action for demo (in real use, this would be your agent)
174
- action = env.action_space.sample()
175
 
176
- # Take step
177
- obs, reward, terminated, truncated, info = env.step(action)
 
 
 
 
 
 
 
178
 
179
- # Update grader
180
- current_position = env.position.copy()
181
- distance_delta = np.linalg.norm(current_position - prev_position)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  grader.update(
184
- steps=1,
185
- distance_traveled=distance_delta,
186
- energy_consumed=np.sum(np.abs(action)) * 0.5,
187
  )
188
 
189
- # Check collisions
190
- if hasattr(env, 'check_collision') and env.check_collision():
191
- grader.update(collisions=1)
192
-
193
- # Track wind deviation
194
- if env.config.wind_disturbance and hasattr(env, 'wind_deviation'):
195
- grader.update(max_wind_deviation=max(
196
- grader.episode_data['max_wind_deviation'],
197
- env.wind_deviation
198
- ))
199
-
200
- prev_position = current_position.copy()
201
- total_reward += reward
202
- steps += 1
203
-
204
- # Render frame (only if not headless)
205
- if render_mode == "rgb_array" and not is_headless:
206
- try:
207
- frame = env.render()
208
- if frame is not None:
209
- frames.append(frame)
210
- except Exception as e:
211
- print(f"Rendering error (non-fatal): {e}")
212
- # Continue without rendering
213
- pass
214
-
215
- # Check termination
216
- if terminated or truncated:
217
- break
218
-
219
- # Final updates
220
- final_distance = np.linalg.norm(env.position - env.target_position)
221
- target_radius = getattr(env, 'target_radius', 5.0)
222
-
223
- grader.update(
224
- target_reached=final_distance < target_radius,
225
- final_distance_to_target=final_distance,
226
- time_to_complete=steps,
227
- )
228
-
229
- # Get grade report
230
- grade_report = grader.get_grade_report()
231
-
232
- # Generate metrics text
233
- metrics_text = f"""
234
  **Episode Statistics:**
235
  - Steps: {steps}
236
  - Total Reward: {total_reward:.2f}
@@ -238,35 +229,43 @@ def run_demo_episode(
238
  - Target Reached: {'Yes ✓' if grade_report['episode_data']['target_reached'] else 'No ✗'}
239
  - Collisions: {grade_report['episode_data']['collisions']}
240
  """.strip()
241
-
242
- # Generate grade text
243
- grade_text = f"""
244
  **Performance Grade: {grade_report['final_score']:.2f} / 1.00**
245
 
246
  {grade_report['feedback']}
247
 
248
  **Criteria Scores:**
249
  """
250
-
251
- for criterion_name, score in grade_report['criteria_scores'].items():
252
- grade_text += f"\n- {criterion_name.replace('_', ' ').title()}: {score:.2f}"
253
-
254
- grade_text += f"\n\n**Status:** {'✓ PASSED' if grade_report['passed'] else '✗ FAILED'}"
255
- grade_text += f"\nThreshold: {grade_report['success_threshold']:.2f}"
256
-
257
- env.close()
258
-
259
- # Return appropriate image based on environment
260
- if is_headless or len(frames) == 0:
261
- # Create a simple placeholder image for headless environments
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  placeholder = np.zeros((768, 1024, 3), dtype=np.uint8)
263
- # Add some text to indicate it's a demo
264
- placeholder[:100, :300] = [200, 200, 200] # Light gray rectangle
265
- return placeholder, metrics_text, grade_text
266
- else:
267
- # Use middle frame as representative
268
- screenshot = frames[len(frames) // 2]
269
- return screenshot, metrics_text, grade_text
270
 
271
 
272
  def compare_all_levels(seed: int = 42):
@@ -279,66 +278,72 @@ def compare_all_levels(seed: int = 42):
279
  Returns:
280
  Comparison table text
281
  """
282
- results = []
283
-
284
- for level in ['easy', 'medium', 'hard']:
285
- task_config = get_task_config(level)
286
-
287
- # Check if we're in a headless environment
288
- import os
289
- is_headless = os.environ.get('HF_SPACES') == '1' or not os.environ.get('DISPLAY', '')
290
- render_mode = None if is_headless else None
291
-
292
- env_config = EnvConfig(
293
- **task_config['config'],
294
- task_level=level,
295
- render_mode=render_mode,
296
- verbose=False,
297
- )
298
-
299
- env = OpenEnv(config=env_config)
300
- grader_instance = create_grader(level, task_config['grader'])
301
-
302
- obs, _ = env.reset(seed=seed)
303
- grader_instance.reset()
304
 
305
- # Run episode
306
- done = False
307
- steps = 0
308
- while not done and steps < 300:
309
- action = env.action_space.sample()
310
- obs, reward, terminated, truncated, info = env.step(action)
311
 
312
- grader_instance.update(steps=1)
313
- done = terminated or truncated
314
- steps += 1
315
-
316
- # Final evaluation
317
- final_distance = np.linalg.norm(env.position - env.target_position)
318
- grader_instance.update(
319
- target_reached=final_distance < 5.0,
320
- final_distance_to_target=final_distance,
321
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
 
323
- grade_report = grader_instance.get_grade_report()
 
 
324
 
325
- results.append({
326
- 'level': level.upper(),
327
- 'score': grade_report['final_score'],
328
- 'passed': '✓' if grade_report['passed'] else '✗',
329
- 'steps': steps,
330
- })
331
 
332
- env.close()
333
-
334
- # Create comparison table
335
- table = "| Difficulty | Score | Status | Steps |\n"
336
- table += "|------------|-------|--------|-------|\n"
337
-
338
- for result in results:
339
- table += f"| {result['level']:10s} | {result['score']:.2f} | {result['passed']:6s} | {result['steps']:5d} |\n"
340
-
341
- return table
342
 
343
 
344
  def create_demo():
@@ -437,12 +442,12 @@ def create_demo():
437
  outputs=[comparison_output],
438
  )
439
 
440
- # Auto-run on load
441
- demo.load(
442
- fn=run_demo_episode,
443
- inputs=[task_level_dropdown, seed_slider],
444
- outputs=[output_image, metrics_output, grade_output],
445
- )
446
 
447
  gr.Markdown("""
448
  ---
 
124
  Returns:
125
  Tuple of (screenshot, metrics_text, grade_text)
126
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  try:
128
+ # Check if we're in a headless environment (like HF Spaces)
129
+ import os
130
+ is_headless = os.environ.get('HF_SPACES') == '1' or not os.environ.get('DISPLAY', '')
131
+
132
+ if is_headless:
133
+ render_mode = None # Disable rendering in headless environments
134
+
135
+ # Get configuration
136
+ task_config = get_task_config(task_level)
137
+
138
+ # Create environment
139
+ env_config = EnvConfig(
140
+ **task_config['config'],
141
+ task_level=task_level,
142
+ render_mode=render_mode,
143
+ verbose=False,
144
+ )
145
+
146
  env = OpenEnv(config=env_config)
147
+ grader = create_grader(task_level, task_config['grader'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
+ # Reset
150
+ obs, info = env.reset(seed=seed)
151
+ grader.reset()
152
+
153
+ # Run episode
154
+ frames = []
155
+ total_reward = 0.0
156
+ steps = 0
157
+ max_steps = 200 # Limit for demo
158
 
159
+ prev_position = env.position.copy()
160
+ optimal_distance = np.linalg.norm(env.target_position - env.position)
161
+ grader.episode_data['optimal_distance'] = optimal_distance
162
+
163
+ for step in range(max_steps):
164
+ # Random action for demo (in real use, this would be your agent)
165
+ action = env.action_space.sample()
166
+
167
+ # Take step
168
+ obs, reward, terminated, truncated, info = env.step(action)
169
+
170
+ # Update grader
171
+ current_position = env.position.copy()
172
+ distance_delta = np.linalg.norm(current_position - prev_position)
173
+
174
+ grader.update(
175
+ steps=1,
176
+ distance_traveled=distance_delta,
177
+ energy_consumed=np.sum(np.abs(action)) * 0.5,
178
+ )
179
+
180
+ # Check collisions
181
+ if hasattr(env, 'check_collision') and env.check_collision():
182
+ grader.update(collisions=1)
183
+
184
+ # Track wind deviation
185
+ if env.config.wind_disturbance and hasattr(env, 'wind_deviation'):
186
+ grader.update(max_wind_deviation=max(
187
+ grader.episode_data['max_wind_deviation'],
188
+ env.wind_deviation
189
+ ))
190
+
191
+ prev_position = current_position.copy()
192
+ total_reward += reward
193
+ steps += 1
194
+
195
+ # Render frame (only if not headless)
196
+ if render_mode == "rgb_array" and not is_headless:
197
+ try:
198
+ frame = env.render()
199
+ if frame is not None:
200
+ frames.append(frame)
201
+ except Exception as e:
202
+ print(f"Rendering error (non-fatal): {e}")
203
+ # Continue without rendering
204
+ pass
205
+
206
+ # Check termination
207
+ if terminated or truncated:
208
+ break
209
+
210
+ # Final updates
211
+ final_distance = np.linalg.norm(env.position - env.target_position)
212
+ target_radius = getattr(env, 'target_radius', 5.0)
213
 
214
  grader.update(
215
+ target_reached=final_distance < target_radius,
216
+ final_distance_to_target=final_distance,
217
+ time_to_complete=steps,
218
  )
219
 
220
+ # Get grade report
221
+ grade_report = grader.get_grade_report()
222
+
223
+ # Generate metrics text
224
+ metrics_text = f"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  **Episode Statistics:**
226
  - Steps: {steps}
227
  - Total Reward: {total_reward:.2f}
 
229
  - Target Reached: {'Yes ✓' if grade_report['episode_data']['target_reached'] else 'No ✗'}
230
  - Collisions: {grade_report['episode_data']['collisions']}
231
  """.strip()
232
+
233
+ # Generate grade text
234
+ grade_text = f"""
235
  **Performance Grade: {grade_report['final_score']:.2f} / 1.00**
236
 
237
  {grade_report['feedback']}
238
 
239
  **Criteria Scores:**
240
  """
241
+
242
+ for criterion_name, score in grade_report['criteria_scores'].items():
243
+ grade_text += f"\n- {criterion_name.replace('_', ' ').title()}: {score:.2f}"
244
+
245
+ grade_text += f"\n\n**Status:** {'✓ PASSED' if grade_report['passed'] else '✗ FAILED'}"
246
+ grade_text += f"\nThreshold: {grade_report['success_threshold']:.2f}"
247
+
248
+ env.close()
249
+
250
+ # Return appropriate image based on environment
251
+ if is_headless or len(frames) == 0:
252
+ # Create a simple placeholder image for headless environments
253
+ placeholder = np.zeros((768, 1024, 3), dtype=np.uint8)
254
+ # Add some text to indicate it's a demo
255
+ placeholder[:100, :300] = [200, 200, 200] # Light gray rectangle
256
+ return placeholder, metrics_text, grade_text
257
+ else:
258
+ # Use middle frame as representative
259
+ screenshot = frames[len(frames) // 2]
260
+ return screenshot, metrics_text, grade_text
261
+
262
+ except Exception as e:
263
+ import traceback
264
+ error_msg = f"Failed to run episode: {str(e)}\n\n{traceback.format_exc()}"
265
+ print(error_msg)
266
+ # Return placeholder image and error message
267
  placeholder = np.zeros((768, 1024, 3), dtype=np.uint8)
268
+ return placeholder, "Error running episode", error_msg
 
 
 
 
 
 
269
 
270
 
271
  def compare_all_levels(seed: int = 42):
 
278
  Returns:
279
  Comparison table text
280
  """
281
+ try:
282
+ results = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
+ for level in ['easy', 'medium', 'hard']:
285
+ task_config = get_task_config(level)
 
 
 
 
286
 
287
+ # Check if we're in a headless environment
288
+ import os
289
+ is_headless = os.environ.get('HF_SPACES') == '1' or not os.environ.get('DISPLAY', '')
290
+ render_mode = None if is_headless else None
291
+
292
+ env_config = EnvConfig(
293
+ **task_config['config'],
294
+ task_level=level,
295
+ render_mode=render_mode,
296
+ verbose=False,
297
+ )
298
+
299
+ env = OpenEnv(config=env_config)
300
+ grader_instance = create_grader(level, task_config['grader'])
301
+
302
+ obs, _ = env.reset(seed=seed)
303
+ grader_instance.reset()
304
+
305
+ # Run episode
306
+ done = False
307
+ steps = 0
308
+ while not done and steps < 300:
309
+ action = env.action_space.sample()
310
+ obs, reward, terminated, truncated, info = env.step(action)
311
+
312
+ grader_instance.update(steps=1)
313
+ done = terminated or truncated
314
+ steps += 1
315
+
316
+ # Final evaluation
317
+ final_distance = np.linalg.norm(env.position - env.target_position)
318
+ grader_instance.update(
319
+ target_reached=final_distance < 5.0,
320
+ final_distance_to_target=final_distance,
321
+ )
322
+
323
+ grade_report = grader_instance.get_grade_report()
324
+
325
+ results.append({
326
+ 'level': level.upper(),
327
+ 'score': grade_report['final_score'],
328
+ 'passed': '✓' if grade_report['passed'] else '✗',
329
+ 'steps': steps,
330
+ })
331
+
332
+ env.close()
333
 
334
+ # Create comparison table
335
+ table = "| Difficulty | Score | Status | Steps |\n"
336
+ table += "|------------|-------|--------|-------|\n"
337
 
338
+ for result in results:
339
+ table += f"| {result['level']:10s} | {result['score']:.2f} | {result['passed']:6s} | {result['steps']:5d} |\n"
 
 
 
 
340
 
341
+ return table
342
+ except Exception as e:
343
+ import traceback
344
+ error_msg = f"Failed to compare levels: {str(e)}\n\n{traceback.format_exc()}"
345
+ print(error_msg)
346
+ return f"Error comparing levels: {str(e)}"
 
 
 
 
347
 
348
 
349
  def create_demo():
 
442
  outputs=[comparison_output],
443
  )
444
 
445
+ # Remove auto-run on load to prevent startup issues
446
+ # demo.load(
447
+ # fn=run_demo_episode,
448
+ # inputs=[task_level_dropdown, seed_slider],
449
+ # outputs=[output_image, metrics_output, grade_output],
450
+ # )
451
 
452
  gr.Markdown("""
453
  ---