Spaces:
Sleeping
Sleeping
File size: 10,899 Bytes
9100ec4 1049992 9100ec4 1049992 9100ec4 1049992 70631ec 9100ec4 913c12d 47d05b3 9100ec4 47d05b3 9100ec4 871ce11 9100ec4 47d05b3 1049992 9100ec4 1049992 9100ec4 6afd8cb 9100ec4 1049992 9100ec4 1049992 9100ec4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# app.py - النسخة النهائية باستخدام gr.Dataset
import os
import json
import gradio as gr
import base64
from PIL import Image
import io
import requests
# ==============================================================================
# 1. إعدادات الـ API
# ==============================================================================
API_URL_BASE = "https://BaseerAI-baseer-server.hf.space"
API_START_SESSION_URL = f"{API_URL_BASE}/start_session"
API_RUN_STEP_URL = f"{API_URL_BASE}/run_step"
API_END_SESSION_URL = f"{API_URL_BASE}/end_session"
EXAMPLES_DIR = "examples"
# ==============================================================================
# 2. الدوال المساعدة والدوال التي تتصل بالـ API
# ==============================================================================
def image_to_base64(pil_image):
buffered = io.BytesIO()
pil_image.save(buffered, format="JPEG")
return base64.b64encode(buffered.getvalue()).decode('utf-8')
def base64_to_image(b64_string):
img_data = base64.b64decode(b64_string)
return Image.open(io.BytesIO(img_data))
def start_new_session():
print("Requesting to start a new session...")
try:
response = requests.post(API_START_SESSION_URL, timeout=30)
response.raise_for_status()
session_data = response.json()
session_id = session_data.get("session_id")
if not session_id:
raise gr.Error("لم يتمكن الخادم من بدء جلسة جديدة.")
status_message = f"✅ تم بدء جلسة جديدة بنجاح. أنت الآن متصل بالخادم."
print(f"Session started successfully: {session_id}")
return session_id, status_message, gr.update(visible=True)
except requests.exceptions.RequestException as e:
error_message = f"فشل الاتصال بخادم الـ API: {e}"
print(error_message)
raise gr.Error(error_message)
def handle_end_session(session_id):
if not session_id:
return "لا توجد جلسة نشطة لإنهائها.", None, gr.update(visible=False)
print(f"Requesting to end session: {session_id}")
try:
response = requests.post(f"{API_END_SESSION_URL}?session_id={session_id}", timeout=30)
response.raise_for_status()
status_message = f"🔌 تم إنهاء الجلسة بنجاح. انقطع الاتصال بالخادم."
print(status_message)
return status_message, None, gr.update(visible=False)
except requests.exceptions.RequestException as e:
error_message = f"حدث خطأ أثناء إنهاء الجلسة: {e}"
print(error_message)
raise gr.Error(error_message)
def run_single_frame_via_api(session_id, rgb_image_path, measurements_path):
if not session_id:
raise gr.Error("لا توجد جلسة نشطة. يرجى بدء جلسة جديدة أولاً.")
if not (rgb_image_path and measurements_path):
raise gr.Error("الرجاء توفير الصورة الأمامية وملف القياسات على الأقل.")
try:
rgb_image_pil = Image.open(rgb_image_path).convert("RGB")
# التأكد من أن المسار هو ملف صالح قبل فتحه
if not isinstance(measurements_path, str) or not os.path.exists(measurements_path):
raise gr.Error(f"مسار ملف القياسات غير صالح أو مفقود: {measurements_path}")
with open(measurements_path, 'r') as f:
measurements_dict = json.load(f)
image_b64 = image_to_base64(rgb_image_pil)
payload = {
"session_id": session_id, "image_b64": image_b64,
"measurements": {
"pos_global": measurements_dict.get('pos_global', [0.0, 0.0]),
"theta": measurements_dict.get('theta', 0.0),
"speed": measurements_dict.get('speed', 0.0),
"target_point": measurements_dict.get('target_point', [0.0, 100.0])
}
}
print(f"Sending run_step request for session: {session_id}")
response = requests.post(API_RUN_STEP_URL, json=payload, timeout=60)
response.raise_for_status()
api_result = response.json()
dashboard_b64 = api_result.get("dashboard_b64")
control_commands = api_result.get("control_commands", {})
if not dashboard_b64:
raise gr.Error("لم يتم إرجاع صورة لوحة التحكم من الـ API.")
output_image = base64_to_image(dashboard_b64)
return output_image, control_commands
except FileNotFoundError:
raise gr.Error(f"لم يتم العثور على الملف: {measurements_path}")
except requests.exceptions.RequestException as e:
raise gr.Error(f"حدث خطأ أثناء الاتصال بالـ API: {e}")
except Exception as e:
raise gr.Error(f"حدث خطأ غير متوقع: {e}")
# ==============================================================================
# 3. إعداد بيانات الأمثلة
# ==============================================================================
# قائمة تحتوي على البيانات الكاملة لكل مثال
FULL_EXAMPLES_DATA = []
# قائمة تحتوي فقط على البيانات التي سيتم عرضها في الجدول
SAMPLES_FOR_DISPLAY = []
if os.path.isdir(EXAMPLES_DIR):
try:
for i in range(1, 5):
sample_name = f"sample{i}"
img_path = os.path.join(EXAMPLES_DIR, sample_name, "rgb.jpg")
json_path = os.path.join(EXAMPLES_DIR, sample_name, "measurements.json")
with open(json_path, 'r') as f:
data = json.load(f)
# إضافة البيانات الكاملة
FULL_EXAMPLES_DATA.append({
"img_path": img_path,
"json_path": json_path
})
# إضافة بيانات العرض فقط
SAMPLES_FOR_DISPLAY.append([
img_path,
f"{data.get('speed', 0.0):.2f}",
f"{data.get('theta', 0.0):.2f}",
str(data.get('pos_global', 'N/A')),
str(data.get('target_point', 'N/A'))
])
except FileNotFoundError:
print(f"تحذير: لم يتم العثور على بعض ملفات الأمثلة في مجلد '{EXAMPLES_DIR}'.")
FULL_EXAMPLES_DATA = []
SAMPLES_FOR_DISPLAY = []
# ==============================================================================
# 4. تعريف واجهة Gradio
# ==============================================================================
# لم نعد بحاجة إلى CSS معقد
CUSTOM_CSS = ".gradio-container {max-width: 100% !important;}"
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"), css=CUSTOM_CSS) as demo:
session_id_state = gr.State(value=None)
gr.Markdown("# 🚗 Baseer Self-Driving System Dashboard")
gr.Markdown("This interface acts as a **client** that connects to the **[Baseer Self-Driving API](https://huggingface.co/spaces/BaseerAI/Baseer_Server)** for data processing.")
gr.Markdown("---")
with gr.Group():
gr.Markdown("## ⚙️ Session Control")
with gr.Row():
start_session_button = gr.Button("🟢 Start New Session", variant="primary")
end_session_button = gr.Button("🔴 End Current Session")
status_textbox = gr.Textbox(label="Session Status", interactive=False, value="Waiting to start session...")
gr.Markdown("")
with gr.Group(visible=False) as main_controls_group:
with gr.Row(equal_height=False):
with gr.Column(scale=2):
with gr.Group():
gr.Markdown("### 🗂️ Upload Scenario Files")
api_rgb_image_path = gr.Image(type="filepath", label="(RGB Image)")
api_measurements_path = gr.File(label="(Measurements JSON)", type="filepath")
api_run_button = gr.Button("🚀 Send Data for Processing", variant="primary")
with gr.Group():
gr.Markdown("### ✨ Preloaded Examples")
if SAMPLES_FOR_DISPLAY:
def on_example_select(evt: gr.SelectData):
selected_example = FULL_EXAMPLES_DATA[evt.index]
return gr.update(value=selected_example["img_path"]), gr.update(value=selected_example["json_path"])
with gr.Column(visible=False):
example_image = gr.Image(label="Image", type="filepath")
example_speed = gr.Textbox(label="Speed")
example_theta = gr.Textbox(label="Direction (theta)")
example_position = gr.Textbox(label="Position")
example_target = gr.Textbox(label="Target Point")
example_components = [example_image, example_speed, example_theta, example_position, example_target]
if SAMPLES_FOR_DISPLAY:
example_dataset = gr.Dataset(
components=example_components,
samples=SAMPLES_FOR_DISPLAY,
label="Select Test Scenario"
)
example_dataset.select(
fn=on_example_select,
inputs=None,
outputs=[api_rgb_image_path, api_measurements_path]
)
else:
gr.Markdown("No valid examples found.")
with gr.Column(scale=3):
with gr.Group():
gr.Markdown("### 📊 Results from API")
api_output_image = gr.Image(label="Dashboard Image (from API)", type="pil", interactive=False, height=600)
api_control_json = gr.JSON(label="Control Commands (from API)")
start_session_button.click(fn=start_new_session, inputs=None, outputs=[session_id_state, status_textbox, main_controls_group])
end_session_button.click(fn=handle_end_session, inputs=[session_id_state], outputs=[status_textbox, session_id_state, main_controls_group])
api_run_button.click(fn=run_single_frame_via_api, inputs=[session_id_state, api_rgb_image_path, api_measurements_path], outputs=[api_output_image, api_control_json])
if __name__ == "__main__":
# قم بإعادة تشغيل الـ Space بعد لصق هذا الكود
demo.queue().launch(debug=True) |