<jupyter_start><jupyter_text>Desarrollo de algoritmo para simulación.El desarrollo de este algoritmo fue llevado a cabo durante el semestre agosto-diciembre 2020, como parte de la asignatura de robotica.    Alumno : <NAME> de <NAME>.    Numero de control : 15400806.    Materia : Robotica.    Maestro : Dr. <NAME>.Requiere que los archivos 'sim.py', 'simConst.py', 'remoteapi.dll' estén alojados en la misma carpeta que este cuaderno de Jupyter.Desde CoppeliaSim, abrir la escena 'DeskBot_scena.ttt' Instrucciones para preparar la simulacion.1. Abra la escena 'DeskBot_scena.ttt'2. Seleccionando la base del robot desde la jerarquía de escena, presione botón derecho del mouse y agregue un archivo de script mediante  Add -> Associated child script -> Non threaded . Aparecerá un pequeño ícono de documento junto al nombre del robot en la escena de jerarquía.3. En el script es posible incluir código de programación, escritos en lenguaje LUA. Para nuestro caso, todo el código que requeriremos es habilitar el API remoto, asignando un puerto de comunicación. En la función sysCall_init() agregue la siguiente línea:   simRemoteApi.start(19999) Proceda a continuación con las actividades:  Seccion 1.- Simulacion y coneccion con coppelia.<jupyter_code># importamos las librerías necesarias
import sim          # librería para conectar con CoppeliaSim
import sympy as sp  # librería para cálculo simbólico
import numpy as np<jupyter_output><empty_output><jupyter_text>Configuraciones del servidor local<jupyter_code>#Variables para configurar entorno del servidor y port
localhost = '127.0.0.1'  #Servidor local de la computadora
port = 19999  #Puerto para coneccion con V-rep<jupyter_output><empty_output><jupyter_text>Configuramos el servidor y el portEl siguiente codigo deberia ejecutarse una vez que se presiona play en la simulacion, de funcionar correctamente el cliente quedara conectado con la API de V-rep.<jupyter_code>def connect(port):
# Establece la conexión a VREP
# port debe coincidir con el puerto de conexión en VREP
# retorna el número de cliente o -1 si no puede establecer conexión
    sim.simxFinish(-1) # Cierra ports abiertos en caso de haber
    clientID=sim.simxStart(localhost,port,True,True,2000,5) # Conectarse
    if clientID == 0: print("conectado a", port)
    else: print("no se pudo conectar")
    return clientID

# Requerimos los manejadores para las articulaciones y el Dummy
clientID = connect(19999)<jupyter_output>conectado a 19999<jupyter_text>Configuramos el programa y obtenemos objetos de la simulacion.obtendermos las juntas y objetos de la simulacion para asignarlos a variables con las que nos podremos referir en el codigo.De esta forma trabajaremos con POO (Programacion Orientada a Objetos) en nuestro programa.<jupyter_code>#Variables para configurar entorno 
#Estas variables se agregaron dado que la simulacion fuera a modificarse y por ende sus valores 
#tales como rangos de juntas prismaticas, nombres de juntas etc.

#Como esta nombrada la junta revoluta de dicho eslabon
nombre_junta_eslabon_1 = 'eslabon_1' #la primera junta revoluta acoplada a la corredera
nombre_junta_eslabon_2 = 'eslabon_2' #la segunda junta revoluta acoplada a el eslabon anterior

#Como esta nombrada la junta prismatica de dicho eslabon
nombre_junta_corredera = 'Corredera'
nombre_junta_efector = 'junta_efector'

#Como esta nombrado el dummy que sirve como punto final del efector
dummy_posicion = 'posicion_final'

#Valores de los rangos minimos y maximos de juntas prismaticas (en metros) dado que las funciones se encargan
#de transformar en decimales necesarios 
min_corredera,max_corredera = [0,0.3]
min_efector,max_efector = [-0.04,0]

