1

Dependencies:   CircularBuffer Radio Servo Terminal mbed

Fork of WalkingRobot by Patrick Clary

Committer:
alex03
Date:
Tue Apr 09 01:40:27 2013 +0000
Revision:
11:975d24305af7
Parent:
10:dc1ba352667e
g

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 8:db453051f3f4 6 RobotLeg::RobotLeg(PinName thetaPin, PinName phiPin, PinName psiPin, bool start) : theta(thetaPin, start), phi(phiPin, start), psi(psiPin, start)
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 6:0163f2737cc6 12 stepTime = 0.4f;
pclary 6:0163f2737cc6 13 stepDelta = 3.141593f / stepTime;
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 5:475f67175510 40 void RobotLeg::setStepCircle(float xc, float yc, float zc, float rc)
pclary 5:475f67175510 41 {
pclary 5:475f67175510 42 circleCenter = vector3(xc, yc, zc);
pclary 5:475f67175510 43 circleRadius = rc;
pclary 5:475f67175510 44 }
pclary 5:475f67175510 45
pclary 5:475f67175510 46
pclary 5:475f67175510 47
pclary 3:6fa07ceb897f 48 vector3 RobotLeg::getPosition()
pclary 3:6fa07ceb897f 49 {
pclary 3:6fa07ceb897f 50 const float deg2rad = 0.01745329f;
pclary 3:6fa07ceb897f 51 vector3 p;
pclary 3:6fa07ceb897f 52 float L, thetaR, phiR, psiR;
pclary 3:6fa07ceb897f 53
pclary 3:6fa07ceb897f 54 // Convert degrees to radians
pclary 3:6fa07ceb897f 55 thetaR = theta.read() * deg2rad;
pclary 3:6fa07ceb897f 56 phiR = phi.read() * deg2rad;
pclary 3:6fa07ceb897f 57 psiR = psi.read() * deg2rad;
pclary 3:6fa07ceb897f 58
pclary 3:6fa07ceb897f 59 // Calculate forward kinematics
pclary 3:6fa07ceb897f 60 L = a*cos(phiR + oph) + b*sin(phiR + oph + psiR + ops);
pclary 3:6fa07ceb897f 61 p.x = -c*sin(thetaR + oth) + (L + d)*cos(thetaR + oth);
pclary 3:6fa07ceb897f 62 p.y = c*cos(thetaR + oth) + (L + d)*sin(thetaR + oth);
pclary 3:6fa07ceb897f 63 p.z = a*sin(phiR + oph) - b*cos(phiR + oph + psiR + ops);
pclary 3:6fa07ceb897f 64
pclary 3:6fa07ceb897f 65 return p;
pclary 3:6fa07ceb897f 66 }
pclary 3:6fa07ceb897f 67
pclary 3:6fa07ceb897f 68
pclary 3:6fa07ceb897f 69
pclary 3:6fa07ceb897f 70 bool RobotLeg::move(vector3 dest)
pclary 3:6fa07ceb897f 71 {
pclary 3:6fa07ceb897f 72 const float pi2 = 1.5707963;
pclary 3:6fa07ceb897f 73 const float rad2deg = 57.2958;
pclary 3:6fa07ceb897f 74 float L;
pclary 3:6fa07ceb897f 75
pclary 3:6fa07ceb897f 76 // Calculate new angles
pclary 3:6fa07ceb897f 77 L = sqrt(dest.x*dest.x + dest.y*dest.y - c*c) - d;
pclary 3:6fa07ceb897f 78 thetaAngle = atan2( ((L + d)*dest.y - c*dest.x), ((L + d)*dest.x + c*dest.y) ) - oth;
pclary 3:6fa07ceb897f 79 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 80 psiAngle = acos((a*a + b*b - L*L - dest.z*dest.z)/(2*a*b)) - ops - pi2;
pclary 3:6fa07ceb897f 81
pclary 3:6fa07ceb897f 82 // Convert radians to degrees
pclary 3:6fa07ceb897f 83 thetaAngle *= rad2deg;
pclary 3:6fa07ceb897f 84 phiAngle *= rad2deg;
pclary 3:6fa07ceb897f 85 psiAngle *= rad2deg;
pclary 3:6fa07ceb897f 86
pclary 3:6fa07ceb897f 87 // Return true if angle is reachable
pclary 3:6fa07ceb897f 88 if (thetaAngle <= theta.upperLimit && thetaAngle >= theta.lowerLimit &&
pclary 3:6fa07ceb897f 89 phiAngle <= phi.upperLimit && phiAngle >= phi.lowerLimit &&
pclary 3:6fa07ceb897f 90 psiAngle <= psi.upperLimit && psiAngle >= psi.lowerLimit)
pclary 3:6fa07ceb897f 91 {
pclary 3:6fa07ceb897f 92 // Set new angles
pclary 3:6fa07ceb897f 93 theta = thetaAngle;
pclary 3:6fa07ceb897f 94 phi = phiAngle;
pclary 3:6fa07ceb897f 95 psi = psiAngle;
pclary 3:6fa07ceb897f 96
pclary 3:6fa07ceb897f 97 return true;
pclary 3:6fa07ceb897f 98 }
pclary 3:6fa07ceb897f 99 else
pclary 3:6fa07ceb897f 100 {
pclary 3:6fa07ceb897f 101 return false;
pclary 3:6fa07ceb897f 102 }
pclary 3:6fa07ceb897f 103 }
pclary 3:6fa07ceb897f 104
pclary 3:6fa07ceb897f 105
pclary 3:6fa07ceb897f 106
pclary 3:6fa07ceb897f 107 void RobotLeg::step(vector3 dest)
pclary 3:6fa07ceb897f 108 {
pclary 3:6fa07ceb897f 109 stepA = getPosition();
pclary 3:6fa07ceb897f 110 stepB = dest;
pclary 3:6fa07ceb897f 111
pclary 3:6fa07ceb897f 112 stepTimer.reset();
pclary 3:6fa07ceb897f 113 stepTimer.start();
pclary 3:6fa07ceb897f 114 state = stepping;
pclary 3:6fa07ceb897f 115 }
pclary 3:6fa07ceb897f 116
pclary 3:6fa07ceb897f 117
pclary 3:6fa07ceb897f 118
pclary 9:a6d1502f0f20 119 vector3 RobotLeg::reset(float f)
pclary 5:475f67175510 120 {
pclary 5:475f67175510 121 vector3 newPosition;
pclary 5:475f67175510 122 newPosition = circleCenter + nDeltaPosition.unit() * circleRadius * f;
pclary 5:475f67175510 123 step(newPosition);
pclary 9:a6d1502f0f20 124 return nDeltaPosition;
pclary 5:475f67175510 125 }
pclary 5:475f67175510 126
pclary 5:475f67175510 127
pclary 5:475f67175510 128
pclary 5:475f67175510 129 bool RobotLeg::update(const matrix4& deltaTransform)
pclary 3:6fa07ceb897f 130 {
pclary 10:dc1ba352667e 131 float t, d;
pclary 10:dc1ba352667e 132 vector3 newPosition, newNDeltaPosition, v;
pclary 9:a6d1502f0f20 133 const float eps = 0.000001f;
pclary 3:6fa07ceb897f 134
pclary 3:6fa07ceb897f 135 switch (state)
pclary 3:6fa07ceb897f 136 {
pclary 3:6fa07ceb897f 137 case neutral:
pclary 10:dc1ba352667e 138 // Calculate new position and position delta
pclary 5:475f67175510 139 newPosition = deltaTransform*position;
pclary 9:a6d1502f0f20 140 newNDeltaPosition = position - newPosition;
pclary 9:a6d1502f0f20 141 if (fabs(newNDeltaPosition.x) > eps || fabs(newNDeltaPosition.y) > eps || fabs(newNDeltaPosition.z) > eps)
pclary 9:a6d1502f0f20 142 nDeltaPosition = newNDeltaPosition;
pclary 5:475f67175510 143 position = newPosition;
pclary 10:dc1ba352667e 144
pclary 10:dc1ba352667e 145 // Check if new position is outside the step circle
pclary 10:dc1ba352667e 146 v = position - circleCenter;
pclary 10:dc1ba352667e 147 d = sqrt(v.x*v.x + v.y*v.y);
pclary 10:dc1ba352667e 148
pclary 10:dc1ba352667e 149 // Attempt to move to the new position
pclary 10:dc1ba352667e 150 if (!move(position) || d > circleRadius) return false;
pclary 10:dc1ba352667e 151
pclary 3:6fa07ceb897f 152 break;
pclary 3:6fa07ceb897f 153
pclary 3:6fa07ceb897f 154 case stepping:
pclary 10:dc1ba352667e 155 // Compute new position along step trajectory
pclary 3:6fa07ceb897f 156 t = stepTimer.read();
pclary 3:6fa07ceb897f 157 newPosition.x = stepA.x + (stepB.x - stepA.x)*0.5f*(1 - cos(stepDelta*t));
pclary 3:6fa07ceb897f 158 newPosition.y = stepA.y + (stepB.y - stepA.y)*0.5f*(1 - cos(stepDelta*t));
pclary 3:6fa07ceb897f 159 newPosition.z = stepA.z + (stepB.z - stepA.z)*stepDelta*t + stepHeight*sin(stepDelta*t);
pclary 3:6fa07ceb897f 160
pclary 6:0163f2737cc6 161 if (t < stepTime)
pclary 3:6fa07ceb897f 162 {
pclary 3:6fa07ceb897f 163 move(newPosition);
pclary 3:6fa07ceb897f 164 }
pclary 3:6fa07ceb897f 165 else
pclary 3:6fa07ceb897f 166 {
pclary 3:6fa07ceb897f 167 move(stepB);
pclary 3:6fa07ceb897f 168 state = neutral;
pclary 3:6fa07ceb897f 169 stepTimer.stop();
pclary 3:6fa07ceb897f 170 position = getPosition();
pclary 3:6fa07ceb897f 171 }
pclary 3:6fa07ceb897f 172 break;
pclary 3:6fa07ceb897f 173 }
pclary 5:475f67175510 174
pclary 5:475f67175510 175 return true;
pclary 3:6fa07ceb897f 176 }