Emily, a Quadruped Dog Robot

by twiereng in Circuits > Robots

1265 Views, 17 Favorites, 0 Comments

Emily, a Quadruped Dog Robot

DSC07123.JPG
IMG_4553_en.jpg
DSC07125_en.JPG
Image1.jpg
Image2.jpg
Image3.jpg

My motivation for this project was to build a quadruped robot about the size of Emily, my yellow Labrador Retriever. It began with a search of the Internet for examples of a dog robot I could model. While many dog robot examples can be found, the majority of them use small radio control (RC) servo motors and the robots described were smaller than I wanted. My vision of size was closer to Emily and was constructed along the lines of Boston Dynamics Spot. Their website is https://www.bostondynamics.com/products/spot.

 

While I didn’t expect to build something nearly as sophisticated as Spot, I felt that a good starting objective would be to build a body that could simply walk in a straight line. The goal was to not use sensors and simply use an algorithm to move the legs, creating a walking gait. Once the goal of walking was achieved additional features could be added. This project evolved over two years with many prototypes discarded.

 

This is not a beginner’s project. Prospective builders should have some experience with 3D printing, electronic circuits, soldering components onto printed circuit boards, C++ programming with the Arduino User Interface, using the Arduino User Interface for compiling and uploading programs into MPUs, as well as using the Boards Manager. High school level algebra, geometry and trigonometry are also needed to understand the mathematics presented.

Here's a video of Emily walking.

The Motors

3215-0001-0005_A__11102.jpg

A major decision was what type of motors to use. Hobby RC servos would not have the torque for the size and weight of the robot I wanted. What was needed was a motor with fairly slow speed (12 RPM), high torque (125 kg.cm. / 1750 oz.in.), and simple control signals for accurate positioning. Finding such a motor off the shelf was not easy. The small number I found were very expensive and each motor needed a sophisticated driver board as well. Motors in the more advanced robots like Boston Dynamics Spot are often custom made to specification.

 

My choice for motors was RC servo motors with a gearbox. Servo City has a nice group of these and I used their Actobotics SG12 series (now replaced with their Stingray series) which produces very high torque at slow speeds. They were not inexpensive, but they work quite well. With these you only need to send them a standard RC continuing pulse train at 50 hertz to have them move to a specific angle. The downside of these Servo Gearboxes is the accuracy of the position angle, which I found to be about 1 degree.

 

If the Stingray series is used there are some 3D printed parts that builders will need to change since the hole spacing and sizes are slightly different. The threaded holes on the Stingray series are metric M4, while the Actobotics used ANSI #6.

The Motor Driver

A couple of different servo driver boards were tried. My hope was that I could control their individual speeds and receive feedback on when they had arrived at the desired angle. While speed could be controlled, feedback on when multiple servos each reached their desired angle was not possible. In the end I wrote my own servo drivers in software using a Teensy 4.0 MPU. More on this in the Software section.

Center of Gravity

balance diagram.jpg

Early prototypes were built that incorporated Servo Gearboxes near the hip position to move the femur (top of the leg) and at the knee to move the tibia (bottom portion of the leg). The motor at the knee position caused problems in balance. The motors weigh about 200 grams and in addition to the surrounding 3D printed structure are enough to upset the balance on some of the step positions. When one of the legs is raised the center of gravity of the robot must fall within a triangle made by the three supporting foot positions to balance.

 

A number of different leg styles and positions were tried without success. The Servo Gearboxes are an awkward size and shape. Their power derives from the large 2.5 inch diameter gear with 100 teeth driven by a 20 tooth gear. The large gear, with a one inch diameter hub on top for additional mounting options, is the drive shaft for the motor, making some configurations a challenge.

 

The solution found was to mount both motors near the hip position with the femur mounted directly to the femur motor. The tibia motor is mounted underneath the femur motor and moves independently through a pantograph linkage to the tibia. This linkage is supported on a shaft connected to the mounting hub of the femur motor.

The 3D Printed Parts

12.jpg
13.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg
10.jpg
11.jpg

The majority of all the structural parts were 3D printed with PLA using a printer with a 220mm. x 220mm. x 300mm. build volume.

 