print(f'El nombre en la simulacion de la junta revoluta del eslabon 1 debe ser "{nombre_junta_eslabon_1}"')
print(f'El nombre en la simulacion de la junta revoluta del eslabon 2 debe ser "{nombre_junta_eslabon_2}"')
print(f'El nombre en la simulacion de la junta prismatica de la corredera debe ser "{nombre_junta_corredera}", limite minimo : {min_corredera} mts, limite maximo {max_corredera}')
print(f'El nombre en la simulacion de la junta prismatica del efector final debe ser "{nombre_junta_efector}"", limite minimo : {min_efector} mts, limite maximo {max_efector}')
print(f'El nombre en la simulacion del dummy para obtner posciones finales como comprobacion es "{dummy_posicion}"')
#Manejadores de juntas revolutas

# Obtenemos el manejador de las juntas (joints), y se asignaran a una variable
returnCode,junta_1 = sim.simxGetObjectHandle(clientID,nombre_junta_eslabon_1,sim.simx_opmode_blocking)
returnCode,junta_2 = sim.simxGetObjectHandle(clientID,nombre_junta_eslabon_2,sim.simx_opmode_blocking)
#Imprimimos los id de cada junta
print(f"EL ID de junta_1 = {junta_1}, el ID de junta_2 = {junta_2}")


#Manejadores de juntas prismaticas

#Obtenemos el manejador de la corredera que se coloca en la base
returnCode,corredera = sim.simxGetObjectHandle(clientID,nombre_junta_corredera,sim.simx_opmode_blocking)
#Obtenemos el manejador del efector final
returnCode,efector_cilindro = sim.simxGetObjectHandle(clientID,nombre_junta_efector,sim.simx_opmode_blocking)
#Imprimimos el id de cada junta
print(f"El ID de corredera es = {corredera}, el ID del efector final es {efector_cilindro}")


#Manejador del dummy, que funciona para comprobar la posicion final del efector final.

returnCode,posicion_dummy = sim.simxGetObjectHandle(clientID,dummy_posicion,sim.simx_opmode_blocking)
#Imprimimos el id 
print(f"El ID del dummy es = {posicion_dummy}")<jupyter_output>EL ID de junta_1 = 17, el ID de junta_2 = 18
El ID de corredera es = 16, el ID del efector final es 28
El ID del dummy es = 29<jupyter_text>Posicionamiento en el simuladorFunciones y demostraciones sobre el como se realiza la simulacion sin entrar en detalles de cinematica aun.Son las funciones necesarias para modificar en la simulacion posiciones.<jupyter_code>#la posicion para juntas revolutas se asignara mediante grados 
#Los angulos deben enviarse en radianes, dado que se trabaja con grados se usara la expresion de la manera siguiente
# angulo_en_radianes = angulo_en_grados * pi / 180

angulo_1 = 0 * np.pi/180  #El angulo convertido a radianes para la junta 1.
angulo_2 = 0* np.pi/180 #El angulo convertido a radianes para la junta 2.

retCode = sim.simxSetJointTargetPosition(clientID, junta_1, angulo_1, sim.simx_opmode_oneshot)
retCode = sim.simxSetJointTargetPosition(clientID, junta_2, angulo_2, sim.simx_opmode_oneshot)

#La posicion para juntas prismaticas se asignara representada en distancia.
#La distancia debe ser representada entre [pos.min] y [pos.range] , ambos parametros que se han definido en la simulacion, 
#asignados al elemento (joint) corredera.

#Dado que se debe encontrar expresado en Metros la ecuacion sera la siguiente
#distancia_en_metros = distancia / 100
#Para esta configuracion distancia debe ir de 'min_corredera' hasta 'max_corredera' en el caso de la corredera
distancia = 0
#Para esta configuracion distancia debe ir de 'min_efector' hasta 'max_efector' en el caso del efector final
distancia_efector = -0.040 

retCode = sim.simxSetJointTargetPosition(clientID, corredera,distancia, sim.simx_opmode_oneshot)
retCode = sim.simxSetJointTargetPosition(clientID, efector_cilindro,distancia_efector, sim.simx_opmode_oneshot)
print(retCode)<jupyter_output>1<jupyter_text>Dadas las observaciones anteriores se escribieron dos metodos para ahorrar escritura y simplificar la implementacion<jupyter_code>def mover_junta_revoluta(junta,angulo):
    """
    Esta funcion permite realizar una rotacion en la junta revoluta desde el angulo actual hasta el deseado (grados)
    """
    radianes = angulo * np.pi/180
    
    #Regresa 0 si se ejecuta correctamente
    return sim.simxSetJointTargetPosition(clientID, junta, radianes, sim.simx_opmode_oneshot) 

