You are on page 1of 14

Gripper Final Technical Memo 

DATE: December 14, 2017 


TO: LeAnn Dourte 
FROM: Jaimie Carlson, Jane Shmushkis 
SUBJECT: BE570 Final Project 
1 Design 
1.1 Circuit 

 
Fig 1. Circuit Diagram. Note: all grounds are connected.  

The two servo motors of the Lynx are powered and grounded via a 6V power supply. Their angle 
is controlled by D9 and D10, two pins on the Arduino capable of PWM generation.  

The LED is placed in the middle of the gripper and used for helping the operator target the ball. 
It is powered by the 5V supply and connected in series with a 33kΩ pull-down resistor to ground, 
in order to prevent it from burning out.  

In order to detect pressure on the gripper, two 0-100kΩ-ranging force-sensitive resistors were 
placed inside the gripper. Each was connected in series with a 10 kΩ resistor to make a voltage 
divider. Then, the voltage across the 10kΩ resistor was measured by an analog pin of the 
Arduino (A0 or A1) in order to read in the force. At rest, there is no resistance in the 
force-sensitive resistor and the analog pin measures 5V across the second resistor. However, 
more force applied caused a higher resistance on the force-sensitive resistor, meaning that the 
voltage across the second resistor in the voltage divider would go down.  

The L12 Actuonix linear actuator we used can be powered by a custom control board, which we 
did not at first have access to, so we decided instead to control it via an H-bridge. The actuator 
acted like a DC motor in that it was moved by powering one of its pins and leaving the other on 
ground; switching which pin was powered would cause it to reverse directions. We powered the 
H-bridge from the 6V power supply, and grounded it to the common ground. The D2 pin of the 
Arduino controlled the Enable1,2 pin of the H-bridge; setting it low would prevent the motor 
from moving. The D3 pin of the Arduino controlled the 1A pin of the H-bridge, and the D4 pin 
of the Arduino controlled the 2A pin of the H-bridge. At all times, D3 was set high and D4 low, 
or D4 was set high and D3 low. 1A controlled the 1Y motor output, and 2A controlled the 2Y 
motor output. These were sent to the power and ground pins of the linear actuator.  

Another piece of hardware not shown in this image is the controlling laptop. It received data 
from the Myo armband via a Bluetooth adapter in order to receive user input, processed this data 
in Matlab, and output it to an Arduino connected to the computer over a serial port. We initially 
considered a NI myDAQ board, but decided to use an Arduino instead because the myDAQ 
could only input one PWM output at a time through Digital Output 3 of the board. We 
successfully constructed a circuit with NPN transistors to switch PWM control between the base 
and top servo motors very rapidly. However, whenever the PWM was switched away from the 
top servo, it would read a PWM of zero and begin to fall to the ground position (which was 
accelerated by the weight of the arm). This made motion very jerky. So, we used an Arduino 
because of its multiple PWM output pins.  

All these components were relatively cheap and mechanically robust. Due to time constraints, 
components were prototyped in a breadboard but could have been soldered together for increased 
stability.  

 
   
1.2 CAD Models 

 
Fig 2. Gripper claw CAD model for 3D printing 

The claws (​Fig 2​) were designed to be very thin and (originally) flexible so it would conform to 
the shape of the Play-Doh ball. However, we decided that a firmer structure required less force to 
close around the ball and, thus, left fewer impressions. We also wanted to claw to be wide 
enough for a force sensor to be secured to the end of it. The claw was designed with curved sides 
to prevent indentation in the case that the Play-Doh ball was not positioned perfectly in the 
center of the claw. The tip of the claw was raised to keep the ball from slipping out of the claw if 
the claw was not closed tightly enough, but the tip was also rounded to prevent it from leaving an 
indentation if the gripper was closed too tightly. We added holes towards the central axis for 
stringing paper clips through for added structural stability. 
 

 
Fig 3. Plunger CAD model for 3D printing 
The plunger (​Fig 3​) is necessary to secure the claws to the linear actuator for motion translation. 
We have holes on the sides for securing the claws to the plunger, and there is a slot in the middle 
that snugly fits the moving portion of the linear actuator. A dowel pin is used to secure the 
moving part of the actuator to the plunger. We added an LED to the center of the plunger as 
guidance for making sure that the Play-Doh ball is at the center of the gripper before closing.  
 

 
Fig 4. Claws assembled to plunger 

The CAD model for the claw-plunger assembly (​Fig 4​) was made so the claws were 120 degrees 
away from the plane of the plunger. This model was used to design the linear actuator hub, 
which determined how far the gripper could physically be opened. 
 
