Progreso octubre 2023 - RoboticsURJC/tfg-dcampoamor GitHub Wiki

Progreso junio 2023

SEMANA 26 (16/10/2023-22/10/2023)

SEMANA 27 (23/10/2023-29/10/2023)

SEMANA 28 (30/10/2023-05/11/2023)

Semana 26 (16/10/2023-22/10/2023)

  • Pruebas de código y programa para enviar a un robot UR a una posición determinada por un sistema de visión externo

    Se realizaron las primeras pruebas para poder enviar a un brazo robótico de la marca Universal Robots y modelo UR5e a una posición en el espacio determinada por un sistema de visión externo.

    Para ello se elaboró el programa de robot visionsimple.urp.

    visionsimple program

    Este programa puede leerse también como script de la siguiente manera:

    def visionsimple():
      set_tool_communication(False, 115200, 0, 1, 1.5, 3.5)
      set_tool_output_mode(0)
      set_tool_digital_output_mode(0, 1)
      set_tool_digital_output_mode(1, 1)
      set_tool_voltage(0)
      set_gravity([0.0, 0.0, 9.82])
      set_standard_analog_input_domain(0, 1)
      set_standard_analog_input_domain(1, 1)
      set_tool_analog_input_domain(0, 1)
      set_tool_analog_input_domain(1, 1)
      set_analog_outputdomain(0, 0)
      set_analog_outputdomain(1, 0)
      set_input_actions_to_default()
      set_target_payload(0.000000, [0.000000, 0.000000, 0.000000], [0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000])
      set_tcp(p[0.0,0.0,0.0,0.0,0.0,0.0])
      step_count_8bc87aee_d807_40ef_b872_d7b5435bde05 = 0.0
      thread Step_Counter_Thread_1e9a2406_c633_419c_b6e2_0c27312ef4da():
        while (True):
          step_count_8bc87aee_d807_40ef_b872_d7b5435bde05 = step_count_8bc87aee_d807_40ef_b872_d7b5435bde05 + 1.0
          sync()
        end
      end
      run Step_Counter_Thread_1e9a2406_c633_419c_b6e2_0c27312ef4da()
      set_safety_mode_transition_hardness(1)
      global punto_ref_p=p[-.115755230449, -.608104231571, .633047341516, -.028750562618, 2.224872447434, -2.143508715282]
      global punto_ref_q=[-1.5460882244741576, -1.835829803453966, -1.3966552787100062, 0.05425187699994984, 1.596467105108804, 
      0.02361196008044309]
      while (True):
        $ 1 "Robot Program"
        $ 2 "MoveJ"
        $ 3 "punto_ref" "breakAfter"
        movej(get_inverse_kin(pose_trans(punto_ref_p, get_tcp_offset()), qnear=punto_ref_q), a=1.3962634015954636, v=1.0471975511965976)
        $ 4 "Datos_Recibidos_Camara"
        $ 5 "'Esperar la foto realizada por la camara'"
        # 'Esperar la foto realizada por la camara'
        $ 6 "x≔400"
        global x=400
        $ 7 "y≔200"
        global y=200
        $ 8 "rz≔30"
        global rz=30
        $ 9 "Calcular_Posicion_Pick"
        $ 10 "'# Convertir mm a m y grados a rad'"
        # '# Convertir mm a m y grados a rad'
        $ 11 "pos_base_camara≔p[(x/1000), (y/1000), 0, 0, 0, d2r(rz)]"
        global pos_base_camara=p[(x/1000), (y/1000), 0, 0, 0, d2r(rz)]
        $ 12 "pos_pick≔pose_trans(punto_ref, pos_base_camara)"
        global pos_pick=pose_trans(pose_trans(punto_ref_p, get_tcp_offset()), pos_base_camara)
        $ 13 "Mover_a_pos_pick"
        $ 14 "MoveL"
        $ 15 "pos_pick" "breakAfter"
        movel(pos_pick, a=1.2, v=0.25)
      end
    end
    

    Siendo la posición x=400, y=200, rz=30 la posición devuelta por el sistema de visión en su eje de coordenadas.

    pose_trans()

    Este lenguaje de script de UR es el lenguaje de alto nivel desarrollado por la propia compañía, y basado en el lenguaje de script de Python, y es una alternativa a la realización de una estructura programada en la IGU (Interfaz Gŕafica de Usuario) Polyscope.

  • Elaboración de un programa para enviar una cadena a un servidor y recibir por socket una lista de enteros

    Se elaboró un programa recibir_float_socket en el simulador de UR (URSim) para poder comunicar mediante socket el robot con un servidor externo, como puede ser un sistema de visión. En este programa se abre el socket con el servidor, desde el robot se envía una cadena (str) para avisar de que existe comunicación mediante la palabra "listo", para posteriormente leer tres comas flotantes y poder guardarlas como variables antes de cerrar el socket.

    recibir_float_socket

    El script puede leerse también como:

    def recibir_str_socket():
      set_standard_analog_input_domain(0, 1)
      set_standard_analog_input_domain(1, 1)
      set_tool_analog_input_domain(0, 1)
      set_tool_analog_input_domain(1, 1)
      set_analog_outputdomain(0, 0)
      set_analog_outputdomain(1, 0)
      set_input_actions_to_default()
      step_count_a80e0dc3_bb86_4461_88d5_a49db4213474 = 0.0
      thread Step_Counter_Thread_b8642d5d_1019_4b67_be9e_cf80d39436ee():
        while (True):
          step_count_a80e0dc3_bb86_4461_88d5_a49db4213474 = step_count_a80e0dc3_bb86_4461_88d5_a49db4213474 + 1.0
          sync()
        end
      end
      run Step_Counter_Thread_b8642d5d_1019_4b67_be9e_cf80d39436ee()
      set_safety_mode_transition_hardness(1)
      set_tool_communication(False, 115200, 0, 1, 1.5, 3.5)
      set_tool_output_mode(0)
      set_tool_digital_output_mode(0, 1)
      set_tool_digital_output_mode(1, 1)
      set_tool_voltage(0)
      set_gravity([0.0, 0.0, 9.82])
      set_tcp(p[0.0,0.0,0.0,0.0,0.0,0.0])
      set_target_payload(0.000000, [0.000000, 0.000000, 0.000000], [0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000])
      $ 1 "BeforeStart"
      $ 2 "conexion≔ False "
      global conexion=  False  
      $ 3 "datos≔[0,0,0,0]"
      global datos=[0,0,0,0]
      $ 4 "pos_pick≔p[0,0,0,0,0,0]"
      global pos_pick=p[0,0,0,0,0,0]
      while (True):
        $ 5 "Robot Program"
        $ 6 "Loop conexion≟ False "
        while (conexion ==   False  ):
          $ 7 "'Abrimos socket'"
          # 'Abrimos socket'
          $ 8 "conexion≔socket_open('172.16.17.10',50000)"
          global conexion=socket_open("172.16.17.10",50000)
          $ 9 "Wait: 0.01"
          sleep(0.01)
        end
        $ 10 "'Enviamos la cadena str 'listo''"
        # 'Enviamos la cadena str "listo"'
        $ 11 "str≔'listo'"
        global str="listo"
        $ 12 "socket_send_string(str)"
        socket_send_string(str)
        $ 13 "Loop datos[0]≠3"
        while (datos[0] != 3):
          $ 14 "'Leemos las tres comas flotantes'"
          # 'Leemos las tres comas flotantes'
          $ 15 "datos≔socket_read_ascii_float(3)"
          global datos=socket_read_ascii_float(3)
          $ 16 "Wait: 0.5"
          sleep(0.5)
        end
        $ 17 "'Guardamos las comas flotantes en variables'"
        # 'Guardamos las comas flotantes en variables'
        $ 18 "x≔datos[1]"
        global x=datos[1]
        $ 19 "y≔datos[2]"
        global y=datos[2]
        $ 20 "rz≔datos[3]"
        global rz=datos[3]
        $ 21 "socket_close()"
        socket_close()
        $ 22 "pos_pick≔p[x,y,0,0,0,rz]"
        global pos_pick=p[x,y,0,0,0,rz]
      end
    end
    
  • Elaboración de la memoria

    De manera paralela a la consecución de pruebas, se inició la elaboración de la memoria del trabajo.

