TURTLEBOT4 - DESCRIPCIÓN GENERAL
6:09
TURTLEBOT4 - TU PRIMER NODO PYTHON
17:06
TURTLEBOT 4 - INTRODUCCIÓN
8:54
2 ай бұрын
Jetson Nano - GPIO (PINES)
6:21
3 ай бұрын
Пікірлер
@pablogomez6384
@pablogomez6384 25 күн бұрын
hola amigo gracias por la información, pero no se si sabes como hacer lo mismo pero usando el serial de la jetson nano que esta en los pines 8 y 10 ya que los datos a un esp32 que esta conectado por esa parte
@IN3DMEX2.0
@IN3DMEX2.0 24 күн бұрын
Hola que tal, aún no he probado eso. Por la inestabilidad de la señal que tuve años atrás, lo intentaré nuevamente esta semana y si logro un buen resultado publicaré un vídeo al respecto.
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#MODELO import torch import torch.nn as nn # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") class RNN(nn.Module): def __init__(self, input_size, hidden_size, output_size): # Llama al constructor de la clase padre super(RNN, self).__init__() # Guarda el tamaño de la capa oculta self.hidden_size = hidden_size # Crea la capa RNN self.rnn = nn.RNN(input_size, hidden_size) # Crea la capa densa self.fc = nn.Linear(hidden_size, output_size) def forward(self, input, hidden): # Procesa la entrada por la RNN output, hidden = self.rnn(input, hidden) # Procesa la salida de la RNN por la capa densa output = self.fc(output) # Devuelve la salida y el estado oculto actualizado return output, hidden def init_hidden(self, batch_size): # Inicializa el estado oculto con ceros return torch.zeros(1, self.hidden_size).to(device)
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#ENTRENAMIENTO import torch import torch.nn as nn from modelo import RNN import torch.optim as optim from torch.utils.data import DataLoader import pandas as pd import nltk import numpy as np import sys import pickle # Importa la librería pickle # Descarga el paquete punkt si no está instalado nltk.download('punkt') nltk.download('stopwords') # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Define los parámetros de la red input_size = 15 # Tamaño de la entrada (por ejemplo, 15 palabras) hidden_size = 120 # Tamaño de la capa oculta output_size = 3 # Tamaño de la salida (por ejemplo, 3 clases) # Crea una instancia de la RNN modelo = RNN(input_size, hidden_size, output_size) # Define el optimizador y la función de pérdida optimizer = optim.Adam(modelo.parameters(), lr=0.001) criterion = nn.NLLLoss() # Define el dataset dataset = pd.read_csv('dataset.csv') # Prepara el dataset frases = dataset['Frase'].tolist() etiquetas = dataset['Etiqueta'].tolist() # Tokeniza las frases tokens = [nltk.word_tokenize(frase) for frase in frases] # Elimina las stop words stop_words = nltk.corpus.stopwords.words('spanish') tokens = [[token for token in frase if token not in stop_words] for frase in tokens] # Stemming stemmer = nltk.stem.PorterStemmer() tokens = [[stemmer.stem(token) for token in frase] for frase in tokens] # Crea el vocabulario y el diccionario de palabras a índices vocabulario = set([token for frase in tokens for token in frase]) vocabulario_a_indice = {token: indice for indice, token in enumerate(vocabulario)} # Agrega las etiquetas al vocabulario etiquetas_unicas = set(etiquetas) for etiqueta in etiquetas_unicas: if etiqueta not in vocabulario_a_indice: vocabulario_a_indice[etiqueta] = len(vocabulario_a_indice) # Crea un diccionario de etiquetas a índices etiquetas_a_indice = {etiqueta: indice for indice, etiqueta in enumerate(etiquetas_unicas)} # Guarda el diccionario vocabulario_a_indice en un archivo with open('vocabulario_a_indice.pkl', 'wb') as f: # Abre el archivo en modo escritura binaria pickle.dump(vocabulario_a_indice, f) # Guarda el diccionario en el archivo datos = [] for i, tokens_frase in enumerate(tokens): # Crea un tensor de tamaño input_size (15 en este caso) vector = torch.zeros(input_size, dtype=torch.float32) # Rellena las frases más cortas con ceros for j, token in enumerate(tokens_frase): if j < input_size: vector[j] = vocabulario_a_indice[token] # Asegúrate de que la etiqueta esté dentro del rango válido etiqueta = etiquetas_a_indice[etiquetas[i]] datos.append((vector, etiqueta)) # Convierte a torch.float32 # Verifica que la lista datos no esté vacía if datos: # Crea un DataLoader dataloader = DataLoader(datos, batch_size=32, shuffle=True) else: # Si la lista datos está vacía, termina la ejecución print("La lista de datos está vacía. Terminando la ejecución.") sys.exit() # Mueve el modelo al dispositivo modelo.to(device) # Entrena la red num_epochs = 20 for epoch in range(num_epochs): for i, (inputs, labels) in enumerate(dataloader): # Inicializa el estado oculto hidden = torch.zeros(1, hidden_size).to(device) # Inicializa con forma 2D # Mueve los datos al dispositivo inputs = inputs.to(device) labels = labels.long().to(device) # Convierte las etiquetas a LongTensor # Calcula la salida y la pérdida outputs, hidden = modelo(inputs, hidden) loss = criterion(outputs, labels) # Actualiza los pesos optimizer.zero_grad() loss.backward() optimizer.step() # Imprime el progreso print(f'Epoch {epoch+1}/{num_epochs}, Batch {i+1}/{len(dataloader)}, Loss: {loss.item():.4f}') # Guarda los pesos del modelo entrenado torch.save(modelo.state_dict(), 'modelo_pesos.pth')
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#DATASETUP import csv def crear_dataset(): """Crea un dataset de análisis de sentimientos.""" dataset = [] while True: # Solicita al usuario que introduzca una frase frase = input("Introduce una frase (o escribe 'fin' para terminar): ") # Si el usuario escribe 'fin', termina el bucle if frase == 'fin': break # Solicita al usuario que asigne una etiqueta de sentimiento while True: etiqueta = input("Asigna una etiqueta (positivo, negativo, neutral): ") if etiqueta.lower() in ('positivo', 'negativo', 'neutral'): break else: print("Etiqueta inválida. Por favor, introduce 'positivo', 'negativo' o 'neutral'.") # Agrega la frase y la etiqueta al dataset dataset.append([frase, etiqueta]) # Guarda el dataset en un archivo CSV with open('dataset.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['Frase', 'Etiqueta']) writer.writerows(dataset) print("Dataset creado correctamente en 'dataset.csv'") # Llama a la función para crear el dataset crear_dataset()
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#INFERENCIA import torch import torch.nn as nn from modelo import RNN import nltk import pickle # Importa la librería pickle # Descarga el paquete punkt si no está instalado nltk.download('punkt') nltk.download('stopwords') nltk.download('punkt_tab') # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Define los parámetros de la red input_size = 15 # Tamaño de la entrada (por ejemplo, 10 palabras) hidden_size = 120 # Tamaño de la capa oculta output_size = 3 # Tamaño de la salida (por ejemplo, 3 clases) # Crea una instancia de la RNN modelo = RNN(input_size, hidden_size, output_size) # Carga los pesos del modelo entrenado modelo.load_state_dict(torch.load('modelo_pesos.pth')) # Elimina las stop words stop_words = nltk.corpus.stopwords.words('spanish') # Stemming stemmer = nltk.stem.PorterStemmer() # Mueve el modelo al dispositivo modelo.to(device)
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#CAPTURA import cv2 import os # Define la ruta de la carpeta donde se guardarán las fotos ESTE SE IRÁ MODIFICANDO ruta_carpeta = "data/test_set/YO" # Crea la carpeta si no existe if not os.path.exists(ruta_carpeta): os.makedirs(ruta_carpeta) # Inicializa la cámara cap = cv2.VideoCapture(0) # Define el tiempo de espera entre fotos (en milisegundos) tiempo_espera = 1000 # 1 segundos # Bucle principal while(True): # Lee un frame de la cámara ret, frame = cap.read() # Muestra el frame en la ventana cv2.imshow('Presiona "p" para tomar fotos', frame) # Espera por una tecla presionada key = cv2.waitKey(1) & 0xFF # Si se presiona la tecla "p" if key == ord('p'): # Toma 200 fotos for i in range(200): # Lee un frame de la cámara ret, frame = cap.read() # Guarda la foto con el nombre "i.jpg" nombre_archivo = os.path.join(ruta_carpeta, f"{i}.jpg") cv2.imwrite(nombre_archivo, frame) # Imprime un mensaje en la terminal print(f"Foto {i+1} tomada") # Espera el tiempo definido cv2.waitKey(tiempo_espera) # Imprime un mensaje de finalización print("Se tomaron 200 fotos") # Rompe el bucle break # Libera los recursos cap.release() cv2.destroyAllWindows()
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#ENTRENAMIENTO import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms from modelo import CNN # Importa la clase CNN # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Define las transformaciones para las imágenes data_transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # Carga el dataset de entrenamiento train_dataset = datasets.ImageFolder(root='data/training_set', transform=data_transform) # Crea un DataLoader para el dataset de entrenamiento train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) # Crea una instancia de la CNN y mueve la red al dispositivo modelo = CNN().to(device) # Define el optimizador y la función de pérdida optimizer = optim.Adam(modelo.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() # Entrena la red num_epochs = 10 for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): images = images.to(device) labels = labels.to(device) outputs = modelo(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() if i % 100 == 0: print(f'Epoch {epoch+1}/{num_epochs}, Batch {i+1}/{len(train_loader)}, Loss: {loss.item():.4f}') # Guarda los pesos del modelo entrenado torch.save(modelo.state_dict(), 'modelo_pesos.pth')
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#MODELO import torch import torch.nn as nn class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1) self.relu1 = nn.ReLU() self.maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1) self.relu2 = nn.ReLU() self.maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.flatten = nn.Flatten() self.fc1 = nn.Linear(32 * 56 * 56, 128) self.relu3 = nn.ReLU() self.fc2 = nn.Linear(128, 2) def forward(self, x): x = self.conv1(x) x = self.relu1(x) x = self.maxpool1(x) x = self.conv2(x) x = self.relu2(x) x = self.maxpool2(x) x = self.flatten(x) x = self.fc1(x) x = self.relu3(x) x = self.fc2(x) return x # Crea una instancia de la CNN modelo = CNN()
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#INFERENCIA import torch from torchvision import datasets, transforms from modelo import CNN # Importa la clase CNN import cv2 import os from PIL import Image import RPi.GPIO as GPIO import time LED = 7 GPIO.setmode(GPIO.BOARD) GPIO.setup(LED, GPIO.OUT) # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Define las transformaciones para las imágenes data_transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # Crea una instancia de la CNN y mueve la red al dispositivo modelo = CNN().to(device) # Carga los pesos del modelo entrenado modelo.load_state_dict(torch.load('modelo_pesos.pth')) # Pon el modelo en modo de evaluación modelo.eval() # Inicializa la cámara cap = cv2.VideoCapture(0) # Define los nombres de las clases class_names = ['NADIE', 'YO'] # Bucle principal while(True): # Lee un frame de la cámara ret, frame = cap.read() # Convierte el frame a formato RGB frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Crea una imagen PIL a partir del frame image = Image.fromarray(frame) # Aplica las transformaciones a la imagen image = data_transform(image) # Convierte la imagen a un tensor y mueve al dispositivo image = image.unsqueeze(0).to(device) # Realiza la predicción output = modelo(image) # Obtiene la clase predicha _, predicted_class = torch.max(output.data, 1) # Obtiene el nombre de la clase predicted_class_name = class_names[predicted_class.item()] # Enciende el LED si se detecta "YO" if predicted_class_name == "YO": GPIO.output(LED, True) else: GPIO.output(LED, False) # Imprime la clase predicha print(f'Predicted class: {predicted_class_name}') # Muestra el frame con la predicción cv2.imshow('Camera Feed', frame) # Espera por una tecla presionada if cv2.waitKey(1) & 0xFF == ord('q'): break # Libera los recursos cap.release() cv2.destroyAllWindows() #IMPORTANTE LIMPIAR PINES GPIO.cleanup(LED)
@sgbashec2515
@sgbashec2515 Ай бұрын
Hola, si quiero usar 2 pca9685 los puedo conectar al mismo pin scl de la jetson?
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
Hola! Cada driver pca9685 necesita sus propios pines. Conecta el primer módulo PCA9685 en: SCL en pin 5, SDA en pin 3. Conecta el segundo módulo PCA9685 en: SCL en pin 28, SDA en pin 27.
@sgbashec2515
@sgbashec2515 Ай бұрын
@@IN3DMEX2.0 Vale muchas gracias por la info
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#MODELO import torch import torch.nn as nn class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1) self.relu1 = nn.ReLU() self.maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1) self.relu2 = nn.ReLU() self.maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.flatten = nn.Flatten() self.fc1 = nn.Linear(32 * 56 * 56, 128) self.relu3 = nn.ReLU() self.fc2 = nn.Linear(128, 2) def forward(self, x): x = self.conv1(x) x = self.relu1(x) x = self.maxpool1(x) x = self.conv2(x) x = self.relu2(x) x = self.maxpool2(x) x = self.flatten(x) x = self.fc1(x) x = self.relu3(x) x = self.fc2(x) return x # Crea una instancia de la CNN modelo = CNN()
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#ENTRENAMIENTO import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms from modelo import CNN # Importa la clase CNN # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Define las transformaciones para las imágenes data_transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # Carga el dataset de entrenamiento train_dataset = datasets.ImageFolder(root='data/training_set', transform=data_transform) # Crea un DataLoader para el dataset de entrenamiento train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) # Crea una instancia de la CNN y mueve la red al dispositivo modelo = CNN().to(device) # Define el optimizador y la función de pérdida optimizer = optim.Adam(modelo.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() # Entrena la red num_epochs = 10 for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): images = images.to(device) labels = labels.to(device) outputs = modelo(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() if i % 100 == 0: print(f'Epoch {epoch+1}/{num_epochs}, Batch {i+1}/{len(train_loader)}, Loss: {loss.item():.4f}') # Guarda los pesos del modelo entrenado torch.save(modelo.state_dict(), 'modelo_pesos.pth')
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
#INFERENCIA import torch from torchvision import datasets, transforms from modelo import CNN # Importa la clase CNN import os from PIL import Image # Define el dispositivo (CPU o GPU) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Define las transformaciones para las imágenes data_transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # Crea una instancia de la CNN y mueve la red al dispositivo modelo = CNN().to(device) # Carga los pesos del modelo entrenado modelo.load_state_dict(torch.load('modelo_pesos.pth')) # Pon el modelo en modo de evaluación modelo.eval() # Realiza predicciones sobre nuevas imágenes with torch.no_grad(): image_path = os.path.abspath('data/test_set/cats/cat.4001.jpg') image = Image.open(image_path) # Aplica las transformaciones a la imagen image = data_transform(image) # Convierte la imagen a un tensor y mueve al dispositivo image = image.unsqueeze(0).to(device) # Realiza la predicción output = modelo(image) # Obtiene la clase predicha _, predicted_class = torch.max(output.data, 1) # Define los nombres de las clases class_names = ['gato', 'perro'] # Obtiene el nombre de la clase predicted_class_name = class_names[predicted_class.item()] # Imprime la clase predicha print(f'Predicted class: {predicted_class_name}')
@IN3DMEX2.0
@IN3DMEX2.0 Ай бұрын
import rclpy from rclpy.node import Node from geometry_msgs.msg import Twist import time class ControlNode(Node): def __init__(self): super().__init__('control_node') self.publisher_ = self.create_publisher(Twist, '/cmd_vel', 10) self.timer = self.create_timer(0.1, self.move_robot) # Parámetros del robot self.speed = 0.2 # Velocidad en m/s self.start_time = time.time() # Tiempo de inicio del movimiento def move_robot(self): msg = Twist() # Calcular el tiempo transcurrido elapsed_time = time.time() - self.start_time if elapsed_time < 2: print("Avanzando...") msg.linear.x = self.speed msg.angular.z = 0.0 else: # Detener suavemente el robot if self.speed > 0.0004: self.speed *= 0.95 # Reducir la velocidad gradualmente msg.linear.x = self.speed msg.angular.z = 0.0 else: msg.linear.x = 0.0 msg.angular.z = 0.0 self.get_logger().info('Robot detenido') rclpy.shutdown() self.publisher_.publish(msg) def main(args=None): rclpy.init(args=args) control_node = ControlNode() rclpy.spin(control_node) rclpy.shutdown() if __name__ == '__main__': main()
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
$ ssh ubuntu@ip_raspberry $ source /opt/ros/humble/setup.bash $ mkdir Turtlebot4 $ cd Turtlebot4 $ mkdir src $ cd src $ ros2 pkg create --build-type ament_python --node-name turtlebot4_first_python_node turtlebot4_python_tutorials $ nano package.xml En package.xml, agregar debajo de 'license' <buildtool_depend>ament_cmake_python</buildtool_depend> <depend>rclpy</depend> <depend>irobot_create_msgs</depend> $ cd turtlebot4_python_tutorials $ ls $ cd turtlebot4_python_tutorials $ nano turtlebot4_first_python_node.py
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
from irobot_create_msgs.msg import InterfaceButtons, LightringLeds import rclpy from rclpy.node import Node from rclpy.qos import qos_profile_sensor_data class TurtleBot4FirstNode(Node): lights_on_ = False def __init__(self): super().__init__('turtlebot4_first_python_node') # Subscribe to the /interface_buttons topic self.interface_buttons_subscriber = self.create_subscription( InterfaceButtons, '/interface_buttons', self.interface_buttons_callback, qos_profile_sensor_data ) # Interface buttons subscription callback def interface_buttons_callback(self, create3_buttons_msg: InterfaceButtons): # Button 1 is pressed if create3_buttons_msg.button_1.is_pressed: self.get_logger().info('Button 1 Pressed!') def main(args=None): rclpy.init(args=args) node = TurtleBot4FirstNode() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
$ cd .. $ colcon build $ source install/local_setup.bash ros2 run turtlebot4_python_tutorials turtlebot4_first_python_node ----------------------------------------------------------- ¡¡sólo si hay problema en correr el nodo cd ~/Turtlebot4/src git clone github.com/iRobotEducation/irobot_create_msgs.git ----------------------------------------------------------- $ cd src $ cd turtlebot4_python_tutorials $ cd turtlebot4_python_tutorials $ nano turtlebot4_first_python_node.py
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
from irobot_create_msgs.msg import InterfaceButtons, LightringLeds import rclpy from rclpy.node import Node from rclpy.qos import qos_profile_sensor_data class TurtleBot4FirstNode(Node): lights_on_ = False def __init__(self): super().__init__('turtlebot4_first_python_node') # Subscribe to the /interface_buttons topic self.interface_buttons_subscriber = self.create_subscription( InterfaceButtons, '/interface_buttons', self.interface_buttons_callback, qos_profile_sensor_data) # Create a publisher for the /cmd_lightring topic self.lightring_publisher = self.create_publisher( LightringLeds, '/cmd_lightring', qos_profile_sensor_data) # Interface buttons subscription callback def interface_buttons_callback(self, create3_buttons_msg: InterfaceButtons): # Button 1 is pressed if create3_buttons_msg.button_1.is_pressed: self.get_logger().info('Button 1 Pressed!') self.button_1_function() # Perform a function when Button 1 is pressed def button_1_function(self): # Create a ROS 2 message lightring_msg = LightringLeds() # Stamp the message with the current time lightring_msg.header.stamp = self.get_clock().now().to_msg() # Lights are currently off if not self.lights_on_: # Override system lights lightring_msg.override_system = True # LED 0 lightring_msg.leds[0].red = 255 lightring_msg.leds[0].blue = 0 lightring_msg.leds[0].green = 0 # LED 1 lightring_msg.leds[1].red = 0 lightring_msg.leds[1].blue = 255 lightring_msg.leds[1].green = 0 # LED 2 lightring_msg.leds[2].red = 0 lightring_msg.leds[2].blue = 0 lightring_msg.leds[2].green = 255 # LED 3 lightring_msg.leds[3].red = 255 lightring_msg.leds[3].blue = 255 lightring_msg.leds[3].green = 0 # LED 4 lightring_msg.leds[4].red = 255 lightring_msg.leds[4].blue = 0 lightring_msg.leds[4].green = 255 # LED 5 lightring_msg.leds[5].red = 0 lightring_msg.leds[5].blue = 255 lightring_msg.leds[5].green = 255 # Lights are currently on else: # Disable system override. The system will take back control of the lightring. lightring_msg.override_system = False # Publish the message self.lightring_publisher.publish(lightring_msg) # Toggle the lights on status self.lights_on_ = not self.lights_on_ def main(args=None): rclpy.init(args=args) node = TurtleBot4FirstNode() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ---------------------------------------------------------------------------------------------------------------- $ cd .. $ colcon build $ source install/local_setup.bash
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
#include <micro_ros_arduino.h> #include <ESP32Servo.h> #include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #include <rclc/rclc.h> #include <rclc/executor.h> #include <std_msgs/msg/int8.h> #include <std_msgs/msg/int32.h> #include <geometry_msgs/msg/twist.h> Servo myservo; // create servo object to control a servo const int servoPin = 12; #define BATTERY_PIN 36 rcl_subscription_t LEDs_subscriber; std_msgs__msg__Int8 LEDs_msg; rcl_subscription_t servo_subscriber; std_msgs__msg__Int8 servo_msg; rcl_publisher_t battery_publisher; std_msgs__msg__Int8 battery_msg; rcl_publisher_t left_encoder_publisher; rcl_publisher_t right_encoder_publisher; std_msgs__msg__Int32 left_encoder_msg; std_msgs__msg__Int32 right_encoder_msg; rcl_subscription_t twist_subscriber; geometry_msgs__msg__Twist twist_msg; rclc_executor_t executor; rclc_support_t support; rcl_allocator_t allocator; rcl_node_t node; rcl_timer_t timer; #define LEFT_LED_PIN 2 #define RIGHT_LED_PIN 4 // Encoder Pins #define LeftEncoder_C1 22 #define LeftEncoder_C2 23 #define RightEncoder_C1 19 #define RightEncoder_C2 18 // Pin Definitions #define IN1_PIN 33 //left forward #define IN2_PIN 25 //left backward #define IN3_PIN 26 //right forward #define IN4_PIN 27 //right backward // Motor control variables int motorSpeedLeft = 0; int motorSpeedRight = 0; // Encoder variables int LeftEncoderCount = 0; int RightEncoderCount = 0; void LeftEncoderCallback(); void RightEncoderCallback(); #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}} #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}} // Function prototypes void setMotorSpeed(int speedLeft, int speedRight); int8_t get_battery_percentage(); int map_to_percentage(int raw_value); void error_loop(){ while(1){ delay(100); } } int limitToMaxValue(int value, int maxLimit) { if (value > maxLimit) { return maxLimit; } else { return value; } } void timer_callback(rcl_timer_t * timer, int64_t last_call_time) { RCLC_UNUSED(last_call_time); if (timer != NULL) { RCSOFTCHECK(rcl_publish(&left_encoder_publisher, &left_encoder_msg, NULL)); RCSOFTCHECK(rcl_publish(&right_encoder_publisher, &right_encoder_msg, NULL)); right_encoder_msg.data = RightEncoderCount; left_encoder_msg.data = -LeftEncoderCount; int8_t battery_percentage = get_battery_percentage(); battery_msg.data = battery_percentage; RCSOFTCHECK(rcl_publish(&battery_publisher, &battery_msg, NULL)); } } int8_t get_battery_percentage() { // Read the voltage from the BATTERY_PIN int raw_value = analogRead(BATTERY_PIN); // Convert the raw value to battery percentage (0 to 100) int battery_percentage = map_to_percentage(raw_value); return static_cast<int8_t>(battery_percentage); } int map_to_percentage(int raw_value) { // Assuming the raw_value represents the battery voltage in the range of 0 to 4095 // Adjust the following values based on your battery voltage range and voltage divider setup (if any). int min_voltage = 2400; // Minimum voltage reading (corresponding to 0% battery) int max_voltage = 3720; // Maximum voltage reading (corresponding to 100% battery) // Map the raw value to the battery percentage int battery_percentage = map(raw_value, min_voltage, max_voltage, 0, 100); return battery_percentage; } void LEDs_subscription_callback(const void * msgin) { const std_msgs__msg__Int8 * msg = (const std_msgs__msg__Int8 *)msgin; int8_t value = msg->data; switch (value) { case 0: digitalWrite(LEFT_LED_PIN, LOW); digitalWrite(RIGHT_LED_PIN, LOW); break; case 1: digitalWrite(LEFT_LED_PIN, HIGH); digitalWrite(RIGHT_LED_PIN, LOW); break; case 2: digitalWrite(LEFT_LED_PIN, LOW); digitalWrite(RIGHT_LED_PIN, HIGH); break; case 3: digitalWrite(LEFT_LED_PIN, HIGH); digitalWrite(RIGHT_LED_PIN, HIGH); break; default: break; } //digitalWrite(LED_PIN, (msg->data == 0) ? LOW : HIGH); } void servo_callback(const void* msgin) { const std_msgs__msg__Int8* msg = (const std_msgs__msg__Int8*)msgin; int8_t angle = msg->data; int servo_position; servo_position = limitToMaxValue(angle, 40); myservo.write(servo_position); } // Twist message callback void cmd_vel_callback(const void *msgin) { const geometry_msgs__msg__Twist *msg = (const geometry_msgs__msg__Twist *)msgin; // Calculate motor speeds based on twist message float linear = msg->linear.x; float angular = msg->angular.z; // Calculate individual motor speeds motorSpeedLeft = (int)((linear - angular/2)*1000); motorSpeedRight = (int)((linear + angular/2)*1000); if (motorSpeedLeft > 0) { motorSpeedLeft = motorSpeedLeft +40; } if (motorSpeedLeft < 0) { motorSpeedLeft = motorSpeedLeft - 40; } if (motorSpeedRight > 0) { motorSpeedRight = motorSpeedRight +40; } if (motorSpeedRight < 0) { motorSpeedRight = motorSpeedRight - 40; } // Set motor speeds setMotorSpeed(motorSpeedLeft, motorSpeedRight); } void setMotorSpeed(int speedLeft, int speedRight) { if (speedLeft > 0) { digitalWrite(IN2_PIN, LOW); analogWrite(IN1_PIN, abs(limitToMaxValue(speedLeft, 250))); } else { digitalWrite(IN1_PIN, LOW); analogWrite(IN2_PIN, abs(limitToMaxValue(speedLeft, 250))); } // Set right motor direction and speed if (speedRight > 0) { digitalWrite(IN4_PIN, LOW); analogWrite(IN3_PIN, abs(limitToMaxValue(speedRight, 250))); } else { digitalWrite(IN3_PIN, LOW); analogWrite(IN4_PIN, abs(limitToMaxValue(speedRight, 250))); } if (speedLeft == 0 && speedRight == 0 ) { digitalWrite(IN3_PIN, LOW); digitalWrite(IN4_PIN, LOW); digitalWrite(IN2_PIN, LOW); digitalWrite(IN1_PIN, LOW); analogWrite(IN1_PIN, abs(limitToMaxValue(speedLeft, 250))); analogWrite(IN3_PIN, abs(limitToMaxValue(speedLeft, 250))); } } void setup() { //set_microros_transports(); set_microros_wifi_transports("NOMBRE_RED", "CONTRASEÑA", "IP_JETSON", 8888); pinMode(LEFT_LED_PIN, OUTPUT); digitalWrite(LEFT_LED_PIN, HIGH); pinMode(RIGHT_LED_PIN, OUTPUT); digitalWrite(RIGHT_LED_PIN, HIGH); pinMode(BATTERY_PIN, INPUT); pinMode(LeftEncoder_C1, INPUT_PULLUP); pinMode(LeftEncoder_C2, INPUT_PULLUP); pinMode(RightEncoder_C1, INPUT_PULLUP); pinMode(RightEncoder_C2, INPUT_PULLUP); pinMode(IN1_PIN, OUTPUT); pinMode(IN2_PIN, OUTPUT); pinMode(IN3_PIN, OUTPUT); pinMode(IN4_PIN, OUTPUT); attachInterrupt(digitalPinToInterrupt(LeftEncoder_C1), LeftEncoderCallback, CHANGE); attachInterrupt(digitalPinToInterrupt(RightEncoder_C1), RightEncoderCallback, CHANGE); // Allow allocation of all timers ESP32PWM::allocateTimer(0); ESP32PWM::allocateTimer(1); ESP32PWM::allocateTimer(2); ESP32PWM::allocateTimer(3); myservo.setPeriodHertz(50); // standard 50 hz servo myservo.attach(servoPin, 1000, 2000); // attaches the servo on pin 18 to the servo object delay(2000); allocator = rcl_get_default_allocator(); //create init_options RCCHECK(rclc_support_init(&support, 0, NULL, &allocator)); // create node RCCHECK(rclc_node_init_default(&node, "lineturtle_esp32", "", &support)); // LED subscriber RCCHECK(rclc_subscription_init_default( &LEDs_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "LEDs")); //servo subscriber RCCHECK(rclc_subscription_init_default( &servo_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "/servo")); // Create twist subscriber RCCHECK(rclc_subscription_init_default( &twist_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(geometry_msgs, msg, Twist), "cmd_vel")); RCCHECK(rclc_publisher_init_default( &battery_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "battery")); RCCHECK(rclc_publisher_init_default( &left_encoder_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "left_motor_ticks")); RCCHECK(rclc_publisher_init_default( &right_encoder_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "right_motor_ticks")); // create timer, const unsigned int timer_timeout = 100; RCCHECK(rclc_timer_init_default( &timer, &support, RCL_MS_TO_NS(timer_timeout), timer_callback)); // create executor RCCHECK(rclc_executor_init(&executor, &support.context, 4, &allocator)); RCCHECK(rclc_executor_add_timer(&executor, &timer)); RCCHECK(rclc_executor_add_subscription(&executor, &LEDs_subscriber, &LEDs_msg, &LEDs_subscription_callback, ON_NEW_DATA)); RCCHECK(rclc_executor_add_subscription(&executor, &servo_subscriber, &servo_msg, &servo_callback, ON_NEW_DATA)); RCCHECK(rclc_executor_add_subscription(&executor, &twist_subscriber, &twist_msg, &cmd_vel_callback, ON_NEW_DATA)); left_encoder_msg.data = 0; right_encoder_msg.data = 0; } void loop() { delay(100); RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100))); } void LeftEncoderCallback() { if (digitalRead(LeftEncoder_C1) == digitalRead(LeftEncoder_C2)) { LeftEncoderCount++; } else { LeftEncoderCount--; } } void RightEncoderCallback() { if (digitalRead(RightEncoder_C1) == digitalRead(RightEncoder_C2)) { RightEncoderCount++; } else { RightEncoderCount--; } }
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
#include <micro_ros_arduino.h> #include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #include <rclc/rclc.h> #include <rclc/executor.h> #include <std_msgs/msg/int8.h> rcl_subscription_t LED_subscriber; std_msgs__msg__Int8 LED_msg; rclc_executor_t executor; rclc_support_t support; rcl_allocator_t allocator; rcl_node_t node; #define LED_PIN 2 #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}} #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}} void error_loop(){ while(1){ delay(100); } } void LED_subscription_callback(const void * msgin) { const std_msgs__msg__Int8 * msg = (const std_msgs__msg__Int8 *)msgin; digitalWrite(LED_PIN, msg->data == 1 ? HIGH : LOW); } void setup() { //Nombre de su red, Contraseña de su red, IP del JETSON NANO, 8888 set_microros_wifi_transports("XXX", "XXXXXX", "192.168.XX.XXX", 8888); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); allocator = rcl_get_default_allocator(); // Create init_options RCCHECK(rclc_support_init(&support, 0, NULL, &allocator)); // Create node RCCHECK(rclc_node_init_default(&node, "lineturtle_esp32", "", &support)); // Create subscriber RCCHECK(rclc_subscription_init_default( &LED_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "control_led")); // Create executor RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator)); RCCHECK(rclc_executor_add_subscription(&executor, &LED_subscriber, &LED_msg, &LED_subscription_callback, ON_NEW_DATA)); } void loop() { delay(100); RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100))); }
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
import rclpy from rclpy.node import Node from std_msgs.msg import Int8 import sys, select, termios, tty class LedController(Node): def __init__(self): super().__init__('led_controller') self.publisher_ = self.create_publisher(Int8, 'control_led', 10) self.led_state = 0 self.get_logger().info('Presiona "p" para encender el LED y "a" para apagarlo') def publish_led_state(self, state): msg = Int8() msg.data = state self.publisher_.publish(msg) self.get_logger().info('LED State: "%s"' % msg.data) def get_key(): tty.setraw(sys.stdin.fileno()) select.select([sys.stdin], [], [], 0) key = sys.stdin.read(1) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, termios.tcgetattr(sys.stdin)) return key def main(args=None): rclpy.init(args=args) led_controller = LedController() try: while rclpy.ok(): key = get_key() if key == 'p': led_controller.publish_led_state(1) elif key == 'a': led_controller.publish_led_state(0) elif key == '\x03': # Ctrl+C para salir break except Exception as e: print(e) finally: led_controller.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
INICIO 1. Conectar la estación de carga y colocar el robot 2. Instalar turtlebot4: $ sudo apt update && sudo apt install ros-humble-turtlebot4-desktop 3. En nuestra terminal abrimos nuestro archivo bash $ nano ~/.bashrc Colocar al final del documento: "export CYCLONEDDS_URI='<CycloneDDS><Domain><General><DontRoute>true</></></></>' ctrl+o guarda Enter ctrl+x 4. Conectaremos la rapberrypi Conectarse a la red Turtlebot4, contraseña: Turtlebot4 Ya conectado a la red: $ ssh [email protected] contraseña: turtlebot4 $ sudo wifi.sh -s 'Nombre_de_red' -p 'contraseña' -r 'país' && sudo reboot País: www.arubanetworks.com/techdocs/InstantWenger_Mobile/Advanced/Content/Instant%20User%20Guide%20-%20volumes/Country_Codes_List.htm#regulatory_domain_3737302751_1017918 5. Conectar el create3 a internet presionar ambos botones hasta que la luz se ponga azul Nos conectamos a la red wifi "CreateXX" En nuestro buscador colocamos: 192.168.10.1\ Dentro en /conectar/ usuario,contraseña, guardar Sonara un sonido de que está conectado 6. Para los que tienen el estandar conectaremos el control. Presionamos el boton inicio, la luz blanca pasa a azul y listo! L1 (lento) o R1(rápido) presionado y con la palanca ¡NO MOVERLO DE REVERSA!
@simonvanrij6264
@simonvanrij6264 2 ай бұрын
Hi, is the power (Fuente de 5-6v) from a USB source or seperate adapter? and is this needed or could/should it work without? Thanks for the video :)
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
Hi, it is a separate power supply, without it it does not work since it is specifically for the servo to move. I use a power bank to which I connected a USB and the positive and negative terminals feed the PCA9685 diver. Do not feed it from the 5V of the Jetson nano, since the servo will demand too much current and the Jetson will shut down due to its safety system.
@simonvanrij6264
@simonvanrij6264 2 ай бұрын
@@IN3DMEX2.0 Thanks for the reply!
@simonvanrij6264
@simonvanrij6264 2 ай бұрын
@@IN3DMEX2.0 What is the mAh of the powerbank? i cant get it to work with an 1A adapter (2x MG996R Servo's)
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
​@@simonvanrij6264 In my case was 2000mA
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
+++ CÓDIGO ARDUINO +++ #include <micro_ros_arduino.h> #include <ESP32Servo.h> #include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #include <rclc/rclc.h> #include <rclc/executor.h> #include <std_msgs/msg/int8.h> Servo myservo; // create servo object to control a servo int servoPin = 12; rcl_subscription_t LEDs_subscriber; std_msgs__msg__Int8 LEDs_msg; rcl_subscription_t servo_subscriber; std_msgs__msg__Int8 servo_msg; rclc_executor_t executor; rclc_support_t support; rcl_allocator_t allocator; rcl_node_t node; rcl_timer_t timer; #define LEFT_LED_PIN 2 #define RIGHT_LED_PIN 4 #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}} #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}} void error_loop(){ while(1){ delay(100); } } int limitToMaxValue(int value, int maxLimit) { if (value > maxLimit) { return maxLimit; } else { return value; } } void LEDs_subscription_callback(const void * msgin) { const std_msgs__msg__Int8 * msg = (const std_msgs__msg__Int8 *)msgin; int8_t value = msg->data; switch (value) { case 0: digitalWrite(LEFT_LED_PIN, LOW); digitalWrite(RIGHT_LED_PIN, LOW); break; case 1: digitalWrite(LEFT_LED_PIN, HIGH); digitalWrite(RIGHT_LED_PIN, LOW); break; case 2: digitalWrite(LEFT_LED_PIN, LOW); digitalWrite(RIGHT_LED_PIN, HIGH); break; case 3: digitalWrite(LEFT_LED_PIN, HIGH); digitalWrite(RIGHT_LED_PIN, HIGH); break; default: break; } //digitalWrite(LED_PIN, (msg->data == 0) ? LOW : HIGH); } void servo_callback(const void* msgin) { const std_msgs__msg__Int8* msg = (const std_msgs__msg__Int8*)msgin; int8_t angle = msg->data; int servo_position; servo_position = limitToMaxValue(angle, 90); myservo.write(servo_position); } void setup() { //set_microros_transports(); set_microros_wifi_transports("INNOVA3D", "asdf123asdf", "192.168.50.175", 8888); pinMode(LEFT_LED_PIN, OUTPUT); digitalWrite(LEFT_LED_PIN, HIGH); pinMode(RIGHT_LED_PIN, OUTPUT); digitalWrite(RIGHT_LED_PIN, HIGH); delay(2000); // Allow allocation of all timers ESP32PWM::allocateTimer(0); ESP32PWM::allocateTimer(1); ESP32PWM::allocateTimer(2); ESP32PWM::allocateTimer(3); myservo.setPeriodHertz(50); // standard 50 hz servo myservo.attach(servoPin, 1000, 2000); // attaches the servo on pin 18 to the servo object allocator = rcl_get_default_allocator(); //create init_options RCCHECK(rclc_support_init(&support, 0, NULL, &allocator)); // create node RCCHECK(rclc_node_init_default(&node, "lineturtle_esp32", "", &support)); // LED subscriber RCCHECK(rclc_subscription_init_default( &LEDs_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "LEDs")); //servo subscriber RCCHECK(rclc_subscription_init_default( &servo_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "/servo")); // create executor RCCHECK(rclc_executor_init(&executor, &support.context, 2, &allocator)); RCCHECK(rclc_executor_add_subscription(&executor, &LEDs_subscriber, &LEDs_msg, &LEDs_subscription_callback, ON_NEW_DATA)); RCCHECK(rclc_executor_add_subscription(&executor, &servo_subscriber, &servo_msg, &servo_callback, ON_NEW_DATA)); } void loop() { delay(100); RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100))); }
@IN3DMEX2.0
@IN3DMEX2.0 2 ай бұрын
CURSO EN ESPAÑOL DE IMPLEMENTACIÓN DE INTELIGENCIA ARTIFICIAL EN LA ROBÓTICA --- VE MI CANAL
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
+++CÓDIGO ARDUINO+++ #include <micro_ros_arduino.h> #include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #include <rclc/rclc.h> #include <rclc/executor.h> #include <std_msgs/msg/int8.h> rcl_subscription_t Motor_subscriber; std_msgs__msg__Int8 Motor_msg; rclc_executor_t executor; rclc_support_t support; rcl_allocator_t allocator; rcl_node_t node; rcl_timer_t timer; #define LEFT 2 #define RIGHT 4 #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}} #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}} void error_loop(){ while(1){ delay(100); } } void Motor_subscription_callback(const void * msgin) { const std_msgs__msg__Int8 * msg = (const std_msgs__msg__Int8 *)msgin; int8_t value = msg->data; switch (value) { case 0: digitalWrite(LEFT, LOW); digitalWrite(RIGHT, LOW); break; case 1: digitalWrite(LEFT, HIGH); digitalWrite(RIGHT, LOW); break; case 2: digitalWrite(LEFT, LOW); digitalWrite(RIGHT, HIGH); break; default: break; } } void setup() { //set_microros_transports(); set_microros_wifi_transports("INNOVA3D", "asdf123asdf", "192.168.50.175", 8888); pinMode(LEFT, OUTPUT); digitalWrite(LEFT, HIGH); pinMode(RIGHT, OUTPUT); digitalWrite(RIGHT, HIGH); delay(2000); allocator = rcl_get_default_allocator(); //create init_options RCCHECK(rclc_support_init(&support, 0, NULL, &allocator)); // create node RCCHECK(rclc_node_init_default(&node, "lineturtle_esp32", "", &support)); // create subscriber RCCHECK(rclc_subscription_init_default( &Motor_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "Motor")); // create executor RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator)); RCCHECK(rclc_executor_add_subscription(&executor, &Motor_subscriber, &Motor_msg, &Motor_subscription_callback, ON_NEW_DATA)); } void loop() { delay(100); RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100))); }
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
#CÓDIGO PYTHON import cv2 import mediapipe as mp import serial import time ser = serial.Serial( port = "COM7", #Modificar este puerto JETSON -- "/dev/ttyACM0" Computadora "COM3" baudrate = 115200) # Inicializar MediaPipe Hands mp_hands = mp.solutions.hands hands = mp_hands.Hands() mp_drawing = mp.solutions.drawing_utils # Capturar video desde la cámara cap = cv2.VideoCapture(0) def movimiento(x): if x < 50: print("PRENDE") ser.write("A".encode()) else: print("APAGA") ser.write("B".encode()) while cap.isOpened(): ret, frame = cap.read() if not ret: break # Convertir la imagen de BGR a RGB rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Procesar la imagen y detectar manos results = hands.process(rgb_frame) # Dibujar las anotaciones de las manos en la imagen original if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS) # Obtener la posición x del dedo índice (landmark 8) index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP] x = index_finger_tip.x x = x * 100 #print(f"Posición x del dedo índice: {x}") movimiento(x) # Mostrar la imagen con las anotaciones cv2.imshow('Hand Detection', frame) # Salir del bucle si se presiona la tecla 'q' if cv2.waitKey(1) & 0xFF == ord('q'): break # Liberar los recursos cap.release() cv2.destroyAllWindows()
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
#CÓDIGO ARDUINO int mensaje; void setup() { pinMode(2, OUTPUT); Serial.begin(115200); } void loop() { if(Serial.available()){ mensaje = Serial.read(); Serial.print(mensaje); if(mensaje == 'A'){ digitalWrite(2, HIGH); } if(mensaje == 'B'){ digitalWrite(2, LOW); } } }
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
++++++++ CÓDIGO DE ARDUINO ++++++++++ int mensaje; void setup() { pinMode(2, OUTPUT); Serial.begin(115200); } void loop() { if(Serial.available()){ mensaje = Serial.read(); Serial.print(mensaje); if(mensaje == 'A'){ digitalWrite(2, HIGH); } if(mensaje == 'B'){ digitalWrite(2, LOW); } } }
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
++++++++CÓDIGO DE Prueba de acceso serial ++++++++++ import serial try: ser = serial.Serial('/dev/ttyUSB0', 115200) # Asegúrate de que este sea el puerto correcto print("Puerto serie abierto correctamente") ser.close() except serial.SerialException as e: print(f"Error al abrir el puerto serie: {e}")
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
+++CÓDIGO DE Comunicación Serial Jetson-ESP32 (Python-Arduino)++++++ import serial #Modificar puerto JETSON -- "/dev/ttyACM0" o "/dev/ttyUSB0" Computadora "COM#" ser = serial.Serial( port = "/dev/ttyUSB0", baudrate = 115200) def Estado_LED(x): if x < 50: print("PRENDE") ser.write("A".encode()) else: print("APAGA") ser.write("B".encode()) while True: x = int(input("Ingrese numero: ")) Estado_LED(x)
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
Código: 👇 Recuerden NO colocar el símbolo "$" sólo indica los comandos que se colocan en terminal $ cd miPython $ nano usar_GPIO.py import RPi.GPIO as GPIO import time LED = 7 GPIO.setmode(GPIO.BOARD) GPIO.setup(LED, GPIO.OUT) #Alt+60 para el signo menor que < x = 0 while x < 4: GPIO.output(LED,True) time.sleep(2) GPIO.output(LED,False) time.sleep(2) x += 1 print("Finaliza") #IMPORTANTE LIMPIAR PINES GPIO.cleanup(LED)
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
GUARDARLO CON EL NOMBRE DE: lineturtle_esp32_microros #include <micro_ros_arduino.h> #include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #include <rclc/rclc.h> #include <rclc/executor.h> #include <std_msgs/msg/int8.h> rcl_subscription_t LEDs_subscriber; std_msgs__msg__Int8 LEDs_msg; rclc_executor_t executor; rclc_support_t support; rcl_allocator_t allocator; rcl_node_t node; rcl_timer_t timer; #define LEFT_LED_PIN 2 #define RIGHT_LED_PIN 16 #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}} #define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}} void error_loop(){ while(1){ delay(100); } } void LEDs_subscription_callback(const void * msgin) { const std_msgs__msg__Int8 * msg = (const std_msgs__msg__Int8 *)msgin; int8_t value = msg->data; switch (value) { case 0: digitalWrite(LEFT_LED_PIN, LOW); digitalWrite(RIGHT_LED_PIN, LOW); break; case 1: digitalWrite(LEFT_LED_PIN, HIGH); digitalWrite(RIGHT_LED_PIN, LOW); break; case 2: digitalWrite(LEFT_LED_PIN, LOW); digitalWrite(RIGHT_LED_PIN, HIGH); break; case 3: digitalWrite(LEFT_LED_PIN, HIGH); digitalWrite(RIGHT_LED_PIN, HIGH); break; default: break; } //digitalWrite(LED_PIN, (msg->data == 0) ? LOW : HIGH); } void setup() { //set_microros_transports(); set_microros_wifi_transports("NOMBRE_DE_RED", "CONTRASEÑA", "IP_JETSON", 8888); pinMode(LEFT_LED_PIN, OUTPUT); digitalWrite(LEFT_LED_PIN, HIGH); pinMode(RIGHT_LED_PIN, OUTPUT); digitalWrite(RIGHT_LED_PIN, HIGH); delay(2000); allocator = rcl_get_default_allocator(); //create init_options RCCHECK(rclc_support_init(&support, 0, NULL, &allocator)); // create node RCCHECK(rclc_node_init_default(&node, "lineturtle_esp32", "", &support)); // create subscriber RCCHECK(rclc_subscription_init_default( &LEDs_subscriber, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int8), "LEDs")); // create executor RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator)); RCCHECK(rclc_executor_add_subscription(&executor, &LEDs_subscriber, &LEDs_msg, &LEDs_subscription_callback, ON_NEW_DATA)); } void loop() { delay(100); RCCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100))); }
@IN3DMEX2.0
@IN3DMEX2.0 3 ай бұрын
INSTALACIÓN ROS2 (HUMBLE) JETSON NANO docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html NO COPIAR EL SÍMBOLO DE PESOS "$" SÓLO ES PARA INDICAR CUALES SE COPIAN EN LA TERMINAL --------CORROBORA LOCALE------- locale $ sudo apt update && sudo apt install locales $ sudo locale-gen en_US en_US.UTF-8 $ sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 $ export LANG=en_US.UTF-8 locale --------INSTALA DEPENDENCIAS------- $ sudo apt update && sudo apt install gnupg wget $ sudo apt install software-properties-common $ sudo add-apt-repository universe -----------INICIO SOURCE-------- $ wget -qO - isaac.download.nvidia.com/isaac-ros/repos.key | sudo apt-key add - $ wget -qO - isaac.download.nvidia.cn/isaac-ros/repos.key | sudo apt-key add - $ echo 'deb isaac.download.nvidia.com/isaac-ros/ubuntu/main focal main' | sudo tee -a /etc/apt/sources.list $ echo 'deb isaac.download.nvidia.cn/isaac-ros/ubuntu/main focal main' | sudo tee -a /etc/apt/sources.list $ sudo apt update && sudo apt install curl -y $ sudo curl -sSL raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null ----------INSTALACIÓN DE PAQUETES ROS2, ROS, RVIZ, demos, tutorials------ $ sudo apt update $ sudo apt install ros-humble-desktop --------y/o------- $ sudo apt install ros-humble-desktop-full $ sudo apt install ros-dev-tool ------------PRUEBA DE ROS2----------- $ source /opt/ros/humble/setup.bash $ ros2 run demo_nodes_cpp talker PARA TEMINAR EL DEMO CON "CTRL+C"
@mairios521
@mairios521 10 ай бұрын
Hola Carlos!! Se ve súper interesante tu trabajo, tendrías para compartir el código en Github? Muchas gracias!
@IN3DMEX2.0
@IN3DMEX2.0 10 ай бұрын
Por favor, envíame un correo a [email protected] y puedo pasártelos por ahí.
@mariasusanajalpaflores4511
@mariasusanajalpaflores4511 2 жыл бұрын
Me sorprende ver el resultado ‼️ Muchas felicidades 👏👏
@Anthony-gg9eu
@Anthony-gg9eu 2 жыл бұрын
¿Amigo tendrás algún curso donde expliques este metodo?
@IN3DMEX2.0
@IN3DMEX2.0 2 жыл бұрын
Estoy preparando uno de inteligencia artificial en la robótica. Recomiendo para empezar el curso "Aprendizaje por refuerzo Profundo 2.0" de Juan Gabriel Gomila
@Anthony-gg9eu
@Anthony-gg9eu 2 жыл бұрын
@@IN3DMEX2.0 ya tome ese curso😅 tu trabajo en este proyecto es increíble yo no he podido encontrar mucha información para poder llevar los programas a algo de manera física.
@IN3DMEX2.0
@IN3DMEX2.0 10 ай бұрын
@@Anthony-gg9eu Disculpa la enorme tardanza, daré cursos al respecto, además pasaremos a algo físico. Si te interesa manda correo a [email protected]. Estaremos de la mano para que se entienda cómo se realizó.
@mariasusanajalpaflores4511
@mariasusanajalpaflores4511 3 жыл бұрын
Se me hace muy interesante.