Library for analyitical inverse kinematics on 4-legged 3DOF per leg quadrupod robots. Easily modifyable for more legs.

Dependents:   Quadrapod NeoQuadrapod

Committer:
ikrase
Date:
Fri Jun 26 04:21:43 2015 +0000
Revision:
1:031a0c78d8d6
Parent:
0:9805c9d36254
Child:
2:6214ab5b94cb
Finished library, not yet tested.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ikrase 0:9805c9d36254 1 #include "mbed.h"
ikrase 0:9805c9d36254 2 #include "quadrapod_defs.h"
ikrase 0:9805c9d36254 3 #include "ArthropodIK.h"
ikrase 0:9805c9d36254 4
ikrase 0:9805c9d36254 5 float sq(float n1){
ikrase 0:9805c9d36254 6 float res = n1 * n1;
ikrase 0:9805c9d36254 7 return res;
ikrase 0:9805c9d36254 8 }
ikrase 0:9805c9d36254 9
ikrase 0:9805c9d36254 10
ikrase 0:9805c9d36254 11 const float ArthropodSolver::LEG_ANGLES[4] = {0.78539816339, 2.35619449019, -2.35619449019, -0.78539816339, };
ikrase 0:9805c9d36254 12
ikrase 0:9805c9d36254 13
ikrase 0:9805c9d36254 14 ArthropodSolver::ArthropodSolver() // Constuctor initializes thing.
ikrase 0:9805c9d36254 15 {
ikrase 0:9805c9d36254 16
ikrase 0:9805c9d36254 17
ikrase 0:9805c9d36254 18 }
ikrase 0:9805c9d36254 19
ikrase 0:9805c9d36254 20
ikrase 0:9805c9d36254 21 leg_angles_t ArthropodSolver::SolveLeg(float LegTargetXYZ[], int LegNum)
ikrase 0:9805c9d36254 22 {
ikrase 0:9805c9d36254 23 leg_angles_t angles_out;
ikrase 0:9805c9d36254 24
ikrase 0:9805c9d36254 25 angles_out.gamma = atan2(LegTargetXYZ[1], LegTargetXYZ[0]) - LEG_ANGLES[LegNum];
ikrase 0:9805c9d36254 26
ikrase 0:9805c9d36254 27 float lp = sqrt(sq(LegTargetXYZ[0]) + sq(LegTargetXYZ[1]));
ikrase 0:9805c9d36254 28
ikrase 0:9805c9d36254 29 float L2 = sq(LegTargetXYZ[2]) + sq(lp - COXA_L);
ikrase 0:9805c9d36254 30 float a1 = acos(-LegTargetXYZ[2] / sqrt(L2));
ikrase 0:9805c9d36254 31 float a2 = acos((sq(TIBIA_L)-sq(FEMUR_L)-L2)/(-2*FEMUR_L*sqrt(L2)));
ikrase 0:9805c9d36254 32 angles_out.alpha = a1 + a2;
ikrase 0:9805c9d36254 33 angles_out.beta = acos((-sq(TIBIA_L)-sq(FEMUR_L)+L2)/(-2*FEMUR_L*TIBIA_L));
ikrase 0:9805c9d36254 34
ikrase 0:9805c9d36254 35
ikrase 0:9805c9d36254 36 // IK code, the most basic section.
ikrase 0:9805c9d36254 37
ikrase 0:9805c9d36254 38
ikrase 0:9805c9d36254 39 return angles_out; // THIS WILL OVERWRITE WITH MULTIPLE CALLS!!!!!!
ikrase 0:9805c9d36254 40 }
ikrase 0:9805c9d36254 41
ikrase 0:9805c9d36254 42
ikrase 0:9805c9d36254 43
ikrase 1:031a0c78d8d6 44 float * ArthropodSolver::SolveBody(sixDOF_t BodyTarget6D, float LegPriorPos[], int LegNum) {
ikrase 1:031a0c78d8d6 45
ikrase 1:031a0c78d8d6 46 static float foot_pos_out[3];
ikrase 1:031a0c78d8d6 47 float xp= 0, yp = 0;
ikrase 0:9805c9d36254 48
ikrase 1:031a0c78d8d6 49 float foot_pos_inter[3];
ikrase 1:031a0c78d8d6 50 float foot_pos_new[3];
ikrase 1:031a0c78d8d6 51 switch (LegNum) { // Get the coordinates relative to the robot center rather than the leg axis.
ikrase 1:031a0c78d8d6 52 case 0:
ikrase 1:031a0c78d8d6 53 xp = HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 54 yp = HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 55 break;
ikrase 1:031a0c78d8d6 56 case 1:
ikrase 1:031a0c78d8d6 57 xp = -HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 58 yp = HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 59 break;
ikrase 1:031a0c78d8d6 60 case 2:
ikrase 1:031a0c78d8d6 61 xp = -HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 62 yp = -HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 63 break;
ikrase 1:031a0c78d8d6 64 case 3:
ikrase 1:031a0c78d8d6 65 xp = HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 66 yp = -HIP_DISP_ORTHO;
ikrase 1:031a0c78d8d6 67 break;
ikrase 1:031a0c78d8d6 68 }
ikrase 1:031a0c78d8d6 69 foot_pos_new[0] = LegPriorPos[0] + xp + BodyTarget6D.xyz[0];
ikrase 1:031a0c78d8d6 70 foot_pos_new[1] = LegPriorPos[1] + yp + BodyTarget6D.xyz[1];
ikrase 1:031a0c78d8d6 71 foot_pos_new[2] = LegPriorPos[2] + BodyTarget6D.xyz[2];
ikrase 0:9805c9d36254 72
ikrase 1:031a0c78d8d6 73 YawXform(foot_pos_new,foot_pos_inter,BodyTarget6D.ypr[0]); // apply yaw transformation first.
ikrase 1:031a0c78d8d6 74 PitchXform(foot_pos_inter, foot_pos_new,BodyTarget6D.ypr[1]);
ikrase 1:031a0c78d8d6 75 RollXform(foot_pos_new, foot_pos_inter,BodyTarget6D.ypr[2]);
ikrase 1:031a0c78d8d6 76
ikrase 1:031a0c78d8d6 77 foot_pos_out[0] = foot_pos_inter[0] - xp - BodyTarget6D.xyz[0];
ikrase 1:031a0c78d8d6 78 foot_pos_out[1] = foot_pos_inter[1] - yp - BodyTarget6D.xyz[0];
ikrase 1:031a0c78d8d6 79 foot_pos_out[2] = foot_pos_inter[2] - BodyTarget6D.xyz[0];
ikrase 1:031a0c78d8d6 80
ikrase 1:031a0c78d8d6 81
ikrase 1:031a0c78d8d6 82
ikrase 1:031a0c78d8d6 83
ikrase 0:9805c9d36254 84
ikrase 0:9805c9d36254 85 return foot_pos_out;
ikrase 0:9805c9d36254 86 }
ikrase 0:9805c9d36254 87
ikrase 0:9805c9d36254 88
ikrase 0:9805c9d36254 89
ikrase 0:9805c9d36254 90
ikrase 0:9805c9d36254 91 float * ArthropodSolver::SolveLegFwd(leg_angles_t LegAngles, int LegNum){
ikrase 0:9805c9d36254 92 static float footpos_out[3]; //x y z
ikrase 0:9805c9d36254 93
ikrase 0:9805c9d36254 94 // code
ikrase 0:9805c9d36254 95
ikrase 0:9805c9d36254 96 float L; float b1;
ikrase 0:9805c9d36254 97
ikrase 0:9805c9d36254 98 b1 = LegAngles.beta - (PI - LegAngles.alpha); // The part of beta that matters.
ikrase 0:9805c9d36254 99
ikrase 0:9805c9d36254 100 L = sin(b1) * TIBIA_L + COXA_L + sin(LegAngles.alpha) * FEMUR_L; // the extension length.
ikrase 0:9805c9d36254 101
ikrase 0:9805c9d36254 102 footpos_out[0] = L * cos(LEG_ANGLES[LegNum] + LegAngles.gamma);
ikrase 0:9805c9d36254 103 footpos_out[1] = L * sin(LEG_ANGLES[LegNum] + LegAngles.gamma);
ikrase 0:9805c9d36254 104 footpos_out[2] = -cos(LegAngles.alpha) - TIBIA_L*cos(b1) ;
ikrase 0:9805c9d36254 105
ikrase 0:9805c9d36254 106
ikrase 0:9805c9d36254 107
ikrase 0:9805c9d36254 108 return footpos_out;
ikrase 0:9805c9d36254 109 }
ikrase 0:9805c9d36254 110
ikrase 0:9805c9d36254 111 void ArthropodSolver::YawXform(float invec[], float outvec[], float angle) {
ikrase 0:9805c9d36254 112 outvec[0] = invec[0]*cos(angle)- invec[1]*sin(angle);
ikrase 0:9805c9d36254 113 outvec[1] = invec[0] * sin(angle) + outvec[1] * cos(angle);
ikrase 0:9805c9d36254 114 outvec[2] = invec[2];
ikrase 0:9805c9d36254 115
ikrase 0:9805c9d36254 116
ikrase 0:9805c9d36254 117
ikrase 0:9805c9d36254 118 }
ikrase 0:9805c9d36254 119
ikrase 0:9805c9d36254 120 void ArthropodSolver::PitchXform(float invec[], float outvec[], float angle){
ikrase 0:9805c9d36254 121 outvec[1] = invec[1]*cos(angle)- invec[2]*sin(angle);
ikrase 0:9805c9d36254 122 outvec[2] = invec[1] * sin(angle) + outvec[2] * cos(angle);
ikrase 0:9805c9d36254 123 outvec[0] = invec[0];
ikrase 0:9805c9d36254 124
ikrase 0:9805c9d36254 125 }
ikrase 0:9805c9d36254 126
ikrase 0:9805c9d36254 127 void ArthropodSolver::RollXform(float invec[], float outvec[], float angle){
ikrase 0:9805c9d36254 128 outvec[2] = invec[2]*cos(angle)- invec[0]*sin(angle);
ikrase 0:9805c9d36254 129 outvec[0] = invec[0] * cos(angle) + outvec[2] * sin(angle);
ikrase 0:9805c9d36254 130 outvec[1] = invec[1];
ikrase 0:9805c9d36254 131
ikrase 0:9805c9d36254 132 }
ikrase 0:9805c9d36254 133