1

Dependencies:   CircularBuffer Radio Servo Terminal mbed

Fork of WalkingRobot by Patrick Clary

Committer:
pclary
Date:
Thu Jan 17 18:34:09 2013 +0000
Revision:
8:db453051f3f4
Parent:
7:aac5f901bd76
Child:
9:a6d1502f0f20
Changed leg position initialization and resynchronization routines.

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 5:475f67175510 119 void 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 5:475f67175510 124 }
pclary 5:475f67175510 125
pclary 5:475f67175510 126
pclary 5:475f67175510 127
pclary 5:475f67175510 128 bool RobotLeg::update(const matrix4& deltaTransform)
pclary 3:6fa07ceb897f 129 {
pclary 3:6fa07ceb897f 130 float t;
pclary 3:6fa07ceb897f 131 vector3 newPosition;
pclary 3:6fa07ceb897f 132
pclary 3:6fa07ceb897f 133 switch (state)
pclary 3:6fa07ceb897f 134 {
pclary 3:6fa07ceb897f 135 case neutral:
pclary 5:475f67175510 136 newPosition = deltaTransform*position;
pclary 5:475f67175510 137 nDeltaPosition = position - newPosition;
pclary 5:475f67175510 138 position = newPosition;
pclary 3:6fa07ceb897f 139 if (!move(position))
pclary 3:6fa07ceb897f 140 {
pclary 5:475f67175510 141 return false;
pclary 3:6fa07ceb897f 142 }
pclary 3:6fa07ceb897f 143 break;
pclary 3:6fa07ceb897f 144
pclary 3:6fa07ceb897f 145 case stepping:
pclary 3:6fa07ceb897f 146 t = stepTimer.read();
pclary 3:6fa07ceb897f 147 newPosition.x = stepA.x + (stepB.x - stepA.x)*0.5f*(1 - cos(stepDelta*t));
pclary 3:6fa07ceb897f 148 newPosition.y = stepA.y + (stepB.y - stepA.y)*0.5f*(1 - cos(stepDelta*t));
pclary 3:6fa07ceb897f 149 newPosition.z = stepA.z + (stepB.z - stepA.z)*stepDelta*t + stepHeight*sin(stepDelta*t);
pclary 3:6fa07ceb897f 150
pclary 6:0163f2737cc6 151 if (t < stepTime)
pclary 3:6fa07ceb897f 152 {
pclary 3:6fa07ceb897f 153 move(newPosition);
pclary 3:6fa07ceb897f 154 }
pclary 3:6fa07ceb897f 155 else
pclary 3:6fa07ceb897f 156 {
pclary 3:6fa07ceb897f 157 move(stepB);
pclary 3:6fa07ceb897f 158 state = neutral;
pclary 3:6fa07ceb897f 159 stepTimer.stop();
pclary 3:6fa07ceb897f 160 position = getPosition();
pclary 3:6fa07ceb897f 161 }
pclary 3:6fa07ceb897f 162 break;
pclary 3:6fa07ceb897f 163 }
pclary 5:475f67175510 164
pclary 5:475f67175510 165 return true;
pclary 3:6fa07ceb897f 166 }