Fig 5. Linear actuator hub for 3D printing 

The linear actuator hub (​Fig 5​) is meant to secure the claws at the ends, house the linear actuator, 
and secur the linear actuator to the connector hub for the aluminum tubing. The clamps at the end 
prevent the linear actuator from slipping when extending/retracting. The arm projections are used 
to support and secure the claws at the specified position discussed above. At the bottom, there is 
a projection that secures the connector hub at an angle. This was angled so that gripper could 
come down directly above the Play-Doh ball to grip it.  
 

 
Fig 6. Full assembly of gripper 
In the full assembly (​Fig 6​), the connector hub and linear actuator are attached to the linear 
actuator hub (orange). The two 3D-printed clamp pieces and tightened with two screws and nuts 
to keep the linear actuator from slipping. The moving portion of the actuator is secured to the 
plunger (yellow) with a dowel pin.  

1.3 Control 
To control the Lynx, we used a Myo gesture control armband. It contains accelerometers and 
gyroscopes to detect arm motion, and it uses EMG sensors to identify many possible poses that 
the hand can make (e.g. fists clenched, waving hand out, waving hand in, fingers spread).  

Fig 7. Myo armband 

To control the Lynx servo motors, we decided that the arm pose of the user would map to the 
arm pose of the Lynx. Thus, yaw (or the rotation of the user’s arm around the longitudinal z-axis 
extending from their head to their toes) was used to control the angle of the base motor. Pitch (or 
the rotation of the user’s arm around the sagittal x-axis running sideways through the user) was 
used to control the angle of the top motor.  

The user’s hand motions would decide when an opening or closing motion was initiated, but not 
when it was stopped. If the user made a fist as detected by the Myo, the gripper would begin to 
close in small increments; this was done by retracting the linear actuator, which would pull the 
separate claws of the gripper together. At the beginning of each closing step, we would check if 
either of the force-sensitive resistors, placed on the gripper, was reading voltage below a certain 
threshold (4.3 V). If not, the actuator would continue to retract; if so, we would break out of the 
loop and finish retracting. We decided to check if either of the force sensors was below the 
threshold, and not both, because it is possible for a ball to be placed off-center within the gripper, 
causing one force sensor, and not another, to press tightly on the ball and deform it. Conversely, 
if the Myo detected that the user was waving their hand outwards or spreading their fingers (it 
detected both of these motions robustly but often confused the two), it would extend the actuator 
to open the Myo. This was done for a set period of time, without input from the force sensitive 
resistors, since we did not have to worry about opening the Myo too far, as we did about closing 
it. (However, we did open it for only a short time increment, to avoid extending the actuator all 
the way, which would break our gripper).  