#Ejemplo de como se usa este metodo
# mover_junta_revoluta(junta_1,-90)
# mover_junta_revoluta(junta_2,90)

def mover_junta_prismatica(junta,distancia_desde_origen):
    """
    Esta funcion permite realizar un dezplazamiento en la junta prismatica (debe estar expresada en centimetros)
    en un rango entre [Pos Min - Pos Range] de la junta prismatica en cuestion
    """
    
    distancia = distancia_desde_origen
    #Regresa 0 si se ejecuta correctamente
    return sim.simxSetJointTargetPosition(clientID, junta,distancia, sim.simx_opmode_oneshot)

#Ejemplo de como se usa este metodo
# mover_junta_prismatica(corredera,0.2)
# mover_junta_prismatica(efector_cilindro,0.04)

def get_posicion_dummy():
    return sim.simxGetObjectPosition(clientID,posicion_dummy,-1,sim.simx_opmode_streaming);

#get_posicion_dummy()<jupyter_output><empty_output><jupyter_text>Algunas utilidades realizadas para facilitar la escritura de posiciones comunes<jupyter_code>def abajo_corredera():
    """
    Envia la corredera a su posicion minima, en el eje Z.
    """
    mover_junta_prismatica(corredera,min_corredera)

def arriba_corredera():
    """
    Envia la corredera a su posicion maxima, en el eje Z.
    """
    mover_junta_prismatica(corredera,max_corredera)

def abrir_efector():
    """
    activa el efector , es decir lo baja.
    """
    mover_junta_prismatica(efector_cilindro,min_efector)

def cerrar_efector():
    """
    desactiva el efector , es decir lo sube. 
    """
    mover_junta_prismatica(efector_cilindro,max_efector)


def reiniciar_robot():
    """
    Deja el robot en su posicion inicial 
    """
    cerrar_efector()
    abajo_corredera()
    mover_junta_revoluta(junta_1,0)
    mover_junta_revoluta(junta_2,0)

def mover_robot_cinematica_directa(angulo_eslabon_1,angulo_eslabon_2,posicion_corredera,posicion_efector,):
    """
    Este metodo se basa en los metodos que se tocan mas adelante en este documento/codigo, donde obtenidas las ecuaciones de 
    cinematica directa de consigue obtener una posicion en el efector final, mediante la posicion de todos los grados de libertad. 
    """
    #Mover juntas prismaticas
    mover_junta_prismatica(corredera,posicion_corredera)
    mover_junta_prismatica(efector_cilindro,posicion_efector)
    #Mover juntas revolutas
    mover_junta_revoluta(junta_1,angulo_eslabon_1)
    mover_junta_revoluta(junta_2,angulo_eslabon_2)<jupyter_output><empty_output><jupyter_text>Seccion 2.- Obtencion de modelo cinematico directo, ecuaciones y funciones.  Cinematica directa del modelo por D-HSe realiza un algoritmo de Denavit-Hartenberg para resolver el modelo cinematico directo del robot.  1.- Librerias utilizadas para calculos simbolicos<jupyter_code># importamos las librerías necesarias
import sim          # librería para conectar con CoppeliaSim
import sympy as sp  # librería para cálculo simbólico
import numpy as np

from sympy.physics.vector import init_vprinting
init_vprinting(use_latex='mathjax', pretty_print=False)
from sympy.physics.mechanics import dynamicsymbols<jupyter_output><empty_output><jupyter_text>2.- Variables simbolicas<jupyter_code>#Variables simbolicas para la obtencion de la matriz DH
theta, alpha, a, d = dynamicsymbols('theta alpha a d')
#Imprimimos las variables
theta, alpha, a, d<jupyter_output><empty_output><jupyter_text>3.- Matrices de rotacion y obtencion de matriz D-H<jupyter_code>#Definimos las matrices de rotacion y traslacion correspondientes

#Rotacion en Z
rz = sp.Matrix([[sp.cos(theta),-sp.sin(theta),0,0],
               [sp.sin(theta),sp.cos(theta),0,0],
               [0,0,1,0],
               [0,0,0,1]])

