will be read-only starting December 31st, 2018. For more info please look at this Forum Post

:: 4 Legs, 3 Servos, 2 Battery Packs, 1 Arduino :: This project is a custom chassis 4 leg walker from and Arduino, 3 Servos, and 2 Battery packs.

The concept behind this project was inspired by CrabFu's turtle robot. He does a nice job of showing the relationship between the phases of the legs and the torso movement. Figure 1 shows two examples one with standard servos (top) and one with pico servos (bottom). The batteries are oriented differently in the bottom diagram from that in Figure 1.

Figure 1 Two different layouts for the components.
Figure 2 The robot in my hand for scale
Figure 3 Detailed picture of the robot

The feet and certain connections and braces are made with ShapeLock for convenience.

The Physical Layout

The chassis is very simple. Two servos are oriented so the spindle is pointing down. The remaining servo connects the front half to the back half and provides the ability to twist the waist of the robot. Figure 4 shows a rough picture of the layout of the servos, batteries, and legs. Figure 4 While the figure does show a +/-30 degree swing I suggest you play with this number for your chassis. It is a parameter that is interesting to "tune."

Block Diagram

No block diagram is really needed for this robot. The servos are wired to +Vcc, Gnd, and a digital pin. The servo class in the latest Arduino development tools is used. So basically power the Arduino and Servos from the batteries. Then wire the servo control lines to a digital pin on the Arduino and you are ready to go.

Torque Sensing

Optionally I have been experimenting with a current sensing circuit added to the ground leg of the servos. Figure 3 is the simple resistive circuit that is used. I have experimented with 2ohm resistors but I plan on switching 0.1ohm when they arrive. These three resistors are tied to analog lines so how much current the servo is drawing can be calculated by the voltage divided by .1 (or 2 ohm). But really I only care that the analog reading is proportional to the torque the servo is exerting.

Figure 3


The software is relatively simple for this chassis as well. Basically the front and back servos move exactly opposite of each other. So when the back-left foot is forward the front-left foot is backward. The waist simply moves 1/2 way through the time that the back and front servos are in position. Said another you move the front an back to an extreme position (opposite of each other) and then move the waist to the other extreme. Interestingly this simple Front/Back extreme then Waist extreme then other Front/Back extreme then other Waist extreme is all there is to forward (and played in reverse) backward motion. Turning left and right I thought might be trickier but it was simple also. You simply change one limit in the waist. So to turn right do not go to the extreme on the right twist in the waist only go to center. Left is simply going to center not to the extreme on the left twist in the waist. The front and back servos cycle the same in forward, backward, left or right motion.

  1. #include <Servo.h>
  3. Servo waist,front,back;
  5. #define wCenter 80
  6. #define fCenter 70
  7. #define bCenter 70
  8. #define wSwing 40
  9. #define fSwing 40
  10. #define bSwing 30
  11. #define FORWARD 0
  12. #define BACKWARD 1
  13. #define LEFT 2
  14. #define RIGHT 3
  15. #define STOP 4
  16. int wPos,fPos,bPos,cycle,dir;
  17. long start;
  19. void setup()
  20. {
  21.   Serial.begin(9600);
  22.   waist.attach(13);
  23.   front.attach(12);
  24.   back.attach(11);
  25.   wPos=wCenter;
  26.   fPos=fCenter;
  27.   bPos=bCenter;
  28.   dir=FORWARD;
  29.   cycle=0;
  30.   start=millis();
  31.   Serial.println("iWaist,iFront,iBack");
  32. }
  34. void doBackward(int cycle) {
  35.   if (cycle<12) wPos=wCenter+wSwing;
  36.   else if (cycle<37) wPos=wCenter-wSwing;
  37.   else if (cycle<62) wPos=wCenter+wSwing;
  38.   else if (cycle<87) wPos=wCenter-wSwing;
  39.   else          wPos=wCenter+wSwing;
  40.   if (cycle<25) fPos=fCenter+fSwing;
  41.   else if (cycle<50) fPos=fCenter-fSwing;
  42.   else if (cycle<75) fPos=fCenter+fSwing;
  43.   else fPos=fCenter-fSwing;
  44.   if (cycle<25) bPos=bCenter-bSwing;
  45.   else if (cycle<50) bPos=bCenter+bSwing;
  46.   else if (cycle<75) bPos=bCenter-bSwing;
  47.   else bPos=bCenter+bSwing;
  48. }
  50. void doForward(int cycle) {
  51.   doBackward(100-cycle);
  52. }
  54. void doLeft(int cycle) {
  55.   doBackward(100-cycle);
  56.   if (wPos>wCenter) wPos=wCenter;
  57. }
  59. void doRight(int cycle) {
  60.   doBackward(100-cycle);
  61.   if (wPos<wCenter) wPos=wCenter;
  62. }
  64. void doStop(){
  65.   wPos=wCenter;
  66.   fPos=fCenter;
  67.   bPos=bCenter;
  68. }
  70. void posUpdate() {
  71.   cycle=(cycle+1)%100;  // 100 step cycle
  72.   switch(dir) {
  73.     case FORWARD: doForward(cycle);  break;
  74.     case BACKWARD: doBackward(cycle); break;
  75.     case LEFT: doLeft(cycle); break;
  76.     case RIGHT: doRight(cycle); break;
  77.     case STOP: doStop(); break;
  78.   }
  79. }
  81. void loop()
  82. {
  83.   posUpdate();
  84.   waist.write(wPos);
  85.   front.write(fPos);
  86.   back.write(bPos);
  87.   long iWaist=analogRead(0);
  88.   long iFront=analogRead(1);
  89.   long iBack=analogRead(2);
  90.   Serial.print(iWaist,10);
  91.   Serial.print(",");
  92.   Serial.print(iFront,10);
  93.   Serial.print(",");
  94.   Serial.print(iBack,10);
  95.   Serial.println();
  96.   delay(20);
  97.   long t=millis()-start;
  98.   if (t <10000) dir=FORWARD;
  99.   else if (t < 20000) dir=BACKWARD;
  100.   else if (t < 30000) dir=LEFT;
  101.   else if (t < 40000) dir=RIGHT;
  102.   else dir=STOP;
  103. }

Constants fCenter, bCenter, and wCenter are the center positions for each servo. So if you chassis is a bit off just change these to tweak alignment of the chassis. Constants fSwing, bSwing, and wSwing are the degrees to swing between.

This version will walk slow but stream torques to the serial port. This allows you to capture torques for data logging. Just comment out the Serial.??? calls in the loop body to remove this extra delay.

What is next

I hope to gather some interesting torque information to see if I can detect bumping into walls or drop-offs with torque being different than normal for those situations. This would mean the robot could "sense" walls and dropp-offs with no more circuitry than that discussed here.


Thanks Noah for the detailed pictures.

Update that includes head and sensors is at ThoughtfulWalker