In yesterday’s post Preliminary design review in mechatronics, I contemplated using a single arm to put balls in both targets, with the arm vertical for the higher Ren-ship target and past vertical for the AT-M6 target. I tried doing some calculations with a hand calculator, and it looked like this might work. I then drew out the geometry, labeling all the dimensions, and wrote a program to check the constraints carefully. The program did not accept the values I’d computed by hand, so I did some search in the program and had it report what constraints failed.

Here is a sketch of the geometry:

The program selected the arm length based on the Ren-ship target, then checked that the arm would meet all constraints for both targets.

Unfortunately, an arm long enough to reach the Ren-ship target is too long to hit the AT-M6 target, no matter where I put the pivot. The problem is that AT-M6 target gets very small if the ball is approaching it with the arm almost horizontal, and the inner edge and outer edge of the ball cup can’t both clear the edges of the target.

I simplified the code to check just one target, and I do have a range of pivot positions that would make the arm work for a each target. For the Ren-ship target I’d need to have the pivot at least 4.7″ off the floor in order for the arm to be short enough to fit in the initial box, and 6.5″ off the floor if I want the rest position of the arm to be horizontal (assuming the pivot is 1″ from the edge).

For the AT-M6 target, I’d need the pivot to be at least 2″ off the floor and and no more than 5″ off the floor. The shortest arm would be about 7″ long with the pivot 1″ from the edge and 4″ up, with a separation of 3.8″. The longest arm would be 10.58″ with the pivot 1″ from the edge and 2″ up, with a separation of 6″. The best arm length (giving the most flexibility in position of the pivot and separation) seems to be around 7.5″. I’d have to play around a bit with the computations to take into account other constraints (like interaction with other parts of the robot). I’ll have to build some track-wired detectors, to see if I can get good sensitivity at large separations (which allows sloppier tape following, since I can be further from going out of bounds). If sensitivity of the track-wire detector is low, then I can either try to make the robot follow the tape more precisely and risk going out of bounds, or I can deploy the track-wire detector outside the original 11″ box.

Now that the robot is not going to use a single arm for both targets, the don’t have to face the same direction. The high arm can be on top facing front, and the low arm can be on a lower layer, facing sideways (but there needs to be clearance for the low arm to swing through the higher layers).

Here is the program trying to find a single-arm solution:

#!/usr/bin/env python """ arm-swing.py Fri Nov 10 07:56:41 PST 2017 Kevin Karplus Computations to see whether a single arm can be used for both the AT-M6 and Ren-ship targets for the 2017 Mechatronics course. The arm is A inches long with a D inch deep cup W inches wide (not extending arm) R inches above the floor at rest. The arm pivots X inches from the edge of the robot, Y inches from the floor. The targets are S inches from the edge of the robot L inches from the floor at the bottom of the hole H inches from the floor at the top of the hole Known values: L=6, H=10 for AT-M6 L=13, H=15 for Ren ship Computed values: B to tip of cup: sqrt(A^2+D^2) C to bottom edge of cup: sqrt((A-W)^2+D^2) Constraints: sqrt(A^2 - (R-Y)^2) + X < 11" to fit in initial cube R + (R-Y)D/A < 11" height restriction sqrt(A^2 - (R-Y)^2) + X approx 9" to load balls sqrt((S+X)^2 + (L-Y)^2) <= C (bottom edge clears) sqrt((S+X)^2 + (H-Y)^2) >= B (top edge clears) S for AT-M6: 2"<S<6" (probably around 4") S for Ren ship: 0<=S<=0.3" # mounting space for servo min_mount_X <=X <= 11"-min_mount_X min_mount_Y <=Y <= 11"-min_mount_Y If 1 1/2" Schedule 40 PVC pipe used for cup, then W=1.9" """ from __future__ import division, print_function from math import sqrt from numpy import arange min_mount_X = 0.5 min_mount_Y = 1 def ConstraintsMet(A=7, D=1, W=1.9, R=6, X=2, Y=6, S=0, L=13, H=15, reason=False): """Check all the constraints, returning True is constraints met, False if one fails. if reason, then print the first constraint that fails """ if X<min_mount_X or 11-X<min_mount_X: if reason: print("too close to edge") return False # too close to edge for mounting servo if Y<min_mount_Y: if reason: print("pivot too low") return False # too low to mount servo if Y>11-min_mount_Y: if reason: print("pivot too high") return False # too high to mount servo if S<0: if reason: print("overlap target") return False # edge intersects target rest_above_pivot = R-Y rest_width = sqrt(A**2 - rest_above_pivot**2) if rest_width+X >= 11: if reason: print("too wide") return False # too wide for initial box rest_tip_height = R + rest_above_pivot*D/A # resting height of tip if rest_tip_height >= 11: if reason: print("too tall") return False # too tall for initial box # Note: the ball-loading constraints can be modified by # loading in a different position than the initial rest position if rest_width+X < 8 or rest_width+X>=9.5: if reason: print("loading at {:.2f}".format(rest_width+X)) return False # not enough space for ball loading # distance from pivot to tip of cup tip_to_pivot= sqrt(A**2 + D**2) pivot_to_top = sqrt((S+X)**2 + (H-Y)**2) if tip_to_pivot > pivot_to_top: # print("DEBUG: hits top Y={:.2f}, A={:.2f}, tip_to_pivot={:.2f}, pivot_to_top={:.2f}".format(Y,A,tip_to_pivot,pivot_to_top)) if reason: print("doesn't clear top, tip_to_pivot={:.2f} pivot_to_top={:.2f}".format(tip_to_pivot,pivot_to_top)) return False # doesn't clear top of hole # distance from pivot to inner lip of cup inner_to_pivot= sqrt((A-W)**2 + D**2) pivot_to_bottom = sqrt((S+X)**2 + (L-Y)**2) if inner_to_pivot < pivot_to_bottom: # print("DEBUG: hits bottom Y={:.2f}, A={:.2f}, inner_to_pivot={:.2f}, pivot_to_bottom={:.2f}".format(Y,A,inner_to_pivot,pivot_to_bottom)) if reason: print("doesn't clear bottom inner_to_pivot={:.2f}, pivot_to_bottom={:.2f}".format(inner_to_pivot,pivot_to_bottom)) return False # doesn't clear bottom of hole return True # tops and bottoms of targets H_Ren = 15 L_Ren = 13 H_ATM6 = 10 L_ATM6 = 6 # some fixed values W = 1.9 D = 1 X = 1 # some values to explore for Y in arange(2., 9.05, 0.1): for R in arange(Y, 11.05, 0.1): # set arm length to just clear top of hole when touching Ren ship pivot_to_top = sqrt(X**2+(H_Ren-Y)**2) A_long = sqrt(pivot_to_top**2 - D**2) # set arm length to just clear bottom of hole when touching Ren ship pivot_to_bottom = sqrt(X**2 + (L_Ren-Y)**2) A_short = sqrt(pivot_to_bottom**2 -D**2) + W for A in [A_short, A_long]: if not ConstraintsMet(A=A, D=D, W=W, R=R, X=X, Y=Y, S=0, L=L_Ren, H=H_Ren): continue print ("Y={:.2f} met Ren constraints".format(Y)) for S in arange(2.,6.05, 0.2): if ConstraintsMet(A=A, D=D, W=W, R=R, X=X, Y=Y, S=S, L=L_ATM6, H=H_ATM6, reason=True): print ("X={:.2f}, Y={:.2f}, A={:.2f}, R={:.2f}, SATM6={:.2f}".format(X,Y,A,R,S))

## Leave a Reply