This document provides a comprehensive guide to install and calibrate servos on a spot micro frame, and create a cooresponding servo configuration the ROS motion command node requires. A spreadhseet named servo_calibration_spreadsheet.ods
is included in this repo in the docs
directory as an aid for calculating the servo configuration values.
The servo configuration dictionary is contained within the configuration file spot_micro_motion_cmd.yaml
and holds servo configuration values as shown below:
num_servos: 12
servo_max_angle_deg: 82.5
RF_3: {num: 1, center: 306, range: 385, direction: 1, center_angle_deg: 84.0}
RF_2: {num: 2, center: 306, range: 385, direction: 1, center_angle_deg: -27.9}
RF_1: {num: 3, center: 306, range: 396, direction: -1, center_angle_deg: -5.4}
RB_3: {num: 4, center: 306, range: 394, direction: 1, center_angle_deg: 90.4}
.
.
.
Servo's are defined by a abbreviation and number referring to their location and position within a leg. "RF" cooresponds to right front, "RB" to right back, similarly "LF" and "LB" to the left front and left back legs. A number 1 cooresponds to link 1 (the hip joint), 2 to link 2 (the upper leg, or shoulder joint), and 3 to link 3 (the lower leg or knee joint).
-
num_servos: Fixed at 12 for this spot micro platform
-
servo_max_angle_deg: Maximum permissible command angle in a single direction for every servo. Robotic servos usually have a total movement range of 180 deg (i.e. +/- 90 deg in each direction from center). The maximum value for this limit is usually 90 deg, however it is useful to slightly constrain it to account for errors in servo center position, potential performance loss near the edges of a servo's travel, or to avoid mechanical limits or restrictions. A value of 82.5 deg works for my robot.
-
num: Port on the PCA9685 board (numbered 1-16) which that servo is connected to
-
center: The "raw" pwm value the PCA9685 node recieves representing the servo center position. A servo's position is generally commanded by a 1 to 2 ms pulse in a 50 hz cycle (20 ms time period). The PCA9685 board and cooresponding ros node controls the length of this pulse via a 12 bit pwm value. Assuming a 20ms total cycle length, 0 means no pulse, 2^12=4096 means a constant high signal, and 2048 for example would mean a pulse length of 10ms. A servo's center position is usually positioned with a 1.5 ms pulse which cooresponds to a pwm value of about 307. This value can be fine tuned by moving a sample servo with a horn on it via the servo keyboard move node and finding the center point from where the servo moves equally in opposite directions (say +/- 90 deg equally from the center. The value of 307 is a good starting point, and the value should be the same for all the servos in a set of the same kind.
-
range: The "raw" pwm value that cooresponds to the max end to end movement range for a servo. This will be related to the servo_max_angle_deg defined in the config file. As an example, the servo range value would be the raw pwm value for a servo position at +80 deg minus the raw pwm value for a servo position at -80 deg . The spreadsheet in this repo calculates this range value.
-
direction: A value of 1 or -1. Reverses the direction or servo rotation if needed, dependent on the coordinate axes of a specific leg joint. Computed in the servo calibration spreadsheet.
-
center_angle_deg: The value in degrees, in a leg joint's specific coordinate system, that cooresponds to a servo's position when at it's "center" pwm value. Value calculated in the servo calibration spreadsheet.
Servos must be connected in the following order to the PCA 9685 control board:
- Right front knee
- Right front shoulder
- Right front hip
- Right back knee
- Right back shoulder
- Right back hip
- Left back knee
- Left back shoulder
- Left back hip
- Left front knee
- Left front shoulder
- left front hip
It is reccomended to install servos in the spot micro frame when they are powered and commanded to their center position. The joint which a servo is installed in should be approximately positioned at it's "nuetral" stance, the position about which most leg motion will occur. This ensures maximum servo travel will be available around the typical joint command angles. The two figures below roughly depict the joint orientations for which servo's should be installed when at their center position.
Individual servo's can be commanded via the servo_move_keyboard ROS node for the calibration procedure. After one or more servos are connected to the PCA9685, the steps for commanding a single servo are as follows:
- On the raspberry pi, start the i2cpwm_board node:
rosrun i2cpwm_board i2cpwm_board
- On another terminal on the raspberry pi, or on a linux machine with ROS installed and capabile of communicating with the raspberry pi, run the servo_move_keyboard ros node:
rosrun servo_move_keyboard servoMoveKeyboard.py
- After the descriptive prompt appears, type
oneServo
to enter the one servo command node. - Select the servo to command by entering the integer number cooresponding to the PCA9685 port to command, for example,
2
. After a servo is selected, all other servos are commanded to idle (or freewheel) such that they can be moved by hand. The following prompt will appear:
- Use the key
y
to command the default center value of the selected servo (pwm = 306). Use the keysg
andj
to decrease or increase the servo pwm command value by 1, respectively. This moves the servo in fine increments. The current pwm value is printed in the terminal. Use thef
andk
keys to move the servo in coarser increments.- Key's
z
andx
can be used to quickly command the servo to it's min and max values, respectively (by default 83 and 520, but these can be updated per servo by the keys specified in the instrucitonal prompt). Be careful commanding min/max, and ensure your servos can physically move to those positions and won't get stuck.
- Key's
- After commanding a servo to desired calibration positions and noting down values in the calibration spreadsheet, exit the one servo control mode by pressing
q
- Go back to step 3 to repeat the process for another servo.
Adequate kinematic performance can be achieved through calibration of links by eye, as depicted in the diagrams below. However, I also used a smartphone inclinometer app as an aid to measure angles of 45 deg for the link 1 calibration. It is reccomended to prop up the robot on a box or similar test stand so the legs can hang freely for calibration.
Leg links should be visualized as straight lines segments from reference point to reference point (e.g. axis of rotation to axis of rotation). When positioning joints for calibration, use the wireframe representation of each link for orientation reference rather than the 3d printed part itself.
The servo calibration can be built up with aid of the servo_calibration_spreadsheet, shown in the figure below. Generally the procedure is the position each link to two reference positions (angles) and note down the corresponding pwm values for those positions. I used gross angles of 0 and 90 deg for ease of placement by eye. While the slope value is not used, it is useful to keep an eye on it as all servos should have similar calculated slopes. Large discrepancies in this value could be indicative of errors. If you get unexpected values for servo 3 and 12 you might check if you printed a modified model with inverted hip-servos. To check this take a look from inside the body. If you see 4 ball-bearings you have the original design, if you see 2 ball-bearings and 2 server-horns the servos 3 and 12 will be inverted.
Consistency in the following steps is more important than accuracy.
Start with calibrating links 2 and 3 for all legs, starting with the right side of the robot. The figure below depicts the coordinate systems of the links of the right side legs positioned at 0 degrees, and defines the positive and negative angle directions.
Note that link 3's angles are relative to link 2, as exemplified by the figure below:
Starting with link 2 (ignoring the orientation of link 3), command link 2 to positions of 0 and -90 degrees, and note the cooresponding PWM values in the spreadsheet. These two positions are shown in the following two figures.
Next, move onto link 3. For ease of visualizing reference orientation, manually position link 2 in a vertical orientation. Command link 3 to 0 and +90 degree positions and record the cooresponding pwm values. The two positions of link 3 are shown in the following two figures.
Repeat this process for the other right side leg.
Next repeat this process for the legs on the left side of the robot. Note that the coordinate systems for the left legs have different directions for positive and negative angles. These are depicted in the figure below for completeness.
Repeat the calibration process for link 2 on the left side legs. Position link 2 to 0 and +90 degree positions, and record the PWM values in the spreadsheet. The two positions are shown in the following two figures.
Repeat the calibration process for link 3 on the left side legs. Manually position link 2 vertically, then position link 3 at 0 and -90 degrees and record the cooresponding pwm values in the spreadsheet. The two positions are shown below.
Repeat the process for both left side legs.
Finally, calibrate link 1 for the left and right legs in a similar pattern. The coordinate systems for link 1 of the left and right legs is shown in the figures below.
Start with the right legs, and command link 1 to 0 and -45 degrees, and record the cooresponding PWM values in the spreadsheet. A reference value of 45 degrees is used instead of 90 due to mechanical limits. Repeat the process for the left legs. These positions are shown in the four figures below.
This complets the leg servo calibration process. Take the bold values from the servo calibration spreadsheet and copy them to the servo configuration dictionaries in the spot_micro_motion_cmd.yaml
config file. This file is located in your catkin worksapce in the following subfolders src/spot_micro_motion_cmd/config/spot_micro_motion_cmd.yaml
.