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.

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.

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.

  • Use servos or DC motors with encoders for the arm movement so it can be controlled the position of in space.

  • Leave space between the arm and the other components such as controllers and power source.

  • A good counterweight for a minor torque in the end effector gripper.

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.

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.

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.

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 WEBCAM or a 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 wilberahr@hotmail.com

Thanks to Manuel Barboza mbarboza@hotmail.es and Fernán Urgellés ferurge@hotmail.com for helping in the the build of the arm and its supporting frame.

  • tutorials/robotic_arm_controlled_from_computer_using_nxt-python.txt
  • Last modified: 2016/03/07 09:26
  • by amora