====== Computer Controlled Robotic Arm Using Nxt-Python ====== ===== Introduction ===== In this project it was implemented a control interface using the NXT-Python library for connecting to a robotic system. For the development of this program it was build a model robot controlled with HiTechnic Servo and Motor controllers from the TETRIX educational kit for robotics. Using the Nxt-Python library permits the development of a more robust software control for a robot, for example the capability recognition of patterns and movement of the robot by detecting points in space. ===== Objectives ===== * Build a robotic arm for model to develop the software needed to interact with it. * Achieve the connection with the computer and the HiTechnic Servo and Motor Controllers. * Develop a control program for managing the movement of the robotic arm and its functions. ===== Tutorial ===== ==== Building of the Robotic Arm and its Platform ==== It was needed for the project to build a robotic arm to make the testing on it. In this case, it was used the TETRIX educational kit for robotics for the frame and arm construction. {{:img_1578.jpg?300|}} {{:img_1544.jpg?300|}} Changes were made to the original design because of excess weight in the arm. Also, a circuit was implemented to solve a bug fix in the code that does not allowed the HiTechnic Motor Controller to change the polarity in the grapper motor. {{:img_1569.jpg?300|}} For the design using this components may be followed the next recommended specifications: * A place for the HiTechnic controllers and the NXT brick from the LEGO Mindstorms kit. {{:img_1545.jpg?300|}} * Use servos or DC motors with encoders for the arm movement so it can be controlled the position of in space. {{:img_1576.jpg?300|}} * Leave space between the arm and the other components such as controllers and power source. {{:img_1546.jpg?300|}} * A good counterweight for a minor torque in the end effector gripper. {{:img_1577.jpg?300|}} **Important:** Be sure all connections with the controllers and the servos and motors are properly placed. A bad connection can cause severe damage to the hardware or to people around. {{:img_1572.jpg?300|}} {{:img_1573.jpg?300|}} {{:img_1574.jpg?300|}} Be sure also the battery is fully charged when you are going to use the arm and also first test all components separately to discard malfunction. {{:img_1586.jpg?300|}} Note: The NXT communicates with intelligent sensors via either a I2C or RS-485 bus, while it connects to the computer via USB. The HiTechnic Servo and Motor controller are connected to the ports of the NXT using the cables build for the brick and come along with the TETRIX or LEGO Mindstorms kit. {{:img_1571.jpg?300|}} {{:img_1575.jpg?300|}} ==== The Code: Nxt-Python and Implementation ==== To use the nxt-python library you must install the following dependency sudo apt-get install python-nxt There is a bug fix that must be made on /usr/lib/python2.7/dist-packages/nxt/sensor/hitechnic.py the pwm value of the sensor class: class ServoCon(BaseDigitalSensor): """Object for HiTechnic FIRST Servo Controllers. Coded to HiTechnic's specs for the sensor but not tested. Please report whether this worked for you or not!""" I2C_ADDRESS = BaseDigitalSensor.I2C_ADDRESS.copy() I2C_ADDRESS.update({ 'status': (0x40, 'B'), 'steptime': (0x41, 'B'), 's1pos': (0x42, 'B'), 's2pos': (0x43, 'B'), 's3pos': (0x44, 'B'), 'p4pos': (0x45, 'B'), 'p5pos': (0x46, 'B'), 'p6pos': (0x47, 'B'), 'pwm': (0x48, 'B'), #Originally it was 0x46 }) For controlling the arm, the script below was made for commanding the funcions of the servos and motors #!/usr/bin/env python import nxt.locator from nxt.motor import * from nxt.sensor.hitechnic import * from nxt import error #Connects to the nxt brick b = nxt.locator.find_one_brick() class Arm: #name = 'Brazo Robotico Cognitive Factory' def __init__ (self, name): self.name = name #The prinicpal menu for the arm operation def operate_arm(self): b2 = True while(b2): operation = raw_input('\nMenu Principal: \nQue desea realizar: \n(a-Agarrar objeto, b-Mover brazo, c-Soltar objeto, d-Salir): ') if (operation == 'a'): self.get_object() else: if(operation == 'b'): self.move_object() else: if(operation == 'c'): self.release_object() else: if(operation == 'd'): print('Hasta luego') b2 = False def get_object (self): b1 = True while(b1): try: instruction =raw_input('\nDesea que agarre el objeto? (y/n): ') if(instruction =='y'): self.close_motor_gripper() b1 = False else: if(instruction == 'n'): #self.open_motor_gripper() b1= False else: print('Dato invalido') except error.I2CError: print 'Ha ocurrido un error vuelva a ingresar su comando \n' b1 = True #User movement controll of the arm: up, down, right and left def move_object (self): b1 = True while(b1): instruction =raw_input('\nHacia donde desea mover el objeto? \n(izquierda, derecha, arriba, abajo) \nEscriba Salir para volver al Menu Principal: ') if(instruction == 'izquierda'): self.move_arm_left() else: if(instruction == 'derecha'): self.move_arm_right() else: if(instruction == 'arriba'): self.move_arm_up() else: if(instruction == 'abajo'): self.move_arm_down() else: if(instruction == 'Salir'): b1 = False else: print('Dato invalido') #Prompts the user to release the object def release_object (self): self.move_arm_down() #The arm is moved to the lower position to release the object b1 = True while(b1): try: instruction =raw_input('Desea soltar el objeto? (y/n) ') #Prompts the user to leave the object or not if(instruction =='y'): self.open_motor_gripper() #Opens the grap b1 = False else: if(instruction == 'n'): b1= False else: print('Dato invalido') except error.I2CError: #when running sometimes the conection with the robot fails and produce this error, the loop prevents from terminating the program print 'Ha ocurrido un error vuelva a ingresar su comando' b1 = True #Closes the gripper def close_motor_gripper (self): close_motor=MotorCon(b, PORT_1) cur2= close_motor.get_enc_current(1) print cur2 close_motor.set_power(2,9) #Opens the gripper def open_motor_gripper (self): open_motor=MotorCon(b, PORT_1) cur1 = open_motor.get_enc_current(1) print cur1 #should be 0 if the motor hasn't moved since being powered on open_motor.set_power(1,9) #At 1-100% power #Moves the arm to the left def move_arm_left (self): servo1=ServoCon(b, PORT_2) print servo1.get_status() print servo1.get_pwm() servo1.set_pwm(170) servo1.set_step_time(8) servo1.set_pos(1,225) #Moves the arm to the right def move_arm_right (self): servo1=ServoCon(b, PORT_2) print servo1.get_status() print servo1.get_pwm() servo1.set_pwm(170) servo1.set_step_time(8) servo1.set_pos(1,0) #servo2 data for the arm build: #min pos = 100, max = 225 #min pos = 120, max = 225 #Moves the arm to the minimun position def move_arm_down (self): servo2=ServoCon(b, PORT_2) print servo2.get_status() print servo2.get_pwm() servo2.set_pwm(170) servo2.set_step_time(8) servo2.set_pos(2,225) #Moves the arm to the maxinum position def move_arm_up (self): servo2=ServoCon(b, PORT_2) print servo2.get_status() print servo2.get_pwm() servo2.set_pwm(170) servo2.set_step_time(8) servo2.set_pos(2,130) #Initialize the arm to operate print '\nInicializando operacion del brazo:' a = Arm('Cognitive Factory arm01') print(a.name) a.operate_arm() ==== Aplications: Inverse Kinematics ==== The implementation of python for connection and control of the servos and motors in a robot permits the usage of other resources for a more complex and cognitive response of the system. For example, a model used for robot controlling is inverse kinematics. By obtaining the position of an object in space, by inverse kinematics it can be ordered to change the position of the servos on its joints until the end effector reaches the position previosly detected. There is a library use for applying this technic called Orocos KDL cd ~/home/user/local/src/ mkdir orocos_kinematics_dynamics git clone http://git.mech.kuleuven.be/robotics/orocos_kinematics_dynamics.git cd ~/home/user/local/src/orocos_kinematics_dynamics/orocos_kdl mkdir build cd build ccmake ../ #Configure the INSTALL_PREFIX to /home/user/local/DIR/orocos_kdl, must also turn off all options related to bindings with ROS make -j2 make install Must be also installed the python bindings for Orocos KDL cd ~/home/user/local/src/orocos_kinematics_dynamics/python_orocos_kdl mkdir build cd build ccmake ../ #Configure the INSTALL_PREFIX to /home/user/local/DIR/python_orocos_kdl #Configure PYTHON_SITE_PACKAGES_INSTALL_D to /home/wilberahr/local/DIR/python_orocos_kdl/lib/python2.7/site-packages make -j2 make install Now you can use the package to program in Python scripts with kinematic functions. For examples of how to use this library: [[http://www.orocos.org/kdl/examples]] Program that can be used for detecting objects in space are ROS using a [[teaching:ie0117:proyectos:2012:i:webcam|WEBCAM]] or a [[teaching:ie0117:proyectos:2012:i:linux:deteccion_de_markers_con_ar_kinect_ros:el_paso_a_paso_en_la_realizacion|Kinect]] ===== Results ===== After building the robotic arm and its platform it successfully functions with the NXT-Python library and the code written for its control. Further changes where made to ensure the running of the program handling errors in the NXT-Python script. The script used for controlling the movement and the functions of the arm can be modified for the user to control the input values of servo position from a program that detects the points in space for the arm to reach. ===== Conslusion ===== A robotic arm for model was built to develop the software and implementing the nxt-python library. The connection between the computer and the NXT brick was achived and also the conncetion with the Hitechnic Servo and Motor Controllers. The control program developed for managing the movement of the robotic arm and its functions successfully runs and can be modified for more complex programming. Author: Wilber Hernandez Ruiz Thanks to Manuel Barboza and Fernán Urgellés for helping in the the build of the arm and its supporting frame.