A dual channel with cutouts and matching screw holes was designed to hold two of the Servo Gearboxes, which are the hip motors. The bottom of the dual channel has some alignment ridges and holes to fit ¾ inch angle aluminum, with 1/8 inch walls. A second dual channel is attached to the angle aluminum towards the rear for the back hips.

 

The Servo Gearboxes have a one inch diameter mounting hub in the center of the large gear with four threaded screw holes for #6 machine screws. The base support (refer to the images) has a short mating one inch diameter shaft which is attached to the Servo Gearbox mounting hub using #6 machine screws. At the back end of the base support is a short shaft, aligned with the front short shaft, which is supported by a ball bearing. The front shaft is also supported by a bearing, with a bearing brace that is mounted using the screw holes in the dual channel.

 

A downside of the Servo Gearboxes is that the drive shaft is not as ridged as desired, and has a small amount of give to it. This gets amplified when attaching the weight of two additional Servo Gearboxes, and their mounts, along with the leg and all the forces on it. With the additional two supporting bearings the mount is much more rigid.

 

The two individual channels that are attached to the base support have small brass M3 inserts in the bottom and are attached with flat head M3 machine screws through the base support. These individual channels are mounted after the base support is attached with machine screws to the Servo Gearbox mount hub to allow for clearance.

 

The top individual channel on the motor mount frame will hold the Servo Gearbox that moves the femur, or top portion of the leg. The bottom one holds the Servo Gearbox that moves the tibia.

 

The femur has a circular mounting area at one end that is screwed directly onto the large gear of the Servo Gearbox and moves independently of the tibia’s movement.

 

The drive for the tibia is more involved and consists of a pantograph crank mechanism, the long sides are the femur and a threaded rod attached to the crank arm and the end of the tibia. The short sides of the pantograph mechanism are the crank arm radius and the top portion of the tibia. A crank is mounted on the tibia Servo Gearbox and connects through a crank link to a fan shaped crank arm that rotates on a short shaft screwed into the central hub of the femur’s Servo Gearbox. The crank arm rotates on two side by side bearings. The outside diameter of the bearings are press fitted into the crank arm and the inside diameter of the bearings accepts a short shaft mounted onto the central hub of the femur’s Servo Gearbox. These bearings allow the tibia arm to move independently of the femur.

 

The handles mounted on top of the two dual channels are important. Not only do they make lifting and moving easy, they keep your fingers away from areas where they can get severely pinched when the Servo Gearboxes are activated.

Detailed Assembly Steps

1.     Print all the parts with PLA. I used 100% infill, which in some cases is needed and in others may be overkill.

2.     All 3D printed parts with ¼ inch holes incorporated should have the holes gently cleaned out with a ¼ inch drill bit. These parts are the femur, tibia, crank arm left, crank arm right, crank link and crank.

3.     Cut two pieces of ¾ inch angle aluminum, with 1/8 inch walls, 24 inches long.

4.     Install #6 threaded brass inserts in the bottom of the two dual channels and M3 threaded brass inserts into the bottom of the eight individual channels.

5.     Drill two sets of two holes in the ends of the two angle aluminum pieces, matching those holes inside the raised slots in the bottom of the dual channel. The #6 machine screws will go through these holes in the angle aluminum, with one going into the threaded brass insert and the other going into the body of the Servo Gearbox as described below. The end of the angle aluminum should align with the front edge of the dual channel.

6.     Drill another two sets of two holes as in number 4, spaced 395 mm. down the angle aluminum.

7.     Attach the angle aluminum to the dual channels with #6 machine screws into the threaded brass inserts only.

8.     All the Servo Gearboxes should be aligned to the middle position by sending them a 1,500 microsecond standard RC servo signal. This center position should be marked with a felt tipped marker where the two gears mesh. As parts are connected to the Servo Gearboxes be sure they are in the center position as the software needs to have this alignment for proper operation.

9.     The four hip Servo Gearboxes are installed with #6 machine screws through the holes in the top and bottom of the dual channels. The bearing braces will also need to be installed at the same time, using the outer two holes in the top and bottom of the dual channel. A 25x37x7 mm. ball bearing needs to be press fit into each of the four bearing braces. Longer #6 machine screws will go through the bearing brace, into the dual channel holes and then into the threaded holes in the Servo Gearboxes. Two of the machine screws going into the bottom will go through the angle aluminum, then the dual channel and then into the Servo Gearbox.