#Traslacion en Z
tz = sp.Matrix([[1,0,0,0],
               [0,1,0,0],
               [0,0,1,d],
               [0,0,0,1]])

#Traslacion en X
tx = sp.Matrix([[1,0,0,a],
               [0,1,0,0],
               [0,0,1,0],
               [0,0,0,1]])

#Rotacion en X
rx = sp.Matrix([[1,0,0,0],
               [0,sp.cos(alpha),-sp.sin(alpha),0],
               [0,sp.sin(alpha),sp.cos(alpha),0],
               [0,0,0,1]])

#Matriz de rotacion de parametros D-H
DH = rz*tz*tx*rx
#Se muestra la matriz A resultado de la operacion anterior
DH<jupyter_output><empty_output><jupyter_text>4.- Agregamos de uno en uno los grados de libertad correspondientes.Se sustituyen la matriz D-H los parametros theta,d,a,alpha.En base a la tabla obtenida por nosotros mismos referente al robot diseñadoDonde :     theta = La rotacion en Z.    d = Desplazamiento en Z.    a = Desplazamiento en X.    alpha = La rotacion en X.<jupyter_code>#Variables simbolicas para sustituir en la matriz homogenea (DH)
l1,d1, theta2, d2, theta3, d3, l4 = dynamicsymbols('l1 d1 theta2 d2 theta3 d3 l4')
#Imprimimos las variables
l1,d1, theta2, d2, theta3, d3, l4<jupyter_output><empty_output><jupyter_text>De estas variables se obserba lo siguiente :     l1 = La distancia que recorre la corredera en el eje Z.     theta2 = La rotacion en el eje Z que realiza el eslabon 1.     d2 = El desplazamiento en X que recorre el eslabon 1.     theta3 = La rotacion en el eje Z que realiza el eslabon 2.     d3 = El desplazamiento en X que recorre el eslabon 2.     l4 = La distancia que recorre el efector final en el eje Z.   Eslabon corredera<jupyter_code>rot_corredera = DH.subs({theta:0, d:l1, a:d1, alpha:0 })
#imprimimos la matriz
rot_corredera<jupyter_output><empty_output><jupyter_text>Eslabon 1<jupyter_code>rot_eslabon1 = DH.subs({theta:theta2, d:0, a:d2, alpha:0 })
#imprimimos la matriz
rot_eslabon1<jupyter_output><empty_output><jupyter_text>Eslabon 2<jupyter_code>rot_eslabon2 = DH.subs({theta:theta3, d:0, a:d3, alpha:0 })
#imprimimos la matriz
rot_eslabon2<jupyter_output><empty_output><jupyter_text>Efector final<jupyter_code>rot_efector = DH.subs({theta:0, d:l4, a:0, alpha:0 })
#imprimimos la matriz
rot_efector<jupyter_output><empty_output><jupyter_text>Obtencion de matriz homogenea y simplificacion<jupyter_code>matriz_homogenea_resultado = (rot_corredera * rot_eslabon1 * rot_eslabon2 * rot_efector)

#Imprimimos la matriz final resultado de la ecuacion anterior
T = matriz_homogenea_resultado
matriz_homogenea_resultado
matriz_homogenea_simplificada = sp.Matrix([[T[0,0].simplify(), T[0,1].simplify(), T[0,2].simplify(),T[0,3].simplify()],
                 [T[1,0].simplify(), T[1,1].simplify(), T[1,2].simplify(),T[1,3].simplify()],
                 [T[2,0].simplify(), T[2,1].simplify(), T[2,2].simplify(),T[2,3].simplify()],
                 [T[3,0].simplify(), T[3,1].simplify(), T[3,2].simplify(),T[3,3].simplify()]])

#Imprimimos la matriz ya simplificada 
matriz_homogenea_simplificada<jupyter_output><empty_output><jupyter_text>5.- Obtener las ecuaciones de CinematicaDe la matriz obtenida por <NAME> (D-H), se obtienen las ecuaciones para cinematrica Directa.<jupyter_code>#Dado que la ultima columna representa el posicionamiento del robot obtenemos dicho vector
posiciones = matriz_homogenea_simplificada[0:3,3] #Vector de posiciones 4 columna de la matriz homogenea

#Ecuaciones de posicion x,y,z
pos_x = posiciones[0]
pos_y = posiciones[1]
pos_z = posiciones[2]

