Control program for a four-legged 12 axis robot.

Dependencies:   CircularBuffer Servo Terminal mbed Radio

Committer:
pclary
Date:
Wed May 15 17:22:22 2013 +0000
Revision:
11:9ee0214bd410
Parent:
10:dc1ba352667e
Child:
12:a952bd74d363
Changed synchronization method to block instead of reset

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pclary 0:449568595ed9 1 #include "mbed.h"
pclary 0:449568595ed9 2 #include "RobotLeg.h"
pclary 3:6fa07ceb897f 3 #include "Matrix.h"
pclary 2:caf73a1d7827 4 #include "CircularBuffer.h"
pclary 5:475f67175510 5 #include "Radio.h"
pclary 6:0163f2737cc6 6 #include "Terminal.h"
pclary 9:a6d1502f0f20 7 #include "utility.h"
pclary 0:449568595ed9 8 #include <cstring>
pclary 6:0163f2737cc6 9 #include <cmath>
pclary 0:449568595ed9 10
pclary 6:0163f2737cc6 11 #define MAXSPEED 0.1f
pclary 6:0163f2737cc6 12 #define MAXTURN 1.0f
pclary 8:db453051f3f4 13 #define RESET_STEP_TIME 0.4f
pclary 8:db453051f3f4 14 #define DIM_A 0.125f
pclary 8:db453051f3f4 15 #define DIM_B 0.11f
pclary 8:db453051f3f4 16 #define DIM_C 0.0025f
pclary 8:db453051f3f4 17 #define DIM_D 0.025f
pclary 8:db453051f3f4 18 #define CIRCLE_X 0.095f
pclary 8:db453051f3f4 19 #define CIRCLE_Y 0.095f
pclary 8:db453051f3f4 20 #define CIRCLE_Z -0.12f
pclary 8:db453051f3f4 21 #define CIRCLE_R 0.09f
pclary 11:9ee0214bd410 22 #define PERIOD 0.002f
pclary 6:0163f2737cc6 23
pclary 11:9ee0214bd410 24
pclary 0:449568595ed9 25
pclary 3:6fa07ceb897f 26 CircularBuffer<float,16> dataLog;
pclary 9:a6d1502f0f20 27 Radio radio(p5, p6, p7, p16, p17, p18);
pclary 11:9ee0214bd410 28 RobotLeg legA(p26, p29, p30, false);
pclary 8:db453051f3f4 29 RobotLeg legB(p13, p14, p15, false);
pclary 11:9ee0214bd410 30 RobotLeg legC(p19, p11, p8, false);
pclary 11:9ee0214bd410 31 RobotLeg legD(p25, p24, p23, false);
pclary 6:0163f2737cc6 32
pclary 6:0163f2737cc6 33
pclary 6:0163f2737cc6 34
pclary 6:0163f2737cc6 35 CmdHandler* log(Terminal* terminal, const char* input)
pclary 6:0163f2737cc6 36 {
pclary 6:0163f2737cc6 37 int start = 0;
pclary 6:0163f2737cc6 38 int end = 15;
pclary 6:0163f2737cc6 39 char output[256];
pclary 6:0163f2737cc6 40
pclary 6:0163f2737cc6 41 if (sscanf(input, "log %d %d", &start, &end) == 1)
pclary 6:0163f2737cc6 42 {
pclary 6:0163f2737cc6 43 // Print only one item
pclary 6:0163f2737cc6 44 sprintf(output, "%4d: %f\n", start, dataLog[start]);
pclary 6:0163f2737cc6 45 terminal->write(output);
pclary 6:0163f2737cc6 46 }
pclary 6:0163f2737cc6 47 else
pclary 6:0163f2737cc6 48 {
pclary 6:0163f2737cc6 49 // Print a range of items
pclary 6:0163f2737cc6 50 for (int i = start; i <= end; i++)
pclary 6:0163f2737cc6 51 {
pclary 6:0163f2737cc6 52 sprintf(output, "%4d: %f\n", i, dataLog[i]);
pclary 6:0163f2737cc6 53 terminal->write(output);
pclary 6:0163f2737cc6 54 }
pclary 6:0163f2737cc6 55 }
pclary 6:0163f2737cc6 56
pclary 6:0163f2737cc6 57 return NULL;
pclary 8:db453051f3f4 58 } // log()
pclary 6:0163f2737cc6 59
pclary 6:0163f2737cc6 60
pclary 6:0163f2737cc6 61
pclary 6:0163f2737cc6 62 int deadzone(int input, int zone)
pclary 6:0163f2737cc6 63 {
pclary 6:0163f2737cc6 64 if (input > zone) return input;
pclary 6:0163f2737cc6 65 else if (input < -zone) return input;
pclary 6:0163f2737cc6 66 else return 0;
pclary 8:db453051f3f4 67 } // deadzone()
pclary 6:0163f2737cc6 68
pclary 6:0163f2737cc6 69
pclary 6:0163f2737cc6 70
pclary 6:0163f2737cc6 71 void resetLegs()
pclary 6:0163f2737cc6 72 {
pclary 11:9ee0214bd410 73 legA.reset(-0.6f);
pclary 11:9ee0214bd410 74 legB.reset(-0.1f);
pclary 11:9ee0214bd410 75 legC.reset(0.4f);
pclary 11:9ee0214bd410 76 legD.reset(0.9f);
pclary 8:db453051f3f4 77 } // resetLegs()
pclary 8:db453051f3f4 78
pclary 8:db453051f3f4 79
pclary 8:db453051f3f4 80
pclary 11:9ee0214bd410 81 void setupLegs();
pclary 0:449568595ed9 82
pclary 0:449568595ed9 83
pclary 0:449568595ed9 84
pclary 0:449568595ed9 85 int main()
pclary 0:449568595ed9 86 {
pclary 9:a6d1502f0f20 87 Timer deltaTimer;
pclary 10:dc1ba352667e 88 float xaxis, yaxis, turnaxis, angle;
pclary 11:9ee0214bd410 89 float deltaTime;
pclary 2:caf73a1d7827 90 vector3 v;
pclary 5:475f67175510 91 matrix4 T;
pclary 5:475f67175510 92 matrix4 PA, QA;
pclary 5:475f67175510 93 matrix4 PB, QB;
pclary 5:475f67175510 94 matrix4 PC, QC;
pclary 6:0163f2737cc6 95 matrix4 PD, QD;
pclary 0:449568595ed9 96 Terminal terminal;
pclary 2:caf73a1d7827 97
pclary 2:caf73a1d7827 98 terminal.addCommand("log", &log);
pclary 2:caf73a1d7827 99
pclary 6:0163f2737cc6 100 radio.reset();
pclary 6:0163f2737cc6 101
pclary 11:9ee0214bd410 102 setupLegs();
pclary 11:9ee0214bd410 103
pclary 11:9ee0214bd410 104 // Create matrices to change base from robot coordinates to leg coordinates
pclary 11:9ee0214bd410 105 QA.translate(vector3(0.1f, 0.1f, 0.0f));
pclary 11:9ee0214bd410 106 PA = QA.inverse();
pclary 11:9ee0214bd410 107 QB.translate(vector3(-0.1f, -0.1f, 0.0f));
pclary 11:9ee0214bd410 108 QB.a11 = -1.0f; QB.a22 = -1.0f;
pclary 11:9ee0214bd410 109 PB = QB.inverse();
pclary 11:9ee0214bd410 110 QC.translate(vector3(0.1f, -0.1f, 0.0f));
pclary 11:9ee0214bd410 111 QC.a11 = -1.0f;
pclary 11:9ee0214bd410 112 PC = QC.inverse();
pclary 11:9ee0214bd410 113 QD.translate(vector3(-0.1f, 0.1f, 0.0f));
pclary 11:9ee0214bd410 114 QD.a22 = -1.0f;
pclary 11:9ee0214bd410 115 PD = QD.inverse();
pclary 11:9ee0214bd410 116
pclary 11:9ee0214bd410 117 // Start timer
pclary 11:9ee0214bd410 118 deltaTimer.start();
pclary 11:9ee0214bd410 119
pclary 11:9ee0214bd410 120 while(true)
pclary 11:9ee0214bd410 121 {
pclary 11:9ee0214bd410 122 while (deltaTimer.read() < PERIOD);
pclary 11:9ee0214bd410 123
pclary 11:9ee0214bd410 124 // Read controller input
pclary 11:9ee0214bd410 125 xaxis = 0.0078125f * deadzone((int8_t)((radio.rx_controller>>0)&0xff), 8); // Convert to +/-1.0f range
pclary 11:9ee0214bd410 126 yaxis = -0.0078125f * deadzone((int8_t)((radio.rx_controller>>8)&0xff), 8);
pclary 11:9ee0214bd410 127 turnaxis = -0.0078125f * deadzone((int8_t)((radio.rx_controller>>16)&0xff), 8);
pclary 11:9ee0214bd410 128
pclary 11:9ee0214bd410 129 // Get delta-time
pclary 11:9ee0214bd410 130 deltaTime = deltaTimer.read();
pclary 11:9ee0214bd410 131 deltaTimer.reset();
pclary 11:9ee0214bd410 132 dataLog.push(deltaTime);
pclary 11:9ee0214bd410 133
pclary 11:9ee0214bd410 134 // Compute delta movement vector and delta angle
pclary 11:9ee0214bd410 135 v.x = -xaxis;
pclary 11:9ee0214bd410 136 v.y = -yaxis;
pclary 11:9ee0214bd410 137 v.z = 0;
pclary 11:9ee0214bd410 138 v = v * MAXSPEED * deltaTime;
pclary 11:9ee0214bd410 139 angle = -turnaxis * MAXTURN * deltaTime;
pclary 11:9ee0214bd410 140
pclary 11:9ee0214bd410 141 // Compute movement transformation in robot coordinates
pclary 11:9ee0214bd410 142 T.identity().rotateZ(angle).translate(v).inverse();
pclary 11:9ee0214bd410 143
pclary 11:9ee0214bd410 144 bool stepping = legA.getStepping() || legB.getStepping() || legC.getStepping() || legD.getStepping();
pclary 11:9ee0214bd410 145 bool lockup = false;
pclary 11:9ee0214bd410 146
pclary 11:9ee0214bd410 147 if (!legA.update(PA*T*QA))
pclary 11:9ee0214bd410 148 {
pclary 11:9ee0214bd410 149 if (stepping) lockup = true;
pclary 11:9ee0214bd410 150 else
pclary 11:9ee0214bd410 151 {
pclary 11:9ee0214bd410 152 legA.reset(0.8);
pclary 11:9ee0214bd410 153 stepping = true;
pclary 11:9ee0214bd410 154 }
pclary 11:9ee0214bd410 155 }
pclary 11:9ee0214bd410 156 if (!legB.update(PB*T*QB))
pclary 11:9ee0214bd410 157 {
pclary 11:9ee0214bd410 158 if (stepping) lockup = true;
pclary 11:9ee0214bd410 159 else
pclary 11:9ee0214bd410 160 {
pclary 11:9ee0214bd410 161 legB.reset(0.8f);
pclary 11:9ee0214bd410 162 stepping = true;
pclary 11:9ee0214bd410 163 }
pclary 11:9ee0214bd410 164 }
pclary 11:9ee0214bd410 165 if (!legC.update(PC*T*QC))
pclary 11:9ee0214bd410 166 {
pclary 11:9ee0214bd410 167 if (stepping) lockup = true;
pclary 11:9ee0214bd410 168 else
pclary 11:9ee0214bd410 169 {
pclary 11:9ee0214bd410 170 legC.reset(0.8f);
pclary 11:9ee0214bd410 171 stepping = true;
pclary 11:9ee0214bd410 172 }
pclary 11:9ee0214bd410 173 }
pclary 11:9ee0214bd410 174 if (!legD.update(PD*T*QD))
pclary 11:9ee0214bd410 175 {
pclary 11:9ee0214bd410 176 if (stepping) lockup = true;
pclary 11:9ee0214bd410 177 else
pclary 11:9ee0214bd410 178 {
pclary 11:9ee0214bd410 179 legD.reset(0.8f);
pclary 11:9ee0214bd410 180 stepping = true;
pclary 11:9ee0214bd410 181 }
pclary 11:9ee0214bd410 182 }
pclary 11:9ee0214bd410 183
pclary 11:9ee0214bd410 184 if (!lockup)
pclary 11:9ee0214bd410 185 {
pclary 11:9ee0214bd410 186 legA.apply();
pclary 11:9ee0214bd410 187 legB.apply();
pclary 11:9ee0214bd410 188 legC.apply();
pclary 11:9ee0214bd410 189 legD.apply();
pclary 11:9ee0214bd410 190 }
pclary 11:9ee0214bd410 191 } // while (true)
pclary 11:9ee0214bd410 192 } // main()
pclary 11:9ee0214bd410 193
pclary 11:9ee0214bd410 194
pclary 11:9ee0214bd410 195
pclary 11:9ee0214bd410 196 void setupLegs()
pclary 11:9ee0214bd410 197 {
pclary 0:449568595ed9 198 // Set leg parameters
pclary 8:db453051f3f4 199 legA.setDimensions(DIM_A, DIM_B, DIM_C, DIM_D);
pclary 8:db453051f3f4 200 legB.setDimensions(DIM_A, DIM_B, DIM_C, DIM_D);
pclary 8:db453051f3f4 201 legC.setDimensions(DIM_A, DIM_B, DIM_C, DIM_D);
pclary 8:db453051f3f4 202 legD.setDimensions(DIM_A, DIM_B, DIM_C, DIM_D);
pclary 5:475f67175510 203 legA.setAngleOffsets(0.7853982f, 0.0f, 0.0f);
pclary 5:475f67175510 204 legB.setAngleOffsets(0.7853982f, 0.0f, 0.0f);
pclary 5:475f67175510 205 legC.setAngleOffsets(0.7853982f, 0.0f, 0.0f);
pclary 5:475f67175510 206 legD.setAngleOffsets(0.7853982f, 0.0f, 0.0f);
pclary 8:db453051f3f4 207 legA.setStepCircle(CIRCLE_X, CIRCLE_Y, CIRCLE_Z, CIRCLE_R);
pclary 8:db453051f3f4 208 legB.setStepCircle(CIRCLE_X, CIRCLE_Y, CIRCLE_Z, CIRCLE_R);
pclary 8:db453051f3f4 209 legC.setStepCircle(CIRCLE_X, CIRCLE_Y, CIRCLE_Z, CIRCLE_R);
pclary 8:db453051f3f4 210 legD.setStepCircle(CIRCLE_X, CIRCLE_Y, CIRCLE_Z, CIRCLE_R);
pclary 11:9ee0214bd410 211 legA.theta.calibrate(1130, 2060, 45.0f, -45.0f);
pclary 11:9ee0214bd410 212 legA.phi.calibrate(1200, 2050, 70.0f, -45.0f);
pclary 11:9ee0214bd410 213 legA.psi.calibrate(2020, 1050, 70.0f, -60.0f);
pclary 11:9ee0214bd410 214 legB.theta.calibrate(980, 1930, 45.0f, -45.0f);
pclary 11:9ee0214bd410 215 legB.phi.calibrate(1120, 2030, 70.0f, -45.0f);
pclary 11:9ee0214bd410 216 legB.psi.calibrate(2070, 1170, 70.0f, -60.0f);
pclary 5:475f67175510 217 legC.theta.calibrate(2000, 1000, 45.0f, -45.0f);
pclary 11:9ee0214bd410 218 legC.phi.calibrate(1930, 1050, 70.0f, -45.0f);
pclary 11:9ee0214bd410 219 legC.psi.calibrate(1100, 2000, 70.0f, -60.0f);
pclary 11:9ee0214bd410 220 legD.theta.calibrate(2000, 1070, 45.0f, -45.0f);
pclary 11:9ee0214bd410 221 legD.phi.calibrate(1930, 1050, 70.0f, -45.0f);
pclary 11:9ee0214bd410 222 legD.psi.calibrate(1020, 1900, 70.0f, -60.0f);
pclary 6:0163f2737cc6 223
pclary 6:0163f2737cc6 224 // Initialize leg position deltas
pclary 6:0163f2737cc6 225 legA.nDeltaPosition = vector3(0.0f, 0.01f, 0.0f);
pclary 6:0163f2737cc6 226 legB.nDeltaPosition = vector3(0.0f, -0.01f, 0.0f);
pclary 6:0163f2737cc6 227 legC.nDeltaPosition = vector3(0.0f, 0.01f, 0.0f);
pclary 6:0163f2737cc6 228 legD.nDeltaPosition = vector3(0.0f, -0.01f, 0.0f);
pclary 8:db453051f3f4 229
pclary 2:caf73a1d7827 230 // Go to initial position
pclary 9:a6d1502f0f20 231 legA.move(vector3(0.15f, 0.15f, 0.05f));
pclary 9:a6d1502f0f20 232 legB.move(vector3(0.15f, 0.15f, 0.05f));
pclary 9:a6d1502f0f20 233 legC.move(vector3(0.15f, 0.15f, 0.05f));
pclary 9:a6d1502f0f20 234 legD.move(vector3(0.15f, 0.15f, 0.05f));
pclary 8:db453051f3f4 235 legA.theta.enable(); wait(0.1f);
pclary 8:db453051f3f4 236 legB.theta.enable(); wait(0.1f);
pclary 8:db453051f3f4 237 legC.theta.enable(); wait(0.1f);
pclary 8:db453051f3f4 238 legD.theta.enable(); wait(0.1f);
pclary 8:db453051f3f4 239 legA.phi.enable(); wait(0.1f);
pclary 8:db453051f3f4 240 legB.phi.enable(); wait(0.1f);
pclary 8:db453051f3f4 241 legC.phi.enable(); wait(0.1f);
pclary 8:db453051f3f4 242 legD.phi.enable(); wait(0.1f);
pclary 8:db453051f3f4 243 legA.psi.enable(); wait(0.1f);
pclary 8:db453051f3f4 244 legB.psi.enable(); wait(0.1f);
pclary 8:db453051f3f4 245 legC.psi.enable(); wait(0.1f);
pclary 8:db453051f3f4 246 legD.psi.enable(); wait(0.1f);
pclary 9:a6d1502f0f20 247 wait(0.4f);
pclary 6:0163f2737cc6 248 resetLegs();
pclary 11:9ee0214bd410 249 }