The Art of Servo Alignment
by Josh Southerland
Intro
I have spent some time with the problem of aligning multiple servos sharing 1 DOF and have found a solution with benefits over the standard method of testing two servos to match teeth when issued the same command. Then I took this one step farther by creating a simple script to validate a pair of servos, or in the case of a mismatched pair, suggest the useable range. This page will provide the script, in addition to describing how to use it, and the method behind the madness
I don't care about the theory and problem, just give me the matlab function and tell me how to fix things.
Assumptions
I am working with 180 degree Hitec Servos (HS-645MG). Though this guide is theoretically applicable to most servos, several parameters may need to be tweaked (explained later). I am also using the SSC32 PWM Generator from LynxMotion, which makes Pulse Offsets and Group Moves possible.
The Problem
The problem is that if two servos share 1 DOF (you do this to increase torque on that DOF) and aren't aligned, the servos will continuously fight against eachother because they will try to be achieving different joint angles which are outside of eachother's deadband. Deadbands for the Hitec HS-645MG's are less than 1 degree. The traditional method (even recommended on sites such as lynxmotion) is to test two servos by sending them both one joint command and check if their gear teeth line up. This method requires several servos to find a single pair, so lynxmotion recommends drilling their bracket so that they line up. But as I will describe next, even if you manage to find a pair or servos that align at some angle, or drill the brackets, chances are the servos will not work across the entire joint range.
The Issue with Traditional "fixes"
The problem with finding two servos that match can be understood by examining their circuitry. The servos use a potentiometer as a voltage divider to determine the relative joint angle. The problem with this approach is that there are considerable tolerances on resistors and these vary across servos. OK so you just rummaged through 5 servos and found two that the gears lined up, or drilled your bracket so that they did so. You successfully dealt with the problem of gears misaligned across servos. The bad news is the potentiometers most likely arent close enough.
The servos can be described by the linear equation Y = mX + b
Where:
Y = joint angle
m = slope determined by potentiometer = (change in joint angle)/(change in PWM command)
X = PWM signal sent
b = gear alignment offset
X is controlled by the user in an attempt to achieve some desired Y and b is the variable normally matched by servo users during alignment(for some particular X).
Approach
We don't care about b; m is the variable to match. The reason for this is that even a 2 degree change in the numerator of m over the range of 180 degrees is enough to cause the servos to fight eachother during some part of the range. What we will do is measure the change in angle (using an angle finder) over a large range(180degrees preferably) and use the slope calculated to determine if both servos can be adjusted via controlling offset(b) to be within both deadbands across the entire joint range. (note: each servo's deadband is modified by the slope of that servo).
Step By Step Instructions
Solving and evaluating slope for each servo
- Get my matlab function to check servos
- Connect servos using a Y connector so they can receive the same command
- Issue the Move command to move them to 0 degrees, or an angle possible without hitting the joint limits. This angle should be achieved by rotating coutnerclockwise on most servos.
- Record the PWM command you issued (we will call this the range min) and the corresponding measured servo horn angle
- Now rotate the servos to the other end of their possible joint spaces (ie: 90/180 degrees depending on range) and record the PWM command sent(we will call this range max) with the corresponding servo horn angles.
- At this point subtract the range min from the range max, giving you a positive difference of the number of degrees rotation you achieved for each servo.(for example 181degrees and 185 degrees)
- Now open my check_servos.m function and set range_min and range_max values to the PWM commands you issued(in microseconds) example: range_min = 600; range_max = 2400; Also set deadband to the deadband for your servo (in microseconds, if your spec sheet says degrees it is incorrect)
- You can now execute my function in matlab using %check_servos(delta_theta_servo1,delta_theta_servo2) with each delta being the difference in degrees of rotation, which you found in step 6.
- The function will evaluate the possibility of the 2 servos as a pair. If they match you are ready to align the offset(b). If they do not match, the function will list the maximum range(in degrees) that the servos will match over. If this range is acceptable you can continue to align the offset for the range you require. If not, you will have to check another servo.
Solving Alignment
- First, send both servos the same command as we did before
- Now, try to push the Servo Horns onto the Servo, minimizing the error between the two in joint angle. You should also make sure at this point that the servo stops will allow the full range you need(ie, 50 degrees aren't blocked by a robot base or other mechanical structure)
- If the servo horns are already connected to the servo link, one servo horn will not fit onto the servo because the teeth won't mesh
- At this point experiment with the Pulse offset command neccessary to align the servo teeth with the servo horn teeth of the second servo. When you have found it fasten the servo horn to the servo and record the pulse offset command for future initialization.
Using Servos After Alignment
- First call should be a Pulse Offset command for both servos if using the SSC32. This will look like: # [Channel] PO [offset] [^cr]
- Immediately following this command send a group move for the two servos to some initial position which looks like: # [Channel1] P [Position] # [Channel2] P [Position] S [Speed] [^cr] ,where the Positions are equal
- From this point on always use the group move command for the pair of servos and send the same position to both.