#Imprimimos el vector de posiciones
posiciones<jupyter_output><empty_output><jupyter_text>De estas ecuaciones de posicion se desprenden las siguientes funciones para obtener su pocision dados los parametros deseados.<jupyter_code>#dado que el desplazamiento en X para ambos eslabones es fijo, pues depende de la longitud como tal del eslabon.
d_1 = (125  + 63.01) / 1000 # 125 mm + 63.01 mm , representan el ajusto de desplazamiento en X sobre la corredera.
d_2 = 200 / 1000 #206 mm
d_3 = 200 / 1000 #206 mm

#Funciones de cinematica directa del mecanismo
def get_posicion_x(angulo_eslabon_1,angulo_eslabon_2):
    """
    Resuelve la ecuacion de posicion en el eje x, y regresa su resultado.
    """
    return  pos_x.subs({d1 : d_1, d2: d_2 , d3: d_3,  theta2 : angulo_eslabon_1, theta3 : angulo_eslabon_2})

def get_posicion_y(angulo_eslabon_1,angulo_eslabon_2):
    """
    Resuelve la ecuacion de posicion en el eje y, y regresa su resultado.
    """
    return  pos_y.subs({d2: d_2 , d3: d_3,  theta2 : angulo_eslabon_1, theta3 : angulo_eslabon_2})

def get_posicion_z(desplazamiento_corredera, desplazamiento_efector_final):
    """
    Resuelve la ecuacion de posicion en el eje z, y regresa su resultado.
    """
    #Dada la simplicidad de la ecuacion de posicion en Z , se reajusta con una distancia producto de los ensambles no contemplados anteriormente.
    ajuste_z = pos_z.subs({l1 : desplazamiento_corredera, l4 : desplazamiento_efector_final}) + 0.1196 #ajuste en mm, 1.196 * 10 a la -1
    return  ajuste_z

def get_posicion_cinematica_directa(angulo_eslabon_1,angulo_eslabon_2,desplazamiento_corredera,desplazamiento_efector_final):
    """
    Regresa el vector posicion x,y,z. Este vector representa los resultados de los calculos matematicos, son una aproximacion
    al valor que deberia tener la punta final del efector final.
    
    """
    vector_posicion_final = sp.Matrix([[get_posicion_x(angulo_eslabon_1,angulo_eslabon_2)],
                                      [get_posicion_y(angulo_eslabon_1,angulo_eslabon_2)],
                                      [get_posicion_z(desplazamiento_corredera,desplazamiento_efector_final)]])
    return vector_posicion_final<jupyter_output><empty_output><jupyter_text>6.- Obtener el espacio del robot.Evaluaremos la posicion numerica de nuestro robot, dadas las ecuaciones de cinematica directa.<jupyter_code>import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
d2r = np.deg2rad

#Se evaluaran las funciones de posicion con sus respectivas variables

fx = sp.lambdify((d1, d2, d3, theta2, theta3), pos_x, 'numpy')
fy = sp.lambdify((d2, d3, theta2, theta3), pos_y, 'numpy')
fz = sp.lambdify((l1,l4), pos_z, 'numpy')


#Definimos las muestras de nuestro espacio, estan en este caso basadas en los GDL del robot

theta2s = np.linspace(d2r(-90), d2r(90)) # desired range of motion for joint 1
theta3s = np.linspace(d2r(-90), d2r(90)) # desired range of motion for joint 2
l1s = np.linspace(0, 0.3) # desired range of motion for joint 2
l4s = np.linspace(-0.04,0) # desired range of motion for joint 2

zx = np.array(fx(d_1,d_2,d_3, theta2s, theta3s))
zy = np.array(fy(d_2, d_3, theta2s, theta3s))
zz = np.array(fz(l1s,l4s))

zz = zz + 0.1196 #ajustamos el valor de z


fig, ax1 = plt.subplots()
ax1.set_title('Posiciones en X')
ax1.plot(np.rad2deg(theta1s), zx, label = r'$p_x$')
ax1.set_xlabel(r'($\theta_2$, $\theta_3$) [deg]')
ax1.set_ylabel(r' posicion en x [mm]')
plt.legend()
plt.grid()