10. The 25 mm. short shaft on the four base supports, that mount the eight individual channels, are now inserted through the 25x37x7 mm. ball bearings and screwed into the center hub of the Servo Gearboxes with four #6 machine screws. The base supports are different for the right and left sides. Note that the individual channels are attached to the base support with flat headed M3 machine screws. Identify the side of the base support with the cone shaped entry for the flat head machine screws. This side will face inward. When the Servo Gearboxes for the femur are installed in the individual channels at the top of the base supports, the large gear should be oriented towards the rear of the robot. The Servo Gearbox for the tibia is installed in the lower individual channel, with its large gear oriented forward.

11. The cross brace needs to have two 25x37x7 mm. ball bearings press fit into the 37 mm. openings. The two bearings are slipped over the rear mounting 25 mm. short shaft on the base supports. The cross brace has two feet which are attached to the two angle aluminum rails. With the cross brace in place and aligned perpendicular to the angle aluminum, mark where the holes need to be in the angle aluminum and drill these holes for #6 machine screws. Use nylon lock nuts on the #6 machine screws.

12. The same procedure, beginning with number 4 above, should be repeated for the assembly for the back legs.

13. Each femur needs to have two FR188-2RS flanged ball bearings, 1/4 x 1/2 x 3/16 in., press fit into the ends of the arms. The easiest way to press fit the bearings is to insert a tibia between the arms of the femur for support and then use a vise to press the bearing into the opening. Doing one bearing at a time works best. The four femurs are then attached to the large gear of the Servo Gearboxes at the top of the base supports. Flat head #6 machine screws are used with nylon lock nuts on the back of the large gear. Two machine screws are enough to hold the femur in place.

14. Two 25x37x7 mm. ball bearings are press fit into each of the four crank arms. Note that there are right and left side crank arms. The 25mm. end of the short shaft is then inserted into the ball bearings and then mounted to the center hub of the femur Servo Gearbox with four #6 machine screws. The 25.4 mm. end of the short shaft fits against the center hub of the Servo Gearbox. Note also that there is a slight lip around the 37 mm. opening on one side of the crank fans. This side should be placed against the round femur mount.

15. The crank that moves the tibia is installed on the lower Servo Gearbox. The arm on the crank is installed facing forward.

16. The crank link is connected between the crank and the crank arm with two ¼-20 pan head machine screws and nylon lock nuts. The machine screws should be slightly tightened and then backed off slightly so that the crank, crank link and crank fan can turn easily.

17. Each tibia needs to have a FR188-2RS flanged ball bearing, 1/4 x 1/2 x 3/16 in., press fit into the ends of the arm. Again, a vise used for the pressure works well. A R188ZZ ball bearing, 1/4 x 1/2 x 3/16 in., is inserted midway into the ½ inch hole in the tibia. The bearing, which is centered inside the ½ inch hole in the tibia, is then aligned with the two flanged bearings at the end of the femur. A ¼-20 pan head machine screw is then inserted through all three bearings and tightened in place with a nylon lock nut. After tightening, the machine screw should be backed off slightly for easy movement.

18. There are eight rod ends and the hole in each of these needs to be threaded with a ¼-20 tap. Be sure to align the tap closely parallel to the hole when starting. A FR188-2RS flanged ball bearing, 1/4 x 1/2 x 3/16 in., is also pressed into the rod end. Four pieces of ¼-20 threaded rod are cut 5 ½ inches long. Rod ends are placed on each threaded rod. The combined length of the rod ends and rod are determined by moving the femur into a horizontal position. Then adjust the combined length until the crank fan and tibia produce a rectangle with the femur and combined length of the rod ends and rod. Aligning by eye should work but a small square can also be used. Once the length is determined, the rod ends are connected to the crank fan and top end of the tibia by ¼-20 pan head machine screws. Again, tighten the machine screws and then slightly loosen them for easy turning.

19. The PCB is mounted on the left piece of angle aluminum just in front of the rear dual channel. The holes at the bottom of the PCB are on 3 ½ inch centers and are sized for #4 machine screws. Use a ¼ inch plastic or nylon spacer between the PCB and the aluminum rail to avoid the rail shorting any of the traces on the bottom of the PCB. Nylon #4 lock nuts should also be used.

