27 Apr 2013

4-legged Robot using Arduino


This is a 4-legged robot built by Oscar, original post can be found here:

This is a screen shot of what he has done so far.

Arduino Quadruped robot

Arduino 4-legged Robot - Stalker

I am going to build an Arduino Quadruped Robot. As usual, I will share my source code and show as many pictures as possible, to help those of you who are also building Quadruped robots. The way I do things might not be the best ways, and I am sure you can come up with better solutions, please let me know if you do! :-)


This robot is actually the first robot I wanted to build, but I failed miserably. you can check this out and this. After building a working Arduino Hexapod robot, I feel confident that I can pull it off this time! I recycled the parts from the arduino hexapod robot, and build a body with styrene sheets, so there is no new parts.
For Inverse Kinematics, Check out my tutorial:
http://blog.oscarliang.net/inverse-kinematics-and-trigonometry-basics/
I made an excel spreadsheet to simulate the movements of a quadruped robot. It shows detailed inverse kinematics calculations, and it might help those who are having problem understanding IK to visualize the complex computations, also it’s a great help to debug your code.
Download Quadruped Robot Simulation Spreadsheet V1.0
-
Okay, so, here are my progress so far
[31/01/2013]
I call this arduino quadruped robot ’Stalker’, because of the game unit in Star Craft of the same name. (although they look totally different :p)

Hardware that I use at the moment:

1. Arduino Mega
2. 12 Servos
3. Wii Nunchuck controller
5. a few thick styrene sheets (skeleton)
6. 6V Ni-MH 4300mh Battery

Plan:

1. Build Body and Assemble Robot.
2. Test Wii Nunchuck on it.
3. Write good IK for body rotation, and translation.
4. Get it walking!
5. Write Android App to achieve more complicated task.
6. IR/ Ultra-Sonic Detection and simple AI.
7. Terrain Adaption.
============================================================

Project Started – Update 31/03/2013

Basically copied most of the codes from my last Hexapod robot. All I did was to remove the variables related to the middle legs, and modifed the preset variable values to work in the Quadruped Robot, and it actually worked! :)
But the movements are quite Awkward, a lot of work need to be done about Inverse Kinamatics.
Here is how I made the body:
IMAG0595-1IMAG0596-1
Arduino Quadruped Robot 2
========================================================================

Quadruped Robot Leg Calibration (Servo Angle Offsets) – Update 03/04/2013

I just didn’t like the body, i thought it was too big! So I spent an evening re-measured, and cut it down from 16cm to 12cm (leg to leg distance).
Quadruped Body IMAG0606
I have also created a very simple Servo Offset calibration program.
As you might know, due to the fact that no servo is perfect, they might tilt to the right a little more than the left, or the other way round. (It could be also caused by the servo brackets) You might want to give it an offset to correct this. It’s very handy when you have a lot of servos like Hexapod/Quadruped Robts have.
1// ===========================================================
2// blog.OscarLiang.net
3// Created on 04/04/2013
4//
5// ===========================================================
6//
7// A very simple program to calibrate multiple servo offsets.
8// Especially useful if you have a lot of servos, for example
9// Hexapod Robots and Quadruped Robots.
10//
11// ===========================================================
12//
13// Instructions:
14//
15// 1. change variable "ServoNum" - number of servos you have.
16// 2. change variable "servoPin" - the pins used by your servos.
17// 3. upload code to Arduino.
18// 4. open serial monitor, use baud rate 9600
19// 5. enter + or - in serial monitor to calibrate servo, there
20//    is a reading printed on the monitor.
21// 6. enter n or l to move to next or last servo.
22//
23// =============================================================
24
25#include <Servo.h>
26
27const int ServoNum = 12;
28
29Servo legServo[ServoNum];
30int servoPos[ServoNum];
31int servoIndex;
32
33int servoPin[ServoNum] = {23, 24, 25,
34                          26, 27, 28,
35                          29, 30, 31,
36                          32, 33, 34};
37
38void setup() {
39
40    Serial.begin(9600);
41    servoIndex = 0;
42
43    // ================  Servos  ==================
44    for (int i=0; i<ServoNum; i++){
45        legServo[i].attach(servoPin[i]);
46        delay(50);
47        legServo[i].writeMicroseconds(1500);
48        servoPos[i] = 1500;
49        delay(100);
50    }
51    delay(500);
52
53    Serial.println("Ready");
54    Serial.println("enter + to increment");
55    Serial.println("enter - to decrement");
56    Serial.println("enter n to proceed to next servo");
57    Serial.println("enter l to go back to last servo");
58
59}
60
61void loop(){
62
63    if ( Serial.available())  {
64        char ch = Serial.read();
65
66        switch(ch){
67            case '+':
68                servoPos[servoIndex] += 3;
69                if(servoPos[servoIndex] >= 2350){
70                    servoIndex = 2350;
71                    Serial.println("You can't turn it up anymore (you might damage it!");
72                }
73                else{
74                    legServo[servoIndex].write(servoPos[servoIndex]);
75                    Serial.println(servoPos[servoIndex]);
76                    delay(100);
77                }
78                break;
79
80            case '-':
81                servoPos[servoIndex] -= 3;
82                if(servoPos[servoIndex] <= 650){
83                    servoIndex = 650;
84                    Serial.println("You can't turn it down anymore (you might damage it!");
85                }
86                else{
87                    legServo[servoIndex].write(servoPos[servoIndex]);
88                    Serial.println(servoPos[servoIndex]);
89                    delay(100);
90                }
91                break;
92
93            case 'n':
94                if(++servoIndex >= 12){
95                    servoIndex = 11;
96                    Serial.println("we have reached last servo");
97                }
98                else{
99                    Serial.print("Switched to Pin ");
100                    Serial.println(servoPin[servoIndex]);
101                }
102                break;
103
104            case 'l':
105                if(--servoIndex < 0){
106                    servoIndex = 0;
107                    Serial.println("we have reached first servo");
108                }
109                else{
110                    Serial.print("Switched to Pin ");
111                    Serial.println(servoPin[servoIndex]);
112                }
113                break;
114
115            default:
116                Serial.println("Unknown Command... ");
117
118        }
119    }
120}
.