fig, ax2 = plt.subplots()
ax2.set_title('Posiciones en Y')
ax2.plot(np.rad2deg(theta2s), zy, label = r'$p_y$')
ax2.set_xlabel(r'($\theta_1$, $\theta_2$) [deg]')
ax2.set_ylabel(r' posicion en y [mm]')
plt.legend()
plt.grid()

fig, ax3 = plt.subplots()
ax3.set_title('Posiciones en Z')
ax3.plot(l1s, zz, label = r'$p_z$')
ax3.set_xlabel(r'($\l_1$, $\l_4$) [mm]')
ax3.set_ylabel(r' posicion en z [mm]')
plt.legend()
plt.grid()<jupyter_output><empty_output><jupyter_text>Seccion 3.-  Ejecutando la primera simulacion y calculo de error.Una vez conseguidas las ecuaciones correspondientes, los metodos y funciones necesarias para generar un movimiento controladp en el robot se ejecuta el siguiente codigo.Se colocara al robot en una posicion mediante los metodos explicados en la seccion 1.Posterior a eso se calculara con los mismos angulos y traslaciones indicadas la posicion final que deberia tener en teoria nuestro modelo robotico basados en los metodos de la seccion 2.Para ello debemos considerar: A1 = Al angulo que tomara el eslabon 1.A2 = Al angulo que tomara el eslabon 2.LC = Dezplazamiento que tomara la corredera en el eje Z.LF = Dezplazamiento que tomara el efector final en el eje Z.<jupyter_code># Conectamos con CoppeliaSim
clientID = connect(19999)

#Variables para simulacion y calculos

A1 = 90 #Grados , eslabon 1.
A2 = 45#Grados, eslabon 2.
LC = 0.3 # mm, movimiento en z, corredera.
LF = -0.04 # mm, movimiento en z, efector final.

#ejecutamos en la simulacion un movimiento
mover_robot_cinematica_directa(A1,A2,LC,LF)
#Calculamos por cinematica directa la posicion del efector final 
pos_cinematica_directa = get_posicion_cinematica_directa(A1,A2,LC,LF)
pos_cinematica_directa = pos_cinematica_directa.transpose() # posicion calculada para [x,y,z] respectivamente
pos_cinematica_directa<jupyter_output>conectado a 19999<jupyter_text>Una vez llegado al punto deseado obtenemos la posicion del dummy para comprobar que los calculos esten correctos<jupyter_code>#Obtenemos la posicion real del efector fin en la simulacion, del dummy , [x,y,z] respectivamente
pos_sim = get_posicion_dummy()
pos_sim = pos_sim[1]
pos_sim<jupyter_output><empty_output><jupyter_text>Calculamos el error entre el valor calculado y el valor real en la simulacion<jupyter_code>#Se calcula el error absoluto
error_x = abs(pos_sim[0] - pos_cinematica_directa[0]) # error en mm respecto del valor calculado
error_y = abs(pos_sim[1] - pos_cinematica_directa[1]) # error en mm respecto del valor calculado
error_z = abs(pos_sim[2] - pos_cinematica_directa[2]) # error en mm respecto del valor calculado
print(f'Error absoluto en X : {error_x}')
print(f'Error absoluto en Y : {error_y}')
print(f'Error absoluto en Z : {error_z}')

#Se calcula el error relativo
error_x = (error_x / pos_sim[0] )* 100
error_y = (error_y / pos_sim[0] )* 100
error_z = (error_z / pos_sim[0] )* 100

print(f'Error del valor calculado con respecto al real en X, es de : {error_x} %')
print(f'Error del valor calculado con respecto al real en Y, es de : {error_y} %')
print(f'Error del valor calculado con respecto al real en Z, es de : {error_z} %')<jupyter_output>Error absoluto en X : -0.18801 - 0.2*cos(90) - 0.2*cos(135)
Error absoluto en Y : 0.2*sin(135) + 0.2*sin(90)
Error absoluto en Z : 0.379600000000000
Error del valor calculado con respecto al real en X, es de : zoo %
Error del valor calculado con respecto al real en Y, es de : zoo %
Error del valor calculado con respecto al real en Z, es de : zoo %<jupyter_text>Seccion 4 .- Simulaciones de muestra<jupyter_code>import time