20. The switch mount for the SPDT power switch was printed in a bright color for easy location when a quick shutdown is necessary. This is attached to the center two holes at the top of the rear dual channel with #6 machine screws.

21. The battery holder was printed for four 7.2 volt NIIMH batteries, however only two are used. The batteries are mounted in an upward position to improve the center of gravity of the robot. Cable ties can be used to hold the batteries firmly in place. The battery holder is placed as far back as possible near the rear cross brace. The holes in the battery holder are spaced to attach to the two pieces of angle aluminum. Align the battery holder on the angle aluminum and mark the hole positions with a pencil. Drill the holes in the angle aluminum for #6 machine screws and use nylon lock nuts.

22. The foot on the end of the tibia is a simple slice of a cylinder. Since it is PLA it slips and does not work well on a hard floor. A couple of different boots that fit over the foot were printed from TPU95A plastic, which is softer and grips better. The optimal shape for a boot is probably a partial sphere.

23. Offsets need to be established for each Servo Gearbox. No matter how careful you are in assembling the individual parts of the robot there will be some slight differences in the angles the femur, tibia and hip make as compared to the angles sent. The inaccuracy of the Servo Gearboxes adds to these differences. Instead of trying to build more accurately it’s easier to just assign a correction offset to each of the 12 angles. I choose a test value of 45 degrees for the femurs and tibias for assigning the offsets. A digital level with an accuracy of 0.1 degree was used to measure the angles. These devices are readily available at hardware stores, or Amazon, and are about as big as a medium size tape rule. Make sure the body of the robot is level when measured at the angle aluminum. The digital level is then clamped or taped to a femur (or tibia or base support), and a signal to set the femur to 45 degrees is sent to the femur’s Servo Gearbox. The difference between 45 degrees and the actual digital level reading is the offset value. These offset values are all stored in the main program and when assigning an angle to a Servo Gearbox, the offset values are added to the desired angle. Some discretion may be needed when assigning the offset values as the digital level will probably read slightly differently depending on from which direction the Servo Gearbox approaches 45 degrees.

The 12 offset values are incorporated into the 12 functions that derive the microsecond values for a given angle, as shown below.


int BACK_femur_L_uSec(float angle)
{
 int uSec = int(1500.0 - ((angle + BACK_femur_L_Offset) * uSec_factor) + 0.5);
 return uSec;
}

The Electronics

14.jpg
Ipcb.jpg
Emily_Schematic.jpg

The Emily robot is controlled by a single Teensy 4.0 Microprocessor (MPU). A printed circuit board (PCB) was designed that includes some additional circuitry and connections with further expansion in mind. The circuit could be mounted on a point to point breadboard but a PCB is highly recommended. A lot of frustration with trying to fit and solder all the point to point wires and the easily created short circuits can be avoided with a PCB. The PCB was designed using ExpressPCB’s free classic software and ordered through their website at https://www.expresspcb.com/. The IC sockets were made by cutting 0.6 inch wide sockets lengthwise and are highly recommended. An ESP32 socket was added with a plan for an optional remote control in the future and it is connected to the Teensy 4.0 through a serial port. At present the ESP32 is not necessary to operate the Emily robot. There are also header pins for an LCD display using the I2C interface, MPU6050 3 axis accelerometer and gyroscope, and an SPI interface for something like a SD card. The Servo Gearboxes are connected through twelve 3 pin headers.

 

There are also header pins for a Nextion display, and a second LCD display, using an I2C interface. These are connected to the ESP32.

 

A small fan was mounted over the Teensy 4.0 for cooling if overclocked but is not necessary if running at the default clock speed of 600Mhz.

 

Separate power supplies, two 7.2 volt NIMH batteries, are used for powering the Servo Gearboxes and the MPUs. Separate LM7805, 5 volt voltage regulators, were used for the Teensy 4.0 and ESP32. Only one LM7805 is needed if the ESP32 is not used.


 Viewing the 3 pin headers on the PCB, that connect to the Servo Gearboxes, the connections are, from the top:

 

FRONT_HIP_L                   A9     These are the pin numbers on the Teensy 4.0

FRONT_FEMUR_L            3

FRONT_TIBIA_L               A8

FRONT_HIP_R                  4

FRONT_FEMUR_R            A7

FRONT_TIBIA_R               5

BACK_HIP_L                     A6

BACK_FEMUR_L              6

BACK_TIBIA_L                  A3

BACK_HIP_R                    9

BACK_FEMUR_R              A2

BACK_TIBIA_R                 A1

Software - Servo Signal to Position the Motors

16.jpg

A radio control (RC) type servo motor is controlled by sending it a continuing pulse train. Although servos differ slightly by company, in general the servo’s center position is obtained by sending a 1,500 microsecond pulse to the servo every 20 milliseconds. In general, sending a 1,000 microsecond pulse every 20 milliseconds turns the servo head 90 degrees to the left and a 2,000 microsecond pulse 90 degrees to the right. The Servo Gearboxes, with their geared arrangement, use slightly different values. The speed the movement takes depends on the servo’s speed specification and the voltage used, which is normally in the range of 4.8 to 7.4 volts.

 

Servo City’s Actobotics SG12 Series Servo Gearboxes allow for more rotation because of their geared system. The home position is at 1,500 microseconds, and they turn 0.321 degrees/microsecond, or 1.0 degree with a change of 3.115 microseconds. Setting a gearbox to a specific angle from the 1,500 microsecond center position is done by multiplying the angle by 3.115 and then, depending on the desired position, adding or subtracting from 1,500 to get the pulse width needed. Servo City’s Stingray series has different values for degrees/microsecond.

Software - the Servo Driver

One of the four Interval Timers on the Teensy 4.0 is used to drive each of the Servo Gearboxes.. Here are some simplified code examples.

 

// Teensy 4.0 has 4 timers used to drive the Servo Gearboxes
IntervalTimer timerLFront, timerLBack, timerRFront, timerRBack;
 
// usec values to drive Servo Gearboxes at full speed, or a flag using speed
volatile int usec_FFe_L, usec_FTb_L, usec_FHp_L;
volatile int usec_FFe_R, usec_FTb_R, usec_FHp_R;
volatile int usec_BFe_L, usec_BTb_L, usec_BHp_L;
volatile int usec_BFe_R, usec_BTb_R, usec_BHp_R;
 
// For the back left femur Servo Gearbox we use usec_BFe_L to store the desired pulse width
 
usec_BFe_L = 1500;
 
// Start timers which execute the specified function every 20,000    
// microseconds, giving the 50 Hz. timing needed for a Servo Gearbox
// Each timer operates the femur, tibia and hip of a single leg
timerLFront.begin(front_Servos_L, 20000);
timerLBack.begin(back_Servos_L, 20000);
timerRFront.begin(front_Servos_R, 20000);
timerRBack.begin(back_Servos_R, 20000);
 
// The timer functions
// Each function drives a Servo Gearbox, to move a new microsecond
// value is assigned
 
void back_Servos_L ()
{
   digitalWrite(BACK_FEMUR_L, HIGH);
   delayMicroseconds(usec_BFe_L);
   digitalWrite(BACK_FEMUR_L, LOW);
}

 

With this code all that is needed to change the angle of the back femur left Servo Gearbox is changing the usec_BFe_L value.

 

With a little extra code we can incorporate some speed control into the timer functions. Here we use the usec_BFe_L value as a flag. If its value is zero we will be controlling the speed, if not it will just use the value with the previous code to travel at full speed. If you try changing the speed of a Servo Gearbox every 5 milliseconds it makes no sense as the servo signal is only sent every 20 milliseconds. The change in speed is synchronized to happen every 20 milliseconds when the program enters the timer function. The angles (in microseconds) coming from and going to and the number of 20 millisecond blocks this movement takes are specified.

 

volatile int usec_from_BFL, usec_to_BFL, value_BFL;
volatile int temp_count_BFL, count_BFL;
 
// Get microseconds needed for from and to angles
usec_from_BFL = BACK_femur_L_uSec(e_femur_BL[i]);    
usec_to_FL = BACK_femur_L_uSec(e_femur_BL[i-1]);
 
// Set usec_BFe_L = 0, so speed will be used
usec_BFe_L = 0;
 
// Set count_BFL, number of 20 millisecond periods for speed to change
count_BFL = 12;
 
// Set starting count
temp_count_BFL = 0;                                  
 

 

