Control Robótico Avanzado con Visión Artificial para Clasificación de Objetos ✨
Este tutorial te guiará a través del fascinante mundo de la robótica y la visión artificial, mostrándote cómo construir un sistema capaz de identificar y clasificar objetos automáticamente. Desde la configuración del hardware hasta la programación del software, cubriremos todos los pasos para que tu robot pueda "ver" y actuar. Preparado para dar vida a un clasificador inteligente, este proyecto es ideal para entusiastas y estudiantes de robótica.
La robótica es un campo en constante evolución, y la integración de la visión artificial ha abierto un sinfín de posibilidades, desde la automatización industrial hasta la interacción humano-robot. En este tutorial, nos sumergiremos en un proyecto práctico y emocionante: la construcción de un sistema robótico de clasificación de objetos utilizando un brazo robótico y una cámara, todo controlado mediante Python y OpenCV. Este sistema será capaz de detectar objetos, identificarlos por color o forma básica, y luego moverlos a ubicaciones predefinidas.
🎯 Objetivos del Tutorial
Al finalizar este tutorial, serás capaz de:
- Entender los principios básicos de la visión artificial aplicada a la robótica.
- Configurar el hardware necesario: brazo robótico, servomotores y cámara.
- Programar la comunicación entre una Raspberry Pi (o similar) y los servomotores.
- Desarrollar algoritmos de procesamiento de imagen con OpenCV para detectar y clasificar objetos.
- Integrar la lógica de visión artificial con el control del brazo robótico para la clasificación.
🛠️ Herramientas y Materiales Necesarios
Para llevar a cabo este proyecto, necesitarás los siguientes componentes. La elección específica de cada uno puede variar, pero aquí te damos una guía.
| Componente | Descripción | Cantidad | Enlace (Ejemplo) |
|---|---|---|---|
| --- | --- | --- | --- |
| Microcontrolador | Raspberry Pi 3/4 o Jetson Nano (con GPIOs) | 1 | Raspberry Pi 4 |
| Brazo Robótico | De 4 Grados de Libertad (DOF) con servomotores (MG996R o similares) | 1 | Brazo robótico 4 DOF |
| --- | --- | --- | --- |
| Servomotores | Acordes al brazo robótico (normalmente vienen incluidos) | 4 | N/A |
| Cámara USB | De buena resolución (mínimo 720p), compatible con el microcontrolador | 1 | Logitech C920 |
| --- | --- | --- | --- |
| Protoboard y Cables Jumper | Para conexiones eléctricas | 1 | N/A |
| Fuente de Alimentación | Para la Raspberry Pi y servomotores (5V, 3A-5A) | 1 | N/A |
| --- | --- | --- | --- |
| Tarjetas SD | Para el sistema operativo del microcontrolador | 1 | N/A |
| Objetos de Prueba | Pequeños objetos de diferentes colores y/o formas simples | Varios | Bloques de colores, fichas |
🚀 Configuración del Entorno de Desarrollo
💻 Preparación de la Raspberry Pi
- Instalar Sistema Operativo: Descarga Raspberry Pi OS (recomendado con escritorio) y fláshealo en tu tarjeta SD usando Raspberry Pi Imager.
- Primer Arranque y Conexión: Inicia tu Raspberry Pi, conéctala a una pantalla, teclado y ratón. Configura la red Wi-Fi.
- Actualizar el Sistema: Abre una terminal y ejecuta:
sudo apt update
sudo apt upgrade
🐍 Instalación de Python y Librerías
Nuestro software se desarrollará en Python. Necesitaremos instalar OpenCV para la visión artificial y RPi.GPIO para el control de los servomotores.
# Instalar pip si no está presente
sudo apt install python3-pip
# Instalar OpenCV para Python
# Esto puede tardar un rato
pip3 install opencv-python numpy
# Instalar la librería para control GPIO de Raspberry Pi
pip3 install RPi.GPIO
# Opcional: Instalar pi-camera para cámaras CSI (si usas una)
pip3 install picamera
🔌 Montaje del Hardware: Brazo Robótico y Cámara
🤖 Montaje del Brazo Robótico
Sigue las instrucciones proporcionadas con tu kit de brazo robótico para ensamblarlo. Asegúrate de que los servomotores estén correctamente instalados y que el movimiento de cada articulación sea fluido.
⚡ Conexión de Servomotores a la Raspberry Pi
Los servomotores se controlan mediante PWM (Pulse Width Modulation). Cada servomotor tiene tres cables: alimentación (rojo), tierra (marrón/negro) y señal (amarillo/naranja).
Aquí tienes un esquema de conexión general:
- Servomotores (+): Conectar al riel positivo de una protoboard, alimentado por la fuente externa (ej. 5V).
- Servomotores (GND): Conectar al riel negativo de una protoboard, que a su vez se conecta a un pin GND de la Raspberry Pi y al GND de la fuente externa.
- Servomotores (Señal): Conectar a pines GPIO específicos de la Raspberry Pi (ej. GPIO17, GPIO18, GPIO22, GPIO27 para 4 DOF).
📸 Conexión de la Cámara USB
Simplemente conecta tu cámara USB a uno de los puertos USB de la Raspberry Pi. Verifica que sea detectada correctamente ejecutando:
lsusb
v4l2-ctl --list-devices
Si la cámara aparece en la lista, ¡está lista para usarse!
📝 Programación del Control del Brazo Robótico
Crearemos un módulo de Python para controlar los servomotores. Utilizaremos la librería RPi.GPIO para generar las señales PWM.
servo_control.py
import RPi.GPIO as GPIO
import time
class ServoControl:
def __init__(self, pins):
GPIO.setmode(GPIO.BCM) # Usar numeración BCM de pines
self.servos = {}
for i, pin in enumerate(pins):
GPIO.setup(pin, GPIO.OUT)
# Frecuencia PWM de 50Hz (20ms ciclo)
self.servos[f'servo_{i+1}'] = GPIO.PWM(pin, 50)
self.servos[f'servo_{i+1}'].start(0) # Inicializar con 0% de ciclo de trabajo
print(f"Servo {i+1} en pin GPIO {pin} inicializado.")
def set_angle(self, servo_name, angle):
# Ángulo de 0 a 180 grados
# Ciclo de trabajo (duty cycle) para un servo común:
# 0 grados ~ 2.5% duty cycle
# 90 grados ~ 7.5% duty cycle
# 180 grados ~ 12.5% duty cycle
if 0 <= angle <= 180:
duty = 2.5 + angle / 180 * 10
self.servos[servo_name].ChangeDutyCycle(duty)
time.sleep(0.3) # Pequeña pausa para que el servo se mueva
print(f"Servo {servo_name} ajustado a {angle} grados (duty: {duty:.2f}%).")
else:
print(f"Ángulo fuera de rango para {servo_name}: {angle}. Debe ser entre 0 y 180.")
def cleanup(self):
for servo in self.servos.values():
servo.stop()
GPIO.cleanup()
print("Servos detenidos y GPIO limpiado.")
# Ejemplo de uso (para probar el control de servos)
if __name__ == "__main__":
# Define los pines GPIO BCM para tus servomotores (ej. para un brazo de 4 DOF)
SERVO_PINS = [17, 18, 27, 22]
arm_control = ServoControl(SERVO_PINS)
try:
print("Moviendo servos a 90 grados...")
arm_control.set_angle('servo_1', 90)
arm_control.set_angle('servo_2', 90)
arm_control.set_angle('servo_3', 90)
arm_control.set_angle('servo_4', 90)
time.sleep(1)
print("Moviendo servo_1 a 0 y servo_2 a 180...")
arm_control.set_angle('servo_1', 0)
arm_control.set_angle('servo_2', 180)
time.sleep(1)
print("Volviendo a 90 grados y deteniendo...")
arm_control.set_angle('servo_1', 90)
arm_control.set_angle('servo_2', 90)
time.sleep(1)
except KeyboardInterrupt:
print("Interrupción del usuario.")
finally:
arm_control.cleanup()
Este código define una clase ServoControl que simplifica la interacción con los servomotores. Puedes probarlo ejecutando python3 servo_control.py y observando cómo se mueven los servomotores de tu brazo robótico.
¿Cómo calcular el Duty Cycle para un servo?
Un servomotor estándar espera un pulso cada 20ms (50Hz). La duración de este pulso determina el ángulo. Por ejemplo: - Pulso de 1ms (5% del ciclo de 20ms) = 0 grados - Pulso de 1.5ms (7.5% del ciclo de 20ms) = 90 grados - Pulso de 2ms (10% del ciclo de 20ms) = 180 gradosLa fórmula duty = 2.5 + angle / 180 * 10 es una aproximación común para servos SG90/MG996R, donde 2.5 es el offset para 0 grados y 10 es el rango del duty cycle (12.5% - 2.5% = 10%) para cubrir 180 grados. Es posible que necesites ajustarlo ligeramente para tu modelo específico de servo.
👁️ Visión Artificial con OpenCV: Detección y Clasificación
Ahora, implementaremos la parte de visión artificial que permitirá al robot "ver" los objetos en su entorno. Nos centraremos en la detección de objetos por color y, de manera sencilla, por su contorno básico.
vision_processor.py
import cv2
import numpy as np
import time
class VisionProcessor:
def __init__(self, camera_index=0):
self.cap = cv2.VideoCapture(camera_index) # 0 para la cámara por defecto
if not self.cap.isOpened():
raise IOError("No se puede abrir la cámara.")
print(f"Cámara {camera_index} abierta correctamente.")
# Rangos HSV para diferentes colores (ejemplos)
# Puedes ajustar estos valores según tu iluminación y objetos
self.color_ranges = {
"rojo": {"lower": np.array([0, 100, 100]), "upper": np.array([10, 255, 255])},
"rojo_alt": {"lower": np.array([170, 100, 100]), "upper": np.array([180, 255, 255])},
"verde": {"lower": np.array([40, 40, 40]), "upper": np.array([80, 255, 255])},
"azul": {"lower": np.array([100, 100, 100]), "upper": np.array([120, 255, 255])}
}
def get_frame(self):
ret, frame = self.cap.read()
if not ret:
print("No se pudo leer el frame de la cámara.")
return None
return frame
def detect_object(self, frame):
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
detected_objects = []
for color_name, color_range in self.color_ranges.items():
lower = color_range["lower"]
upper = color_range["upper"]
mask = cv2.inRange(hsv, lower, upper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
contours, _ = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
area = cv2.contourArea(contour)
if area > 500: # Filtrar por área mínima del objeto
x, y, w, h = cv2.boundingRect(contour)
center_x = x + w // 2
center_y = y + h // 2
# Clasificación simple por relación de aspecto para forma básica
aspect_ratio = float(w)/h
form_type = "cuadrado/rectangulo" if 0.8 < aspect_ratio < 1.2 else "otro"
detected_objects.append({
"color": color_name.replace("_alt", ""), # Normalizar nombre de color
"form": form_type,
"center_x": center_x,
"center_y": center_y,
"bbox": (x, y, w, h)
})
return detected_objects
def draw_detections(self, frame, detections):
for obj in detections:
x, y, w, h = obj["bbox"]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) # Cuadro verde
cv2.putText(frame, f"{obj['color']} {obj['form']}", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
return frame
def release(self):
self.cap.release()
cv2.destroyAllWindows()
print("Cámara liberada y ventanas cerradas.")
# Ejemplo de uso (para probar la detección de objetos)
if __name__ == "__main__":
vision = VisionProcessor(camera_index=0) # Ajusta el índice si tienes varias cámaras
try:
while True:
frame = vision.get_frame()
if frame is None: # Si no se pudo leer el frame, intentar de nuevo
continue
detections = vision.detect_object(frame)
frame_with_detections = vision.draw_detections(frame, detections)
cv2.imshow("Deteccion de Objetos", frame_with_detections)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print(f"Ocurrió un error: {e}")
finally:
vision.release()
Explicación del Código de Visión
__init__: Inicializa la cámara y define los rangos de color en el espacio HSV (Hue, Saturation, Value). HSV es ideal para la detección de color ya que es menos sensible a los cambios de iluminación que RGB.- Hue (Tono): Define el color puro (rojo, verde, azul, etc.).
- Saturation (Saturación): La intensidad o pureza del color.
- Value (Valor/Brillo): La luminosidad del color.
detect_object: Procesa unframede imagen. Convierte la imagen a HSV, aplica una máscara para cada rango de color usandocv2.inRange(), y luego realiza operaciones de erosión y dilatación para limpiar el ruido y unir regiones cercanas. Finalmente, encuentra los contornos y filtra por área para identificar objetos significativos. Una clasificación muy básica poraspect_ratio(relación de aspecto) se usa para inferir formas simples.draw_detections: Dibuja rectángulos delimitadores y etiquetas sobre los objetos detectados en elframe.
Para ajustar los rangos HSV, puedes usar herramientas como la aplicación Color Picker en OpenCV o simplemente experimentar con los valores mientras ejecutas el script de prueba (if __name__ == "__main__":) y observas los resultados. La calibración de color es crucial para un buen rendimiento.
🤝 Integración: Visión y Control del Brazo
Ahora, uniremos la visión artificial con el control del brazo robótico. El flujo será el siguiente: la cámara detectará un objeto, el programa determinará su clasificación y su posición, y luego el brazo robótico se moverá para agarrarlo y clasificarlo en un lugar predefinido.
🗺️ Mapeo de Coordenadas
Uno de los desafíos es traducir las coordenadas de píxeles de la cámara a las coordenadas espaciales del brazo robótico. Para simplificar, asumiremos que el área de trabajo del robot está directamente debajo de la cámara, y que los movimientos del brazo se calibran a través de posiciones fijas predefinidas.
main_robot_classifier.py
import time
from servo_control import ServoControl
from vision_processor import VisionProcessor
import cv2
# --- Configuración de Pines GPIO para Servos ---
SERVO_PINS = [17, 18, 27, 22] # Base, Hombro, Codo, Pinza
# --- Posiciones Predefinidas del Brazo Robótico (Ángulos en grados) ---
# Estas posiciones son de ejemplo y DEBEN ser calibradas para tu brazo
HOME_POSITION = {
'servo_1': 90, # Base
'servo_2': 90, # Hombro
'servo_3': 90, # Codo
'servo_4': 90 # Pinza (cerrada o abierta a la mitad)
}
# Posición inicial para observar la zona de trabajo
OBSERVE_POSITION = {
'servo_1': 90,
'servo_2': 60, # Hombro un poco abajo
'servo_3': 120, # Codo arriba
'servo_4': 90 # Pinza
}
# Posición para tomar un objeto (debe ser ajustada según la zona de detección de la cámara)
PICK_POSITION = {
'servo_1': 90, # Se ajustará según el X del objeto
'servo_2': 40, # Bajar hombro
'servo_3': 140, # Bajar codo
'servo_4': 90 # Pinza abierta
}
# Posiciones de destino para clasificación (ajusta según tus bandejas de clasificación)
CLASSIFY_POSITIONS = {
"rojo": {
'servo_1': 30, # Izquierda
'servo_2': 70,
'servo_3': 100,
'servo_4': 90 # Pinza abierta
},
"verde": {
'servo_1': 150, # Derecha
'servo_2': 70,
'servo_3': 100,
'servo_4': 90
},
"azul": {
'servo_1': 90, # Centro
'servo_2': 70,
'servo_3': 100,
'servo_4': 90
}
}
# --- Funciones de Ayuda ---
def move_to_position(arm_controller, position_dict, open_gripper=False):
for servo_name, angle in position_dict.items():
if servo_name == 'servo_4' and open_gripper: # Controlar pinza al final si es necesario
pass # La pinza se controla explícitamente más tarde
else:
arm_controller.set_angle(servo_name, angle)
time.sleep(1) # Pausa para asegurar que se muevan
def open_gripper(arm_controller):
arm_controller.set_angle('servo_4', 120) # Abre más la pinza
time.sleep(0.5)
def close_gripper(arm_controller):
arm_controller.set_angle('servo_4', 60) # Cierra la pinza
time.sleep(0.5)
# --- Programa Principal ---
if __name__ == "__main__":
arm_controller = ServoControl(SERVO_PINS)
vision_processor = VisionProcessor(camera_index=0) # Asegúrate que sea el índice correcto
try:
print("Inicializando brazo robótico y cámara...")
move_to_position(arm_controller, HOME_POSITION)
open_gripper(arm_controller) # Asegúrate de que la pinza esté abierta al inicio
time.sleep(1)
print("Movimiento a posición de observación.")
move_to_position(arm_controller, OBSERVE_POSITION)
while True:
frame = vision_processor.get_frame()
if frame is None:
time.sleep(0.1)
continue
detections = vision_processor.detect_object(frame)
frame_with_detections = vision_processor.draw_detections(frame, detections)
cv2.imshow("Clasificador de Objetos", frame_with_detections)
if detections: # Si se detecta al menos un objeto
# Tomamos el primer objeto detectado para simplificar
obj_to_classify = detections[0]
print(f"Objeto detectado: {obj_to_classify['color']} {obj_to_classify['form']} en ({obj_to_classify['center_x']}, {obj_to_classify['center_y']})")
# Calcular ángulo de la base (servo_1) basado en la posición X del objeto
# Asumimos que el centro de la imagen (width/2) corresponde a 90 grados de la base
# Y que mover a la izquierda es disminuir ángulo, a la derecha es aumentar
# Estos valores son aproximados y requieren calibración manual
img_center_x = frame.shape[1] // 2
pixel_offset_x = obj_to_classify['center_x'] - img_center_x
# Factor de escalado para traducir píxeles a grados. Ajusta este valor!
# Un valor negativo si el aumento de píxeles X corresponde a disminuir ángulo de servo
# Por ejemplo, 1 grado por cada 10 píxeles de diferencia
angle_offset = pixel_offset_x * 0.1 # Ajusta este factor
target_base_angle = HOME_POSITION['servo_1'] - angle_offset
if not (0 <= target_base_angle <= 180):
print(f"Ángulo de base calculado {target_base_angle:.2f} fuera de rango. Ajustando.")
target_base_angle = max(0, min(180, target_base_angle))
print(f"Moviendo a posición de toma para {obj_to_classify['color']} con base en {target_base_angle:.2f} grados...")
# Mover a la posición de toma con el ángulo de base ajustado
current_pick_position = PICK_POSITION.copy()
current_pick_position['servo_1'] = int(target_base_angle)
move_to_position(arm_controller, current_pick_position, open_gripper=True)
close_gripper(arm_controller)
print("Objeto agarrado!")
time.sleep(1)
# Mover a la posición de clasificación
target_color = obj_to_classify['color']
if target_color in CLASSIFY_POSITIONS:
print(f"Clasificando objeto {target_color}...")
move_to_position(arm_controller, CLASSIFY_POSITIONS[target_color])
open_gripper(arm_controller)
print(f"Objeto {target_color} clasificado.")
time.sleep(1)
else:
print(f"Color {target_color} no tiene posición de clasificación definida. Volviendo a HOME.")
# Volver a la posición de observación para detectar el siguiente objeto
move_to_position(arm_controller, OBSERVE_POSITION)
time.sleep(1)
# Salir con 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except KeyboardInterrupt:
print("Interrupción del usuario.")
except Exception as e:
print(f"Ocurrió un error inesperado: {e}")
finally:
arm_controller.cleanup()
vision_processor.release()
cv2.destroyAllWindows()
print("Programa finalizado y recursos liberados.")
Calibración y Ajustes Cruciales
Las posiciones predefinidas y el factor de escalado de píxeles a grados son los aspectos más críticos para el funcionamiento de este sistema. Deberás ajustarlos empíricamente para tu brazo robótico y entorno de trabajo específicos.
Procedimiento de Calibración Sugerido:
- Calibrar Servos Individualmente: Usa el script
servo_control.pypara encontrar los ángulos mínimos y máximos de cada servo que tu brazo puede alcanzar sin forzarse y que corresponden a movimientos lógicos. - Calibrar Rangos HSV: Utiliza el script
vision_processor.pyy una herramienta de selección de color (o simplemente prueba y error) para afinar los rangos de color que identifican tus objetos de prueba bajo tu iluminación real. - Calibrar Posiciones del Brazo:
- HOME_POSITION y OBSERVE_POSITION: Mueve el brazo manualmente a una posición segura y que permita a la cámara ver bien la zona de trabajo. Anota los ángulos de cada servo y actualiza las constantes.
- PICK_POSITION: Coloca un objeto en el centro de la zona donde la cámara lo detectará. Mueve el brazo para que la pinza pueda agarrar el objeto. Anota los ángulos. Luego, haz lo mismo con la pinza abierta y cerrada.
- CLASSIFY_POSITIONS: Mueve el brazo a cada una de las ubicaciones donde deseas dejar los objetos clasificados (ej. bandejas) y anota los ángulos para cada color.
- Calibrar Mapeo X-Píxel a Ángulo de Base: Coloca un objeto en diferentes posiciones a lo largo del eje X en la imagen de la cámara. Observa el
pixel_offset_xy ajusta elangle_offset = pixel_offset_x * factorpara que el brazo base gire lo suficiente para centrarse sobre el objeto. Estefactores crucial.
📈 Mejoras y Próximos Pasos
Este tutorial proporciona una base sólida para un sistema de clasificación. Aquí hay algunas ideas para llevarlo al siguiente nivel:
- Detección de Múltiples Objetos: Modificar
detect_objectpara procesar y clasificar múltiples objetos en un solo frame, quizás utilizando una cola o priorización. - Clasificación de Formas Avanzada: Implementar algoritmos de reconocimiento de formas más sofisticados (ej.
cv2.approxPolyDPpara polígonos, o clasificadores basados en momentos de Hu) para diferenciar cuadrados, círculos, triángulos, etc. - Estimación de Profundidad: Integrar una cámara de profundidad (ej. Intel RealSense, Kinect) para obtener coordenadas 3D precisas de los objetos, lo que simplificaría enormemente el cálculo de la posición de agarre.
- Interfaz de Usuario: Desarrollar una interfaz gráfica (GUI) con
PyQtoTkinterpara visualizar el stream de la cámara, controlar el brazo manualmente y ajustar parámetros en tiempo real. - Machine Learning: Entrenar un modelo de aprendizaje automático (ej. TensorFlow Lite en la Raspberry Pi) para una clasificación de objetos más robusta y generalizable, más allá del color y formas simples.
- Control de Movimiento Suave (Cinemática Inversa): Para movimientos más fluidos y precisos, se puede implementar cinemática inversa, que calcula los ángulos de los servos a partir de una posición deseada en coordenadas cartesianas (X, Y, Z).
❓ Preguntas Frecuentes (FAQ)
¿Por qué usar HSV en lugar de RGB para la detección de color?
HSV (Hue, Saturation, Value) es superior a RGB para la detección de color porque el componente Hue (tono) representa el color en sí mismo y es menos afectado por los cambios en la iluminación. En RGB, un cambio en la iluminación puede alterar los tres componentes (R, G, B) de un color, haciendo que la detección sea menos robusta. HSV permite aislar y segmentar colores de manera más fiable.Mi brazo robótico no se mueve correctamente, ¿qué puedo revisar?
Primero, verifica las conexiones de los cables de los servomotores (alimentación, tierra, señal). Asegúrate de que la fuente de alimentación externa sea suficiente para los servomotores. Revisa que los pines GPIO en tu código (`SERVO_PINS`) coincidan con los pines a los que has conectado físicamente los servos en la Raspberry Pi. Finalmente, asegúrate de que los rangos de ángulo en `set_angle` son válidos para tus servomotores y que los valores de `duty cycle` se correspondan. Es común que los servos tengan límites físicos diferentes a 0-180 grados, ¡ajusta!¿Cómo puedo mejorar la precisión de la detección de objetos?
Varias estrategias pueden ayudar: * **Iluminación Controlada:** Usa una iluminación uniforme y sin sombras para evitar variaciones en el color de los objetos. * **Calibración de Cámara:** Realiza una calibración de cámara para corregir la distorsión de la lente. * **Filtros Adicionales en OpenCV:** Experimenta con filtros como el filtro Gaussiano para suavizar imágenes y Canny Edge Detection para mejorar la detección de contornos. * **Fondos Simples:** Utiliza un fondo de color uniforme y contrastante con los objetos. * **Rangos HSV Específicos:** Dedica tiempo a ajustar los rangos HSV para cada color bajo las condiciones de luz reales de tu entorno.¡Felicidades! Has completado un tutorial que te ha guiado desde el montaje físico hasta la programación de un sistema robótico con visión artificial. Este proyecto es un excelente punto de partida para explorar aplicaciones más complejas en el campo de la robótica y la automatización.
Tutoriales relacionados
- Robots Biomiméticos: Diseñando y Construyendo un Robot Biónico Inspirado en la Naturalezaintermediate20 min
- Diseño y Construcción de un Robot Móvil Diferencial Controlado por ESP32intermediate20 min
- Robótica Colaborativa: Integrando COBOTS en Entornos Industriales 🤖intermediate18 min
- Navegación Autónoma para Rovers: Sensores y Algoritmos para Evitar Obstáculosintermediate18 min
- Robots Escaladores: Diseño y Construcción de un Robot Móvil que Trepa Superficies Verticalesintermediate18 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!