Creeping Gait – Update 15/04/2013

Some Background Gait Knowledge you might want to know:
Tonight I came up with a 20-step Creeping Gait. This gait is how 4 legged animals, for example cats, walk.
This is the GaitStep Plan (leg 1 is the top right leg, leg 2 is the bottom right leg… etc…)
This follows the idea about creep gait described here: http://blog.oscarliang.net/quadruped-robot-gait-study/
Quadruped robot gait sequence
Circled steps are the leg-lifting steps, and the gait cycle starts at step one where leg starts to be lifted.
I copied most of the code on how to generate gait sequence from my previous hexapod robot, you can check out the source code. Here is the source code for the gait I have written:
Before we start, we call this function to initialize the variables for the Gait:
1void GaitSelect (){
2
3    //begining of the step cycle for each leg (with reference to the first leg)
4    GaitLegNr[LR] = 1;
5    GaitLegNr[LF] = 6;
6    GaitLegNr[RR] = 11;
7    GaitLegNr[RF] = 16;
8
9    NrLiftedPos = 5;  // number of steps that the leg is in the air
10    TLDivFactor = 15; // number of steps that the leg is on the ground
11    StepsInGait = 20; // total steps
12}
For a complete Gait cycle (e.g. from step 1 to step 20), we will go through loop() function 20 times, each time we call GaitCalculate(), and then increment ‘GaitStep’ variable.
1coor GaitCalculate (){
2    //Calculate Gait positions
3
4    for (int LegIndex = 0; LegIndex < 4; LegIndex++){
5
6        if (GaitStep == GaitLegNr[LegIndex]) {
7            GaitPos[LegIndex].Y = -LegLiftHeight/2;
8        }
9        else if (GaitStep == GaitLegNr[LegIndex]+1) {
10            GaitPos[LegIndex].Z = 0;
11            GaitPos[LegIndex].Y = -LegLiftHeight;
12        }
13        else if (GaitStep == GaitLegNr[LegIndex]+2) {
14            GaitPos[LegIndex].Z = WalkLength/2;
15            GaitPos[LegIndex].Y = -LegLiftHeight/2;
16        }
17        else if (GaitStep == GaitLegNr[LegIndex]+3) {
18            GaitPos[LegIndex].Y = 0;
19        }
20        else{
21        // move body forward
22            GaitPos[LegIndex].Z -= WalkLength/TLDivFactor;
23
24        }
25
26    }
27
28    //Advance to the next step
29    if (++GaitStep > StepsInGait)
30        GaitStep = 1;
31
32}
This is by no mean the best implementation, but it might give you an idea how to start doing gaits if you still have no clue.
I will keep working on Gait, make it more stable, faster, smoother and maybe come up with some more gait style as well, before I publish my full working code.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.