We decided not to implement PID control to control the motion of the linear actuator. We did not 
see very replicable mappings from force-sensitive-resistor readings to amount the ball was 
deformed; the Adafruit website corroborates us on this point and does not recommend using the 
resistors to precisely measure force (https://www.adafruit.com/product/166). If we did, we 
would try to achieve a certain setpoint voltage very precisely, in which case PID control would 
have helped. However, we usually saw a setpoint voltage reading that remained at 5 V with some 
noise until it contacted the ball, when it suddenly dropped to around 1-2 V. We could feel safe 
setting a high threshold of 4.3 V and simply stopping the motion once the force-sensitive resistor 
achieved a reading below this threshold, which empirically usually achieved a good grasp on the 
ball.  

1.4 Code 
All code was written in Matlab, since it had convenient, well-documented libraries for our input 
device (the Myo-Mex library: ​https://github.com/mark-toma/MyoMex​) and our output device 
(the Arduino plug-in: ​https://www.mathworks.com/hardware-support/arduino-matlab.html​).  

 
The MyoMex library allowed us to instantiate a MyoMex object (​MyoMex mm​) representing our 
Myo and read new data from it at each iteration of a loop (​m1 = mm.myoData(1)​). That data had 
many individual fields, from which we could extract boolean variables about pose (​m1.pose_fist 
would be true if the user was making a fist, for instance), as well as a rotation matrix (​m1.rot​). 
This rotation matrix was used to extract pitch and yaw: 
 
 
Fig 8. Rotation matrix for angle calculation using Myo data 

The Arduino library allowed us to instantiate an Arduino object, attach it to a given port, and 
give it certain Arduino libraries. We used the Arduino servo library to create servo objects tied to 
certain digital pins so that we could just write directly to these servo objects. We used the other 
writing functions of the Arduino (​writeDigitalPin() ​and ​readVoltage()​)​ ​to control the linear 
actuator and read from the resistors).  

 
Pseudocode: 
%Initiate objects
a = arduino('com7', 'uno', 'Libraries', 'Servo')
s = servo(a, 'D9', 'MinPulseDuration', 1.00e-04, 'MaxPulseDuration', 1.00e-03)
s1 = servo(a, 'D10', 'MinPulseDuration', 1.00e-04, 'MaxPulseDuration', 1.00e-03)
mm = MyoMex(1)

baseMotor = 'D9';
topMotor = 'D10';
firstTime = true;

%Keep track of how far gripper has been retracted (0 sec - fully extended; 0.7 sec - fully
retracted)
global retractTime = 0;
global minimumRetractTime = 0;
global maximumRetractTime = 0.7;

basePwm = 0.5;
topPwm = 0.5;

%Retract actuator all the way so that position is certain, then extend it to open positoin
resetActuator(a);

while true
m1 = mm.myoData(1);

​ % data properties sampled on the IMU time base


r = m1.rot;

​% Get start angles which will be subtracted from later angles


if (size(startRot, 1) == 0 && size(r, 1) > 0)
startRot = r;
% Keeping angles bt + - pi/2
startTheta1 = inRange(atan2(-r(2,1), r(2,2)))
startTheta2 = inRange(atan2(-r(3,1), r(3,3)))

if (size(r,1) > 0)
%Get servo rotation angles from rotation matrix
theta_1 = inRange(atan2(-r(2,1), r(2,2)) - startTheta1)
theta_2 = inRange(atan2(-r(3,1), r(3,3)) - startTheta2)
else continue

if firstTime
lastTheta1 = theta_1;
lastTheta2 = theta_2;
firstTime = false;

%Fist closing the gripper (retract)


if (m1.pose_fist == 1)
retractActuator(a);

%Wave out for opening a closed gripper (extend)


if (m1.pose_wave_out == 1 | m1.pose_fingers_spread == 1)
extendActuator(a);

%If you hit the edge (as shown by a very sudden angle jump from -pi/2 to
%pi/2 so that abs(theta_1 - lastTheta1) > pi/2), you should not do
%anything. Otherwise, actuate the motor
if (abs(theta_1 - lastTheta1) < pi()/2)
basePwm = angleToPwm1(directionBase*theta_1);
lastTheta1 = theta_1;

if (abs(theta_2 - lastTheta2) < pi()/2)


topPwm = angleToPwm2(directionTop*theta_2);
lastTheta2 = theta_2;

​%Servo motor control


writePosition(s, basePwm);
writePosition(s1, topPwm);
%%HELPER FUNCTIONS

%Maps from user angle to Lynx angle for joint 1


function pwm = angleToPwm1(angle)
b = 0.5;
m = -0.3;
pwm = m*angle + b
if (pwm < 0.01) pwm = 0.01
if (pwm > 0.99) pwm = 0.99
end

%Maps from user angle to Lynx angle for joint 2


%Cannot go below 0.35 or it smashes into table
function pwm = angleToPwm2(angle)
%PWM:
b = 0.6;
m = 0.2;
pwm = m*angle + b;
if (pwm < 0.35) pwm = 0.35
if (pwm > 0.99) pwm = 0.99
end

function success = retractActuator(a)


thresh = 4.3;
time = 0.01;
foundLowSample = false;

%It is not retracted all the way, and you want to retract it
while (retractTime <= maximumRetractTime) ​%Iterate until maximum retract time reached
d1 = readVoltage(a, 'A0');
d2 = readVoltage(a, 'A1');

if (d1 <= thresh || d2 <= thresh || foundLowSample)


break;
else
%Applying too little force, close the gripper, retract
retractTime = retractTime + time;
ctl(1:3) = [1 0 1];
end
tic;
while toc < time ​%Keep it under individual timestep, stop in between steps
d1 = readVoltage(a, 'A0');
d2 = readVoltage(a, 'A1');
if (d1 <= thresh || d2 <= thresh)
foundLowSample = true;
toc
​%Actuate
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
ctl(1:3) = [0 0 0]; ​%Stop it at end
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
success = true;
end
%If it thinks it's all the way retracted but you still want to reset it
if (retractTime >= maximumRetractTime)
t = 2;
tic;
while (toc < time)
d1 = readVoltage(a, 'A0');
d2 = readVoltage(a, 'A1');
if (d1 <= thresh || d2 <= thresh) ​%Break if force is too high
break;
else
%Do not change the time
ctl(1:3) = [1 0 1];
End
​%Actuate
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
ctl(1:3) = [0 0 0];​ %Make sure you finish it
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
success = true;
end

function success = extendActuator(a)


tic;
t = retractTime;
ctl(1:3) = [0 0 0];
dt = 0.1;
i = 0
while retractTime > 0
tic;
while toc < dt
​%Extend actuator
ctl(1:3) = [1 1 0]
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
​%Stop in between segments
ctl(1:3) = [0 0 0];
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
success = true;
i = i+1;
retractTime = retractTime - dt; ​%Decrease retract time as you extend actuator
end

function success = resetActuator(a)


ctl(1:3) = [1 0 1]
t = 5;
tic;
while toc < t ​%Retract all the way
writeDigitalPin(a, 'D2', ctl(1));
writeDigitalPin(a, 'D3', ctl(2));
writeDigitalPin(a, 'D4', ctl(3));
end
retractTime = maximumRetractTime;
extendActuator(a);
end

%Puts in range from -pi/2 to pi/2


function x = inRange(theta)
while (theta > pi()/2)
theta = theta - pi();
while (theta < -pi()/2)
theta = theta + pi();
x = theta;
end
 
1.5 Cost Breakdown 

 
Fig 9. Cost of components and justification for incorporation 

2 Discussion 
Overall, our design was successful in picking up a ball of Play-doh and transporting it from one 
location to another without denting it too much.  

   
2.1 Gripper Mechanical Design 

 
Fig 10. Fully fabricated gripper 

In Fig 10, the fully fabricated gripper is attached to the rest of the arm with the LED and force 
sensors attached. The clamp is also fully assembled with screws. We found the mechanical 
design to be mostly successful. The holes for the LED wires needed to be enlarged (which we 
achieved with pliers post-print). We noticed excess vibrations when the linear actuator was 
extending/retracting, so we added rubber bands around the interface with the connector hub, 
actuator hub, and aluminum rubbing to decrease vibrations. The curved edges of the claws were 
successful in reducing indentations that we saw in earlier iterations of the design. The LED was 
somewhat helpful in determining whether the ball was in the center of the gripper, but it was 
highly dependent on the lighting of the environment.  

An improvement is to use a brighter LED or another method for identifying the center of the 
gripper relative to the ball. For instance, the top claw could be slightly curved to move the ball 
towards the center and into the other two claws, ensuring that no deformation would occur due to 
poor positioning. A future iteration could extend the actuator hub down towards the aluminum 
tubing to further reduce vibrations. The paperclips we inserted to fill the middles of the claws 
seemed successful. However, we never tested the device without them, and each paperclip took a 
long time to reshape and insert. Future iterations could determine whether just having those 
spokes 3D-printed into the design of the claws serves the same function. 
2.2 Control Discussion 
One control challenge was tuning the mapping between the user’s arm angle and the servo 
motor’s arm angle; we tried to make it so that the user could control the robot comfortably, 
without having to move their arm too far, but that it was not also oversensitive so that the robot 
would move drastically due to a small inadvertent motion of the user, making fine control 
difficult.  

Another control challenge was angle mapping. We converted all angles to between +- pi/2. 
However, it sometimes happened that if a user’s arm started slightly below -pi/2 (Myo angle 
readings were somewhat unpredictable), a slight movement could cause the angle reading to 
jump to pi/2, causing the robot to spin rapidly to the other side of the workspace. To alleviate 
this, we added a check of the distance between angle and last angle and did not move the robot if 
a change of pi/2 was achieved in one cycle (which would only occur because of this). 

If we were to do this again, we would want to tune control of the linear actuator a bit more finely 
or try incorporating the control board. We would also be interested in incorporating some soft 
robotics by printing the gripper with flex filament.  

Another challenge we faced was keeping track of the linear actuator’s extension or retraction. 
Because we did not have the control board, we could not move the actuator to a set position; 
instead, we could only extend or retract it to a set time. However, because its motion did not 
have a linear velocity but involved acceleration, and because we did not retract it for the same 
amount of time each time but instead paused it open reaching a certain force threshold, it was 
difficult to accurately track position. In the end, we did this by moving the actuator only for 
small, same-length timesteps, which should theoretically all have the same distance moved for 
each step, and checking in between these steps whether to stop. We also changed the gripper 
design, making it slightly shorter so that retracting the actuator all the way would not break it. 
That made control easier, because if position knowledge ever became unsure, we could regain it 
simply by fully retracting the actuator for a time definitely greater than the extension time. 
Overall, we implemented a high-level check by ensuring the extension time in terms of the small 
timesteps used was no more than 0.7 seconds, enough to fully open and release the ball.  

You might also like