Project 2

Computing

The second project introduced the use of a virtual invironment built by Quanser. The project involved programming a robotic arm to pick up and put down boxes in various locations; since the actual robotic arms are expensive and delicate, the virtual environment allowed you to make mistakes without fear of damaging the equipment. Here was my final code for the task, which was to randomly spawn six boxes of different colours and sizes and then drop them off at a location that depended on the colour and size.

  `ip_address = 'localhost' # Enter your IP Address here
project_identifier = 'P2B' # Enter the project identifier i.e. P2A or P2B
#--------------------------------------------------------------------------------
import sys
sys.path.append('../')
from Common.simulation_project_library import *

hardware = False
QLabs = configure_environment(project_identifier, ip_address, hardware).QLabs
arm = qarm(project_identifier,ip_address,QLabs,hardware)
potentiometer = potentiometer_interface()
#--------------------------------------------------------------------------------
# STUDENT CODE BEGINS
#---------------------------------------------------------------------------------

def pick_up_container(size):
    if size == 'small': #if container is small, close the gripper a larger angle
        angle = 35 #IF YOU CHANGE THESE ANGLES, ALSO CHANGE THEM IN DROP OFF FUNCTION
    else: #if container is large, close the gripper a smaller angle
        angle = 30
    arm.move_arm(0.6, 0.003, 0.02) #trial pickup location-- could use improvement
    time.sleep(2)
    arm.control_gripper(angle)
    time.sleep(2)
    arm.move_arm(0.406, 0.0, 0.483) #this is the home position
    time.sleep(5)    
    
def rotate_qarm_base(colour):        
    positionsuccess = False
    old_reading = 0.5
    while not positionsuccess:       
        new_reading = potentiometer.right()
        delta = new_reading - old_reading
        increment = 348*delta
        arm.rotate_base(increment)
        time.sleep(0.2)
        print(potentiometer.left(),potentiometer.right())
        old_reading = new_reading          
        positionsuccess = arm.check_autoclave(colour)
        if positionsuccess:
            final_reading = arm.effector_position() 
            print("Arm is in position")
            return final_reading
        else:
            print("Arm is not in position") 
        
    
def drop_off_and_return(colour, size, final_reading):
    arm.move_arm(final_reading[0], final_reading[1], final_reading[2]) 
    arm.activate_autoclaves()
    if size == "large":
        arm.open_autoclave(colour)
    else:
        pass
    print("Please move left potentiometer: between 0.5 and 1 for small, all the way to 1 for large.")
    potentiometerused = False
    while not potentiometerused:
        if 0.5 < potentiometer.left() < 1 and size == "small":
            potentiometerused = True
            arm.rotate_elbow(-15)
            arm.rotate_shoulder(35)
            time.sleep(1)
            arm.control_gripper(-35)
            time.sleep(2)
            arm.home()
        elif potentiometer.left() == 1 and size == "large":
            potentiometerused = True
            arm.rotate_elbow(15) 
            arm.rotate_shoulder(30)
            time.sleep(0.5)
            arm.control_gripper(-30)
            time.sleep(2)
            arm.home()
            arm.open_autoclave(colour, False)
        else:
            pass
        
def get_container_info(container): 
    if container  == 3 or container == 6: 
        colour = 'blue'
    elif container == 1 or container == 4:
        colour = 'red'
    else:
        colour = 'green'
    if 1 <= container <= 3: #Containers 1, 2 and 3 are small containers
        size = "small"
    else: #containers 4, 5 and 6 are large containers
        size = "large"
    return [colour, size]
    
                
def main():
    import random
    usedcontainers = [] #starts at length 0, will be populated with used containers
    while len(usedcontainers) < 6: 
        container = random.randint(1,6) #gets a container with a value in the given range
        if container in usedcontainers:
            pass #We want to use each container only once
        elif container not in usedcontainers: 
            arm.spawn_cage(container) 
            usedcontainers.append(container)
            containerinfo = get_container_info(container)
            colour = containerinfo[0]
            size = containerinfo[1]
            pick_up_container(size) #picks up the container 
            final_reading = rotate_qarm_base(colour) 
            time.sleep(0.5)
            drop_off_and_return(colour, size, final_reading)
            time.sleep(0.5)
            time.sleep(0.5)
        else: 
            print("Random value error!")
                      

if __name__ == "__main__":
    main()

#---------------------------------------------------------------------------------
# STUDENT CODE ENDS
#---------------------------------------------------------------------------------` 

Modelling

Although I was tasked with writing the code for the concept, there was also a modelling and 3D printing aspect to the project, the idea being to create a box that the robotic arm could pick up and put down. Unfortunately, because of constraints on the availability of 3D printers, print time had to be kept under 2 hours. Since most large 3D print jobs take much longer than that, the box had to be scaled down until it was, shall we say, very cute. However, getting to use the 3D printers did provide an interesting view of how they work. The first print job failed, with the first few layers of the box looking like this:

After a quick consultation with my spouse, who works at the Makerspace at the public library and helps with the 3D printers (and embroidery machine, and laser cutter, etc– did you know the public library could do all that?), it seemed that there wasn’t a fundamental problem with the design (I had thought at first that there were too many holes in the box, and the filament wasn’t able to trace them accurately.) Instead it was just an adhesion problem, and could be fixed by either trying it again or, to be sure, using a glue stick on the printer plate. The next try was successful: