LABORATORIO 4 DE ROBÓTICA
VIDEO DEMOSTRACIÓN DEL LABORATORIO
Gráfica digital de las poses comparándola con la fotografía del brazo real en la misma configuración.
A continuación se presentan las configuraciones del robot de forma digital y en el robot real:
La pose de HOME corresponde a la pose donde todas las articulaciones están en 0.
La pose de 1 corresponde a 25, 25, 20, -20, 0.
La pose de 2 corresponde a -35,35, -30, 30, 0.
La pose de 3 corresponde a 85, -20, 55, 25, 0.
La pose de 4 corresponde a 80, -35, 55, -45, 0.
En el script LAB4.py primero se establecen los torques adecuados para cada motor. Estos valores se obtuvieron empíricamente probando los movimientos con el robot para que estos fueran suaves y no generaran tanta vibración, pero sin que pierdan la fuerza para mantener los demás eslabones.
# Definición de torques máximos para cada motor
torques = [500, 400, 350, 350, 350]
La siguiente función es una de las más relevantes en la solución:
# Función para enviar comandos a los motores Dynamixel
def send_joint_command(command, id_num, addr_name, value, delay):
rospy.wait_for_service('dynamixel_workbench/dynamixel_command')
try:
dynamixel_command = rospy.ServiceProxy('/dynamixel_workbench/dynamixel_command', DynamixelCommand)
result = dynamixel_command(command, id_num, addr_name, value)
rospy.sleep(delay)
return result.comm_result
except rospy.ServiceException as exc:
print(str(exc))
Esta función primero espera al servicio de dynamixel_command para crear un comando para los motores Dynamixel. Los parámetros que espera son:
command
: En el código se usa '' porque no se llaman instrucciones de la tabla de control como ping, reboot o reset.id
: El númeor de ID del motor a mover.addr_name
: Puede ser Torque_Limit, Goal_Position o Present_Position dependiendo del objetivo de la instrucción.value
: Valor a escribir en la instrucción.delay
: Tiempo de espera en segundos antes de ejecutar la siguiente instrucción. La función devuelve el booleano comm_result que indica si la comunicación fue exitosa. Esta función es importante ya que es la base del movimiento del robot y se usa en varias partes del código. Primero se usa para llevar el robot a su posición de HOME y también para establecer los torques en cada motor, pasando Torque_Limit como addr_name:
# Configurar los límites de torque de los motores
for i, torque in enumerate(torques):
send_joint_command('', i + 1, 'Torque_Limit', torque, 0)
También se usa en la función move_partial, que es la función que se llama en la función principal para llevar cada eslabón del robot a la posición adecuada de a cuerdo a la configuración seleccionada.
# Función para mover gradualmente las articulaciones hacia una posición objetivo
def move_partial(joint_index, goal_position, current_position):
N = 6
delta = (goal_position - current_position) / N
for i in range(N):
send_joint_command('', joint_index + 1, 'Goal_Position', int(current_position + delta * (i + 1)), 0.5)
En este caso mueve cada motor uno a uno con un delta entre la posición requerida y la posición actual para que el movimiento sea se mueva poco a poco y con un delay de 0.5 para que sea gradual. Como N = 6, cada movimiento lo realiza en 6 partes.
Con la función send_joint_command bien definida en su comportamiento y en sus usos, la función principal sigue el siguiente flujo:
flowchart TD
A((INICIO)) --> B[Inicializar el nodo de ROS];
B --> C[Configurar los límites de torque de los motores];
C --> D[Ir a HOME];
D --> E[Seleccionar caso];
E --> F{1}
F --> G{2} & AA(CONFIGURACIÓN 1)
G --> H{3} & AB(CONFIGURACIÓN 2)
H --> I{4} & AC(CONFIGURACIÓN 3)
I --> AD(CONFIGURACIÓN 4)
AA & AB & AC & AD --> J((FIN))