When moving between the two angles in the example above, it will take 12 * 20 = 240 milliseconds. Regardless of the settings used you cannot get the servo to move faster than what its specifications define. In essence the speed control can only slow down the servo.

 

Here is a portion of the combined timer function.

 

void back_Servos_L()
{
// Femur ********************************************************************
if (usec_BFe_L == 0)
{
// If this is true then Servo Gearbox movement will take count_FL * 20
// milliseconds going to the angle defined by usec_to_FL to
// usec_from_FL
// Note that it is possible to define a speed that exceeds the full
// speed value of the Servo Gearbox
     if (temp_count_BFL != count_BFL)
{
temp_count_BFL += 1.0;
value_BFL = usec_from_BFL + (int)(((float)temp_count_BFL/(float)count_BFL) * ((float)usec_to_BFL - (float)usec_from_BFL) + 0.5);
     }
     digitalWrite(BACK_FEMUR_L, HIGH);
     delayMicroseconds(value_BFL);
     digitalWrite(BACK_FEMUR_L, LOW);
}
else
{
// Otherwise just move to the desired angle, using usec value. At full
// speed the SG12-50 travels 48 deg/sec at 4.8 volts or 75 deg/sec at
// 7.4 volts. The SG12-70 travels 34.29 deg/sec at 4.8 volts or 53.57
// deg/sec at 7.4 volts
 
     digitalWrite(BACK_FEMUR_L, HIGH);
     delayMicroseconds(usec_BFe_L);
     digitalWrite(BACK_FEMUR_L, LOW);
}

Inverse Kinematics

17.jpg
19.jpg
18.jpg

Inverse kinematics is the process of defining the robot’s desired foot positions and then calculating the angles needed to move the legs into those positions. The lengths of the femur (upper leg) and tibia (lower leg) are chosen first. A stride length is also selected and a triangle is formed with the base half the stride length. The height of the triangle is selected by a ratio multiplied by the base. The last parameter is how high the foot is lifted, which is called the lift, and is a percentage of the triangle height. All together there are five parameters which must be chosen as in the example below.

 

Femur = 187.5 mm.

Tibia = 165 mm.

Base = 100 mm.

Ratio = 2.2, so Height = 100 * 2.2 = 220 mm.

Lift = 0.9, so Up = 220 * 0.9 = 198 mm.

 

A Microsoft C# program was designed to allow different values for the five parameters above to be tested. After this was developed the Inverse Kinematics algorithm was incorporated into the Teensy 4.0 program.


The femur and tibia angles are defined in such a way that they will be in the range of 0 to 90 degrees. Note that the sum of the length of the femur and tibia must be longer than the hypotenuse of the triangle.

 

           187.5 + 165 = 352.5 > sqrt((100 * 100) + (220 * 220)) = 241.66

 

At this point the foot positions in x and y can be defined. The hip position is defined at the origin, (0, 0). Each stride is divided into 16 periods. The y value is the height when the foot is down and when up, the lift multiplied by the height value when lifted. See the graph in the images.

 

There are two similar models, the only difference is one uses two periods to move the foot forward and the other uses three. Using the two period model, the foot is in the backward position in periods 0 and 1, and in the forward position in periods 3 and 4. In period 2 the foot is halfway between forward and backward and for the rest of the periods, 5 to 0, the foot is moving from forward to backward in 12 steps.

In pseudo-code we have:

 

for (int i = 0; i < 16; i++)
{
   if ((i > 0) && (i < 4)) { y[i] = up; }
   else { y[i] = height; }
}
 
x[0] = -base;
x[1] = -base;
x[2] = 0.0;
x[3] = base;
x[4] = base;
 
for (int i = 5; i < 16; i++)
{
   x[i] = base - ((float)(i - 4) * ((2.0 * base) / 12.0));
   // Round to two decimal places
   x[i] = (float)((int)(x[i] * 100.0 + 0.5)) / 100.0;
}

 

At this point the hip position is at the origin (0, 0) and there are 16 different foot positions for a single stride along with the length of the femur and tibia. Next, the knee positions are calculated by using a two circle intersect algorithm. The algorithm for this is:

 

Let the centers be: (a,b), (c,d)

Let the radii be: r, s

e = c - a                         [difference in x coordinates]

f = d - b                         [difference in y coordinates]

p = sqrt(e^2 + f^2)               [distance between centers]

k = (p^2 + r^2 - s^2)/(2p)      [distance from center 1 to line joining points of intersection]

x = a + ek/p + (f/p)sqrt(r^2 - k^2)

y = b + fk/p - (e/p)sqrt(r^2 - k^2)

OR

x = a + ek/p - (f/p)sqrt(r^2 - k^2)

y = b + fk/p + (e/p)sqrt(r^2 - k^2)

 

This algorithm is incorporated into a function which returns both the solutions since the circles intersect in two places. Given the output the correct values for x and y can be chosen and they are the first set above which has the most positive x value.

 

Now with the knee positions the angles for the femur and tibia can be calculated.

 

// Also change radians to degrees
femur_angle[i] = atan2(knee_y[i], knee_x[i]) * (180.0 / pi);
 
tibia_angle[i] = atan2(y[i] - knee_y[i], x[i] - knee_x[i]) * (180.0 / pi);
 


Now there are 16 sets of angles for the femur and tibia that will define a single stride for a leg. For a quadruped simply shift the angles by 4, 8 and 12 periods for the three other legs. A walk or creep gait has the foot in the back left touching down first, next the front left, back right and front right.

The Main Program Loop

Emily Flowchart.jpg

The main loop in the software takes the 16 angles for each stride and moves through the angles by dividing the movement between two adjacent angles by count steps. The 16 angles were calculated by the inverse kinematics function for each hip, femur and tibia. The 16 angles were then shifted by 4, 8 or 12 periods respectively for the other legs. When the count is set to 6 then, for each motor, a single stride will be broken up into 16 x 6 = 96 steps. Here is some pseudo code.

 

i = 0;
the_count = 6;   // the_count * 20 msec. for each time slice
while(i < 16)    // 16 time slices, 6 * 20 * 16 = 1920 msec.
{
   Serial.println(i);
   // Get microseconds needed for the from angle
   usec_from_FFL = FRONT_femur_L_uSec(e_femur_FL[i]);  
   // Get microseconds needed for the to angle
   usec_to_FFL = FRONT_femur_L_uSec(e_femur_FL[i+1]);
   // Set the count, the number of 20 msec. periods
   count_FFL = the_count;
   // Zero the temporary counter
   temp_count_FFL = 0;
   // Set usec_Fe_L = 0, so speed will be used
   usec_FFe_L = 0;                                          
 
   // The lines above are repeated for the additional 11 servo gearboxes
 
   // Now wait until the motors have finished moving
   // Note we haven’t used the hip motors
 
   while ((temp_count_BTL != count_BTL) && (temp_count_BFL != count_BFL) &&
          (temp_count_BTR != count_BTR) && (temp_count_BFR != count_BFR) &&
          (temp_count_FTL != count_FTL) && (temp_count_FFL != count_FFL) &&
          (temp_count_FTR != count_FTR) && (temp_count_FFR != count_FFR))
   {
       // Do nothing
   };
 
   i++;
}          
                         

 

Note here that the program’s main loop does not actually move the legs at the angles desired. Instead the main loop assigns global variables that are then used by our timer functions as they are invoked every 20 milliseconds.


The programs and SketchUp files are found below. The Three_Dim_Inv_Kin.ino program is the beginning of my work on having Emily step sideways and is a work in progress. All three ,ino program should be placed in a folder called Emily_Robot_II.

Afterthoughts

1.     Reduce weight by printing some parts at 50%.

2.     If weight can be reduced enough, Servo Gearboxes with smaller gear ratio and faster speed could be used.

3.     Base support and individual channels should be printed as one.

4.     Newer Servo Gearboxes will need to be used, requiring redesign of Dual Channel and Individual Channel parts.

5.     Teensy 4.1 should be used for additional I/O.

6.     Better connectors for servo motors than header pins. Small bullet connectors soldered to PCB.

7.     Better foot, perhaps a sphere, better boot to prevent slipping.

 

Additional Files

There are file types not supported for downloads by Instructables that are useful to a builder. This includes the ExpressPCB .pcb file for a printed circuit board and SketchUp .obj files for use with a slicer such as Cura. The C# program for testing different leg models and balance is also available. These files can be obtained at no cost from the author at theronsarticles@gmail.com.