Spaces:
Runtime error
Runtime error
File size: 7,336 Bytes
5ed0597 |
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 |
# backend/robot_detector.py
import serial.tools.list_ports
import gradio as gr
import json
import os
# Define the path to save/load configurations
CONFIG_FILE = "config/default_config.json"
def list_serial_ports():
"""
Lista todos los puertos seriales disponibles en el sistema.
"""
ports = serial.tools.list_ports.comports()
port_list = []
if not ports:
return ["No se encontraron puertos seriales disponibles."]
for port in ports:
port_info = f"{port.device} - {port.description}"
if port.hwid and "VID:PID" in port.hwid:
port_info += f" ({port.hwid})"
port_list.append(port_info)
return port_list
def save_config(follower_port: str, follower_id: str, leader_port: str, leader_id: str):
"""
Guarda la configuraci贸n del robot y teleoperador en un archivo JSON.
"""
config = {
"robot_follower": {
"port": follower_port.split(' ')[0] if follower_port else "", # Extract only device path
"id": follower_id
},
"teleop_leader": {
"port": leader_port.split(' ')[0] if leader_port else "", # Extract only device path
"id": leader_id
}
}
try:
with open(CONFIG_FILE, 'w') as f:
json.dump(config, f, indent=4)
return f"Configuraci贸n guardada en {CONFIG_FILE} correctamente."
except Exception as e:
return f"Error al guardar la configuraci贸n: {e}"
def load_config():
"""
Carga la configuraci贸n del robot y teleoperador desde un archivo JSON.
"""
if os.path.exists(CONFIG_FILE):
try:
with open(CONFIG_FILE, 'r') as f:
config = json.load(f)
return (
config.get("robot_follower", {}).get("port", ""),
config.get("robot_follower", {}).get("id", ""),
config.get("teleop_leader", {}).get("port", ""),
config.get("teleop_leader", {}).get("id", "")
)
except Exception as e:
gr.Warning(f"Error al cargar la configuraci贸n existente: {e}. Se usar谩n valores por defecto.")
return "", "", "", ""
return "", "", "", ""
# --- Gradio Interface ---
# Load initial config values for Gradio components
initial_follower_port, initial_follower_id, initial_leader_port, initial_leader_id = load_config()
with gr.Blocks(title="Detector y Configuraci贸n de Robots LeRobot") as demo:
gr.Markdown("# <center>Detector y Configuraci贸n de Robots LeRobot</center>")
gr.Markdown(
"Esta herramienta te ayuda a identificar los puertos seriales de tus robots "
"SO101 (follower y leader) y asignarles un ID consistente."
)
with gr.Tab("1. Detectar Puertos Seriales"):
gr.Markdown("## Puertos Seriales Detectados")
gr.Markdown(
"Conecta tus robots SO101 (follower y leader) a tu computadora y haz clic en 'Refrescar Puertos'. "
"Observa la lista y compara con los nombres de tus dispositivos si es posible para identificarlos."
)
refresh_btn = gr.Button("馃攧 Refrescar Puertos")
port_list_output = gr.Textbox(
label="Puertos Seriales Disponibles",
interactive=False,
lines=10,
value="\n".join(list_serial_ports()), # Initial list on startup
show_copy_button=True
)
refresh_btn.click(
fn=lambda: "\n".join(list_serial_ports()),
inputs=None,
outputs=port_list_output
)
with gr.Tab("2. Asignar Puertos e IDs"):
gr.Markdown("## Asignaci贸n de Robots y Teleoperadores")
gr.Markdown(
"Selecciona el puerto correcto para cada dispositivo y asigna un ID 煤nico. "
"**隆Es crucial usar el mismo ID en todos los scripts (grabaci贸n, entrenamiento, evaluaci贸n)!**"
)
gr.Markdown("### Robot Follower (Brazo del Robot SO101)")
follower_port_dropdown = gr.Dropdown(
label="Puerto Serial del Robot Follower",
choices=[], # Will be populated dynamically
value=initial_follower_port,
info="Selecciona el puerto donde est谩 conectado el brazo del robot (SO101)."
)
follower_id_input = gr.Textbox(
label="ID del Robot Follower",
value=initial_follower_id if initial_follower_id else "my_robot_follower_arm",
placeholder="ej. my_robot_follower_arm",
info="Un identificador 煤nico para este robot. Usado para archivos de calibraci贸n."
)
gr.Markdown("### Teleoperador Leader (Brazo de Control SO101)")
leader_port_dropdown = gr.Dropdown(
label="Puerto Serial del Teleoperador Leader",
choices=[], # Will be populated dynamically
value=initial_leader_port,
info="Selecciona el puerto donde est谩 conectado el dispositivo de control (SO101)."
)
leader_id_input = gr.Textbox(
label="ID del Teleoperador Leader",
value=initial_leader_id if initial_leader_id else "my_teleop_leader_arm",
placeholder="ej. my_teleop_leader_arm",
info="Un identificador 煤nico para el dispositivo de teleoperaci贸n."
)
save_btn = gr.Button("馃捑 Guardar Configuraci贸n", variant="primary")
save_status_output = gr.Textbox(
label="Estado de Guardado",
interactive=False,
visible=False
)
save_btn.click(
fn=save_config,
inputs=[follower_port_dropdown, follower_id_input, leader_port_dropdown, leader_id_input],
outputs=save_status_output
)
# Function to update dropdown choices based on current ports
def update_port_choices():
ports = list_serial_ports()
# Extract just the device path for dropdown value (e.g., /dev/tty.usbmodemXXX)
device_paths = [p.split(' ')[0] for p in ports if "No se encontraron" not in p]
return gr.update(choices=device_paths), gr.update(choices=device_paths)
# Update dropdowns on initial load and when refresh button is clicked
demo.load(
fn=update_port_choices,
inputs=None,
outputs=[follower_port_dropdown, leader_port_dropdown]
)
refresh_btn.click( # Re-bind refresh button to update dropdowns too
fn=update_port_choices,
inputs=None,
outputs=[follower_port_dropdown, leader_port_dropdown]
)
gr.Markdown("---")
gr.Markdown(f"**La configuraci贸n guardada se almacenar谩 en:** `{os.path.abspath(CONFIG_FILE)}`")
gr.Markdown(
"**Instrucciones para otros scripts:**\n"
"1. Abre `robot_config.json`.\n"
"2. Copia los valores de `port` y `id` a tus scripts de `record_controller.py` y `train_robot.py` (para evaluaci贸n)."
)
gr.Markdown("Hecho con 鉂わ笍 para RobotCleanPupusas503")
if __name__ == "__main__":
try:
import serial # Test if pyserial is installed
except ImportError:
print("Error: La librer铆a 'pyserial' no est谩 instalada.")
print("Por favor, instala 'pyserial' ejecutando: pip install pyserial")
exit(1)
demo.launch(share=False) |