def delay(tiempo_en_segundos):
    """
    Hace un retardo antes de seguir ejecutando el programa
    """
    time.sleep(tiempo_en_segundos)   # Delays for 5 seconds. You can also use a float value.<jupyter_output><empty_output><jupyter_text>Simulacion 1.- Juego de coordenadas preestablecidas, eslabones 1 y 2 en plano XY<jupyter_code># Conectamos a coppelia
clientID = connect(19999)

#Esta rutina mueve en zigzag el eslabon 2 , sobre la junta con eslabon 1
def mover_eslabon_2_sobre_junta(angulo_eslabon_1):
    #Movemos el robot con eslabon 1 : 90 °, eslabon 2 : -90 °, Corredera eleada hasta : 0 mm , Posicion de efector final :0 mm
    mover_robot_cinematica_directa(angulo_eslabon_1,-90,0,0)
    #Espera segundos antes del proximo movimiento
    delay(1)
    mover_robot_cinematica_directa(angulo_eslabon_1,90,0,0)
    #Espera segundos antes del proximo movimiento
    delay(1)
    mover_robot_cinematica_directa(angulo_eslabon_1,-90,0,0)
    #Espera segundos antes del proximo movimiento
    delay(1)
    mover_robot_cinematica_directa(angulo_eslabon_1,90,0,0)
    #Espera segundos antes del proximo movimiento
    delay(1)
    
#Inicia la rutina.
def rutina_1():
    #Movemos el robot con eslabon 1 : 90 °, eslabon 2 : 0 °, Corredera eleada hasta : 0 mm , Posicion de efector final :0 mm
    mover_robot_cinematica_directa(90,0,0,0)
    #Espera 2 segundos antes del proximo movimiento
    delay(2)
    #Rutina pre diseñada
    mover_eslabon_2_sobre_junta(90)



    #Movemos el robot con eslabon 1 : -90 °, eslabon 2 : 0 °, Corredera eleada hasta : 0 mm , Posicion de efector final :0 mm
    mover_robot_cinematica_directa(-90,0,0,0)
    #Espera 2 segundos antes del proximo movimiento
    delay(2)
    #Rutina pre diseñada
    mover_eslabon_2_sobre_junta(-90)


    #Movemos el robot con eslabon 1 : -90 °, eslabon 2 : 0 °, Corredera eleada hasta : 0 mm , Posicion de efector final :0 mm
    mover_robot_cinematica_directa(0,0,0,0)
    #Espera 2 segundos antes del proximo movimiento
    delay(2)
    #Rutina pre diseñada
    mover_eslabon_2_sobre_junta(0)

    #Regresamos el robot a su posicion inicial, por defecto
    delay(1)
    reiniciar_robot()
    

rutina_1()<jupyter_output><empty_output><jupyter_text>Simulacion 2.- Plano XY agregar movimiento en ZSe realiza un dezplazamiento en Z, a la par que se realiza la rutina 1<jupyter_code># Conectamos a coppelia
clientID = connect(19999)

arriba_corredera()
delay(5)
abajo_corredera()
rutina_1()
arriba_corredera()
delay(5)<jupyter_output><empty_output><jupyter_text>Simulacion 3.- 'Boxeador'Se realiza un dezplazamiento en Z, a la par que se realiza una rutina diferente<jupyter_code># Conectamos a coppelia
clientID = connect(19999)

#Sube hasta lo mas alto la corredera
arriba_corredera()
delay(10)

#Rutina 'Boxeo'
i = 0
while i < 10 :
    mover_robot_cinematica_directa(-90,90,0,0)
    delay(0.8)
    mover_robot_cinematica_directa(90,-90,0,0)
    delay(0.8)
    i = i + 1<jupyter_output>conectado a 19999
{'fraction_non_alphanumeric': 0.08365415463586783, 'fraction_numerical': 0.02783124799486686, 'mean_word_length': 4.96578947368421, 'pattern_counts': {'":': 0, '<': 104, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '26', 'dir': 'jupyter-structured-clean-dedup', 'id': '452217', 'license': 'MIT', 'n_tokens_mistral': 9771, 'n_tokens_neox': 9357, 'n_words': 2653, 'path': 'Simulacion_Deskbot.ipynb', 'repo_name': 'alfredoaguiararce/Deskbot', 'size': '24983'}