Robotic Arm

Annalisa DeBari and Raven Fournier

Our robot consists of two motors and beams of length 14 cm and 11 cm (first and second beam respectively).  Challenge 1: Build the arm and demonstrate the range of motion:

Maximum X position: 25 cm

Maximum Y position: 25 cm

Minimum X position: -11.3 cm

Minimum Y position: -25 cm

Challenge 2: Calculate end effector position based on manual movement of arm. Challenge 2 was done to ensure that position of the end effector is being properly tracked by the computer.  The video demonstrates the motion and then shows the position of the end effector, denoted x_b & y_b.

Challenge 3: Create program that records positions and “plays” back.

As the first half of Challenge 3, we wanted to demonstrate that our robotic arm moves rigidly to specific points to be played back.  It can be noted that the sampling and playback rates can be altered for a more accurate playback, but this video demonstrates that the robot successfully moves to the predetermined positions.

For the second half, we wanted to demonstrate that our robotic arm can move and follow fluid motions.  This was done by altering the code slightly.  Depending on the desired application, we know what alterations to make in our code.

Code:

```#!/usr/bin/env python3
ev3 = Device("this")
def manageRange(n):
return max(min(n,1050),-1050)

def main():
import math

# initialize variables
position_1 = None
length1 = None
length2 = None
theta1 = None
theta2 = None
i = 0

# x_a is the x-coordinate of the end of the beam connected to motor 1, and x_b is the    x-coordinate of the end effector
x_a = None
x_b = None
y_a = None
y_b = None

# create vectors to hold the motor location data
theta1_array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
theta2_array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

while True:
# set theta1 to the position of the motor in port b (motor 1)
theta1 = ev3.LargeMotor('outB').position
theta1 = -1 * theta1 # had to multiply by -1 for the math to work out

# store that value into the current location of an array
theta1_array[i] = theta1
theta2 = ev3.LargeMotor('outD').position
theta2 = -1 * theta2
theta2_array[i] = theta2
length1 = 14 # length of first beam
length2 = 11 # length of 2nd beam

# from class we calculated these formulas
x_a = length1 * math.cos(theta1 / 180.0 * math.pi)
y_a = length1 * math.sin(theta1 / 180.0 * math.pi)
print('x_a:' + str(x_a))
print('y_a:' + str(y_a))
print('motor1 position:' + str(theta1))
x_b = x_a + length2 * math.cos((theta1+theta2) / 180.0 * math.pi)
y_b = y_a + length2 * math.sin((theta1+theta2) / 180.0 * math.pi)
print('x_b:' + str(x_b))
print('y_b:' + str(y_b))
print('motor2 position:' + str(theta2))
sleep(1)
i = i+1 # increase the counter variable

# once the code has recorded location 14 times, enter this next portion where it “plays back”
if i >=14:
print('entered if statement')
print('theta1_array:')
print(theta1_array)
print('theta2_array:')
print(theta2_array)
# need another counter variable to access the stored values
j=0
for count in range(14):
print('ENTERED FOR LOOP')
print('j is:' + str(j))
print('motor1 position:')
print(theta1_array[j])
print('motor2 position:')
print(theta2_array[j])
current_posA = theta1_array[j] * -1
current_posB = theta2_array[j] * -1
# needed to keep track of the previous position in order to move to the correct location relative to the original zero location instead of moving relative to its current position
prev_posA = 0
prev_posB = 0
if j >= 1:
prev_posA = theta1_array[j-1] * -1
prev_posB = theta2_array[j-1] * -1
outB = ev3.LargeMotor('outB')
outB.run_to_rel_pos(speed_sp=manageRange(15 * 10.50),position_sp=current_posA - prev_posA, stop_action="hold")
outD = ev3.LargeMotor('outD')
outD.run_to_rel_pos(speed_sp=manageRange(15 * 10.50),position_sp=current_posB - prev_posB, stop_action="hold")
j=j+1
sleep(1)
pass
print('done')
break

if __name__ == '__main__':
main()```

Disclaimer: Our code logic is correct, but since the EV3 motors are not very precise the locations are not always precise either. The mechanical components have weight to them, and the motors can become misaligned with zero fairly easily. There is also a decent amount of “wiggle room” with the motors where you can mechanically move back and forth a couple of millimeters and the motor reads the same position throughout.

Changing the sleep times also changes the rate of collection. So, to collect more fluidly, changing the sleep time to .5 or less allows the code to store the data more rapidly and collect more fluid motion. We also changed the motor command stop_action set to “coast” instead of “hold” to make the motion even more fluid as seen in the second video of challenge 3.