Semana 27 (23/10/2023-29/10/2023)

  • Pruebas de conexión Servidor-Robot

    Para poder llevar a cabo la comunicación entre el ordenador y el robot, y ejecutar y probar los programas de UR anteriormente mencionados, se llevaron a cabo pruebas de conectividad entre los dos dispositivos, que previamente se habían conectado a la misma red.

    Para ello, se le adjudicó al robot la siguiente configuración detallada de red:

    Dirección estática IP Máscara de subred
    192.168.1.232 255.255.255.0

    Utilizaremos una dirección DHCP (Dynamic Host Configuration Protocol, en español Protocolo de Configuración Dinámica de Host), es decir, un protocolo de red para asignar de manera automática y dinámica direcciones IP y otros parámetros de configuración de red en nuestro ordenador, y desde el símbolo de sistema o cmd escribiremos el siguiente comando:

    ping 192.168.1.232

    Siendo la dirección IP la del robot con el que queremos comunicar el PC. El comando "ping" envía una serie de paquetes de datos a la dirección especificada y muestra información sobre la conectividad entre el ordenador y el destino. La salida del comando "ping" proporcionará información sobre el número de paquetes enviados, recibidos y perdidos, así como el tiempo que tarda cada paquete en viajar desde el PC al destino y regresar, permitiendo evaluar la calidad de la conexión.

    ping cmd

    En este caso, todos los paquetes son recibidos sin pérdida y el tiempo de ida y vuelta (latencia) es bajo, esto indica una buena conectividad con el destino. Si algunos paquetes se pierden o la latencia es alta, puede indicar problemas de conectividad o congestión de red.

  • Pruebas de código para enviar una cadena a un servidor y recibir por socket una lista de enteros

    Tras elaborar los programas de robot, se procedió a probarlos con un resultado satisfactorio. Para el envío de una cadena de caracteres (str) se acotó el programa recibir_float_socket para corroborar que únicamente se enviase la cadena "listo" del UR al servidor mediante socket correctamente, mediante el programa enviar_str_socket y su script.

    enviar_str_socket

    En el vídeo enviar_str_socket.gif puede verse el proceso en el que se lleva a cabo la comunicación robot-servidor y se recibe la cadena str "listo" que se envía a través del programa de robot.

    Tras comprobar esto, se procedió a ejecutar el programa entero recibir_cadena_socket, que consiste en lo mismo que el programa recibir_float_socket, pero variando la instrucción en la que se envía la cadena de caracteres al servidor de socket_send_string(str) a socket_send_line(str), que envía una cadena con un carácter de nueva línea. El resultado en el cual se ve como se envía la cadena str "listo" al servidor, y posteriormente el robot recibe un vector de enteros de tres componentes introducido a mano, para asignarlas a las variables x,y,rz que conforman la pos_pick del objeto, puede verse en el vídeo recibir_cadena_socket.gif.

    recibir_cadena_socket

  • Pruebas de código y programa para enviar a un robot UR a una posición determinada por un sistema de visión externo

    Continuando con las primeras pruebas para poder enviar a un brazo robótico a una posición en el espacio determinada por un sistema de visión externo, mediante el programa de robot visionsimple.urp, se añadieron al programa las líneas necesarias para poder abrir la comunicación con el servidor, leer los datos del socket, que se introducen de manera manual, calcular la posición pos_pick, que es la posición de cogida del objeto, e ir a esta posición en el programa prueba_visionsimple.urp y su script.

    prueba_visionsimple_1 prueba_visionsimple_2

    La ejecución de este programa puede verse en el vídeo prueba_visionsimple.gif.

  • Elaboración de un programa en python para guardar varias posiciones de objeto en una lista

    Ya que el programa de detección de fresas, es probable que detecte más de una fresa a la vez, tal y como se pudo comprobar anteriormente, y por tanto, habrá que gestionar las coordenadas de todas las fresas detectadas para que, posteriormente, el brazo robótico vaya una por una a cada una de estas coordenadas a recoger la fruta. Para ello se elaboró el programa lista_pos.py que recoge las coordenadas x e y (suponiendo z constante) donde se piden de manera manual al usuario las coordenadas de varias posiciones (estas posiciones que se piden de manera manual, deberán ser las que se detecten por la cámara) y en las que se simula como el brazo robótico, a medida que va yendo a cada una de estas posiciones. se van borrando de la lista. Esto se puede ver en el vídeo lista_pos.gif.

  • Elaboración de la memoria

    De manera paralela a la consecución de pruebas, se inició la elaboración de la memoria del trabajo.

Semana 28 (30/10/2023-05/11/2023)

  • Detección de objetos por python

    Debido a que a tras la detección de las posiciones de las frutas mediante el programa de Jupyter Notebook, no se puede trabajar directamente con ellas y enviarlas al robot, ya que Jupyter Notebook está basado en web, por lo que haría falta un servidor web intermediario, como por ejemplo Django, se intentó llevar a cabo la detección mediante python, para que de este modo, se pudieran enviar al brazo robótico directamente las coordenadas, al estar trabajando en local, y tener todo el código unificado.

    Para ello se tomó como referencia y ayuda los repositorios Real Time Emotion Detection for Low Cost Robot in ROS y Detección de objetos en vídeo.

    Para tener en orden nuestras paqueterias de python creamos el ambiente "deteccionobj" el cual tiene la version 3.6 de python.

    conda create -n deteccionobj python=3.6
    

    Activamos el ambiente deteccionobj para asegurarnos que estemos en el ambiente correcto al momento de hacer la instalación de todas las paqueterias necesarias.

    conda activate deteccionobj
    

    Estando dentro de nuestro ambiente y habiendo clonado el repositorio Detección de objetos en vídeo se instalarán todas las paqueterías necesarias para correr nuestro detector de objetos en vídeo, la lista de los paquetes y versiones a instalar están dentro del archivo requirements.txt por lo cual instalaremos haciendo referencia a ese archivo.

    pip install -r requirements.txt
    

    Al instalar este archivo, apareció el siguiente error:

    ERROR cannot uninstall certifi

    No pudiendo desinstalar la versión de certifi para poder instalar una más reciente, por lo que se solucionó con el comando:

    pip install --ignore-installed certifi
    

    installed certifi

    Se volvió a intentar ejecutar el programa deteccion_video.py varias veces, obteniendo problemas ModuleNotFoundError, por lo que se tuvieron que instalar varios módulos:

    ModuleNotFoundError No module named torch

    pip install torch torchvision torchaudio
    

    ModuleNotFoundError No module named matplotlib

    pip install matplotlib
    

    ModuleNotFoundError No module named cv2

    pip install opencv-python
    

    Sin embargo, al volver a ejecutar el programa tras instalar estos módulos, se obtuvo lo siguiente:

    cv2 error

  • Pruebas de uso de la cámara Kinect en Ubuntu

    Paralelamente a las pruebas para la detección de objetos mediante python, se llevó a cabo la instalación de la cámara Kinect en Linux.

    Para ello, primero se instalaron las siguientes librerías:

    • git-core
    • cmake
    • libglut3-dev
    • pkg-config
    • build-essential
    • libxmu-dev
    • libxi-dev
    • libusb-1.0-0-dev
    • gcc
    • g++

    Después de haber instalado estas librerías, es necesario clonar el repositorio libfreenect de OpenKinect.

    git clone https://github.com/OpenKinect/libfreenect.git
    

    Después de haber clonado este repositorio, accederemos a la carpeta que se creó "libfreenect" donde se encuentra el paquete freenect.

    cd libfreenect
    

    En esta carpeta, se creará otra carpeta llamada "build", para posteriormente dirigirse a ella.

    mkdir build
    cd build
    

    Para compilar todos los archivos que contiene el paquete, se utilizará el comando CMake:

    cmake ..
    make
    

    Finalmente, se ejecutarán las siguientes instrucciones para finalizar la instalación del paquete:

    sudo make install
    sudo ldconfig /usr/local/lib64/
    

    Para ejecutar los ejemplos que contiene el paquete, se tendrá que acceder a la carpeta "examples".

    Una vez allí, se probará a ejecutar el glview, ejemplo en el que podremos obtener la imagen a color y en otro cuadro el diagrama de profundidad, además en este ejemplo se puede mover el motor hacia arriba y hacia abajo con las teclas w y x respectivamente; con la tecla s podemos centrar el motor en la posición normal. Ademas con las números del 0 al 6 podemos variar el color del LED del Kinect.

    cd examples
    ./glview.c
    

    Al ejecutar esto, se obtiene el mensaje "Permiso denegado", este error se debe a que se está intentando ejecutar un archivo fuente (en este caso, glview.c), en lugar de un archivo ejecutable.

    glview permiso denegado

    Para compilar y ejecutar un programa C, se debe compilar el código fuente en un archivo ejecutable antes de ejecutarlo:

    1. Compilar el programa: Primero, se debe compilar el archivo fuente glview.c en un archivo ejecutable. Se puede hacer utilizando el compilador de C, por ejemplo, GCC.

    gcc -o glview glview.c -lfreenect
    

    Sin embargo, al ejecutar este comando se obtuvo el siguiente fallo:

    fallo compilacion

    Este error indica que la constante FREENECT_AUTO_FLICKER no está definida en el programa glview.c. En su lugar, sugiere FREENECT_AUTO_EXPOSURE como una opción similar. Esto puede deberse a diferencias en las versiones de libfreenect o a cambios en la API de libfreenect, por lo que, en un editor de texto se busca la línea que contiene la referencia a FREENECT_AUTO_FLICKER y se reemplaza esa constante con FREENECT_AUTO_EXPOSURE.

    Tras este cambio, se intentó ejecutar de nuevo el comando anteriormente mencionado, obteniendo el error:

    Falta de definiciones

    Esto es debido a la falta de definiciones de funciones y bibliotecas relacionadas con OpenGL. Para compilar un programa que utiliza OpenGL, se debe enlazar adecuadamente con las bibliotecas de OpenGL. Esto se hace agregando las opciones de enlace correctas al comando gcc.

    Para solucionar este problema, puedes usar el siguiente comando de compilación:

    gcc -o glview glview.c -lfreenect -lGL -lGLU -lglut -lm
    

    Este comando agrega las siguientes opciones de enlace:

    • lGL: Enlaza con la biblioteca principal de OpenGL.
    • lGLU: Enlaza con la biblioteca OpenGL Utility (GLU) que proporciona funciones útiles para OpenGL.
    • lglut: Enlaza con la biblioteca GLUT, que es una biblioteca para crear ventanas y gestionar eventos de teclado y ratón en aplicaciones gráficas.
    • lm: Enlaza con la biblioteca matemática, que proporciona funciones matemáticas como sqrt y atan2.

    2. Otorgar permisos de ejecución: Una vez teniendo el archivo ejecutable, hay que otorgar permisos para ejecutarlo. Se puede hacer con el siguiente comando:

    chmod +x glview
    

    3. Ejecutar el programa:

    ./glview
    

    ejecutar controles

    El vídeo de la prueba se puede encontra en Prueba Kinect.mp4

    prueba camara

  • Elaboración de la memoria

    De manera paralela a la consecución de pruebas, se inició la elaboración de la memoria del trabajo.