1

Dependencies:   CircularBuffer Radio Servo Terminal mbed

Fork of WalkingRobot by Patrick Clary

Committer:
pclary
Date:
Sat Nov 03 17:20:07 2012 +0000
Revision:
3:6fa07ceb897f
Child:
5:475f67175510
Moved RobotLeg class into the main project and separated it from the matrix stuff.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pclary 3:6fa07ceb897f 1 #include "RobotLeg.h"
pclary 3:6fa07ceb897f 2
pclary 3:6fa07ceb897f 3
pclary 3:6fa07ceb897f 4
pclary 3:6fa07ceb897f 5
pclary 3:6fa07ceb897f 6 RobotLeg::RobotLeg(PinName thetaPin, PinName phiPin, PinName psiPin) : theta(thetaPin), phi(phiPin), psi(psiPin)
pclary 3:6fa07ceb897f 7 {
pclary 3:6fa07ceb897f 8 setDimensions(0.1f, 0.1f, 0.0f, 0.0f);
pclary 3:6fa07ceb897f 9 setAngleOffsets(0.0f, 0.0f, 0.0f);
pclary 3:6fa07ceb897f 10
pclary 3:6fa07ceb897f 11 state = neutral;
pclary 3:6fa07ceb897f 12 stepPeriod = 0.5f;
pclary 3:6fa07ceb897f 13 stepDelta = 3.141593f / stepPeriod;
pclary 3:6fa07ceb897f 14 stepHeight = 0.05f;
pclary 3:6fa07ceb897f 15
pclary 3:6fa07ceb897f 16 position = getPosition();
pclary 3:6fa07ceb897f 17 }
pclary 3:6fa07ceb897f 18
pclary 3:6fa07ceb897f 19
pclary 3:6fa07ceb897f 20
pclary 3:6fa07ceb897f 21 void RobotLeg::setDimensions(float a, float b, float c, float d)
pclary 3:6fa07ceb897f 22 {
pclary 3:6fa07ceb897f 23 this->a = a;
pclary 3:6fa07ceb897f 24 this->b = b;
pclary 3:6fa07ceb897f 25 this->c = c;
pclary 3:6fa07ceb897f 26 this->d = d;
pclary 3:6fa07ceb897f 27 }
pclary 3:6fa07ceb897f 28
pclary 3:6fa07ceb897f 29
pclary 3:6fa07ceb897f 30
pclary 3:6fa07ceb897f 31 void RobotLeg::setAngleOffsets(float oth, float oph, float ops)
pclary 3:6fa07ceb897f 32 {
pclary 3:6fa07ceb897f 33 this->oth = oth;
pclary 3:6fa07ceb897f 34 this->oph = oph;
pclary 3:6fa07ceb897f 35 this->ops = ops;
pclary 3:6fa07ceb897f 36 }
pclary 3:6fa07ceb897f 37
pclary 3:6fa07ceb897f 38
pclary 3:6fa07ceb897f 39
pclary 3:6fa07ceb897f 40 vector3 RobotLeg::getPosition()
pclary 3:6fa07ceb897f 41 {
pclary 3:6fa07ceb897f 42 const float deg2rad = 0.01745329f;
pclary 3:6fa07ceb897f 43 vector3 p;
pclary 3:6fa07ceb897f 44 float L, thetaR, phiR, psiR;
pclary 3:6fa07ceb897f 45
pclary 3:6fa07ceb897f 46 // Convert degrees to radians
pclary 3:6fa07ceb897f 47 thetaR = theta.read() * deg2rad;
pclary 3:6fa07ceb897f 48 phiR = phi.read() * deg2rad;
pclary 3:6fa07ceb897f 49 psiR = psi.read() * deg2rad;
pclary 3:6fa07ceb897f 50
pclary 3:6fa07ceb897f 51 // Calculate forward kinematics
pclary 3:6fa07ceb897f 52 L = a*cos(phiR + oph) + b*sin(phiR + oph + psiR + ops);
pclary 3:6fa07ceb897f 53 p.x = -c*sin(thetaR + oth) + (L + d)*cos(thetaR + oth);
pclary 3:6fa07ceb897f 54 p.y = c*cos(thetaR + oth) + (L + d)*sin(thetaR + oth);
pclary 3:6fa07ceb897f 55 p.z = a*sin(phiR + oph) - b*cos(phiR + oph + psiR + ops);
pclary 3:6fa07ceb897f 56
pclary 3:6fa07ceb897f 57 return p;
pclary 3:6fa07ceb897f 58 }
pclary 3:6fa07ceb897f 59
pclary 3:6fa07ceb897f 60
pclary 3:6fa07ceb897f 61
pclary 3:6fa07ceb897f 62 bool RobotLeg::move(vector3 dest)
pclary 3:6fa07ceb897f 63 {
pclary 3:6fa07ceb897f 64 const float pi2 = 1.5707963;
pclary 3:6fa07ceb897f 65 const float rad2deg = 57.2958;
pclary 3:6fa07ceb897f 66 float L;
pclary 3:6fa07ceb897f 67
pclary 3:6fa07ceb897f 68 // Calculate new angles
pclary 3:6fa07ceb897f 69 L = sqrt(dest.x*dest.x + dest.y*dest.y - c*c) - d;
pclary 3:6fa07ceb897f 70 thetaAngle = atan2( ((L + d)*dest.y - c*dest.x), ((L + d)*dest.x + c*dest.y) ) - oth;
pclary 3:6fa07ceb897f 71 phiAngle = atan2(dest.z, L) + acos((a*a + L*L + dest.z*dest.z - b*b)/(2.f*a*sqrt(L*L + dest.z*dest.z))) - oph;
pclary 3:6fa07ceb897f 72 psiAngle = acos((a*a + b*b - L*L - dest.z*dest.z)/(2*a*b)) - ops - pi2;
pclary 3:6fa07ceb897f 73
pclary 3:6fa07ceb897f 74 // Convert radians to degrees
pclary 3:6fa07ceb897f 75 thetaAngle *= rad2deg;
pclary 3:6fa07ceb897f 76 phiAngle *= rad2deg;
pclary 3:6fa07ceb897f 77 psiAngle *= rad2deg;
pclary 3:6fa07ceb897f 78
pclary 3:6fa07ceb897f 79 // Return true if angle is reachable
pclary 3:6fa07ceb897f 80 if (thetaAngle <= theta.upperLimit && thetaAngle >= theta.lowerLimit &&
pclary 3:6fa07ceb897f 81 phiAngle <= phi.upperLimit && phiAngle >= phi.lowerLimit &&
pclary 3:6fa07ceb897f 82 psiAngle <= psi.upperLimit && psiAngle >= psi.lowerLimit)
pclary 3:6fa07ceb897f 83 {
pclary 3:6fa07ceb897f 84 // Set new angles
pclary 3:6fa07ceb897f 85 theta = thetaAngle;
pclary 3:6fa07ceb897f 86 phi = phiAngle;
pclary 3:6fa07ceb897f 87 psi = psiAngle;
pclary 3:6fa07ceb897f 88
pclary 3:6fa07ceb897f 89 return true;
pclary 3:6fa07ceb897f 90 }
pclary 3:6fa07ceb897f 91 else
pclary 3:6fa07ceb897f 92 {
pclary 3:6fa07ceb897f 93 return false;
pclary 3:6fa07ceb897f 94 }
pclary 3:6fa07ceb897f 95 }
pclary 3:6fa07ceb897f 96
pclary 3:6fa07ceb897f 97
pclary 3:6fa07ceb897f 98
pclary 3:6fa07ceb897f 99 void RobotLeg::step(vector3 dest)
pclary 3:6fa07ceb897f 100 {
pclary 3:6fa07ceb897f 101 stepA = getPosition();
pclary 3:6fa07ceb897f 102 stepB = dest;
pclary 3:6fa07ceb897f 103
pclary 3:6fa07ceb897f 104 stepTimer.reset();
pclary 3:6fa07ceb897f 105 stepTimer.start();
pclary 3:6fa07ceb897f 106 state = stepping;
pclary 3:6fa07ceb897f 107 }
pclary 3:6fa07ceb897f 108
pclary 3:6fa07ceb897f 109
pclary 3:6fa07ceb897f 110
pclary 3:6fa07ceb897f 111 void RobotLeg::update(const matrix4& deltaTransform)
pclary 3:6fa07ceb897f 112 {
pclary 3:6fa07ceb897f 113 float t;
pclary 3:6fa07ceb897f 114 vector3 newPosition;
pclary 3:6fa07ceb897f 115
pclary 3:6fa07ceb897f 116 switch (state)
pclary 3:6fa07ceb897f 117 {
pclary 3:6fa07ceb897f 118 case neutral:
pclary 3:6fa07ceb897f 119 position = deltaTransform*position;
pclary 3:6fa07ceb897f 120 if (!move(position))
pclary 3:6fa07ceb897f 121 {
pclary 3:6fa07ceb897f 122 // Eventually, use the inverse matrix to calculate the reverse path
pclary 3:6fa07ceb897f 123 step(vector3(0.1f, 0.15f, -0.05f));
pclary 3:6fa07ceb897f 124 }
pclary 3:6fa07ceb897f 125 break;
pclary 3:6fa07ceb897f 126
pclary 3:6fa07ceb897f 127 case stepping:
pclary 3:6fa07ceb897f 128 t = stepTimer.read();
pclary 3:6fa07ceb897f 129 newPosition.x = stepA.x + (stepB.x - stepA.x)*0.5f*(1 - cos(stepDelta*t));
pclary 3:6fa07ceb897f 130 newPosition.y = stepA.y + (stepB.y - stepA.y)*0.5f*(1 - cos(stepDelta*t));
pclary 3:6fa07ceb897f 131 newPosition.z = stepA.z + (stepB.z - stepA.z)*stepDelta*t + stepHeight*sin(stepDelta*t);
pclary 3:6fa07ceb897f 132
pclary 3:6fa07ceb897f 133 if (t < stepPeriod)
pclary 3:6fa07ceb897f 134 {
pclary 3:6fa07ceb897f 135 move(newPosition);
pclary 3:6fa07ceb897f 136 }
pclary 3:6fa07ceb897f 137 else
pclary 3:6fa07ceb897f 138 {
pclary 3:6fa07ceb897f 139 move(stepB);
pclary 3:6fa07ceb897f 140 state = neutral;
pclary 3:6fa07ceb897f 141 stepTimer.stop();
pclary 3:6fa07ceb897f 142 position = getPosition();
pclary 3:6fa07ceb897f 143 }
pclary 3:6fa07ceb897f 144 break;
pclary 3:6fa07ceb897f 145 }
pclary 3:6fa07ceb897f 146 }