Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

UPennWalkMC.cc

Go to the documentation of this file.
00001 #include "UPennWalkMC.h"
00002 
00003 //This class is ported from University of Pennsylvania's 2004 Robosoccer entry, and falls under their license:
00004 /*=========================================================================
00005     This software is distributed under the GNU General Public License,
00006     version 2.  If you do not have a copy of this licence, visit
00007     www.gnu.org, or write: Free Software Foundation, 59 Temple Place,
00008     Suite 330 Boston, MA 02111-1307 USA.  This program is distributed
00009     in the hope that it will be useful, but WITHOUT ANY WARRANTY,
00010     including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011   ========================================================================= */
00012 
00013 //better to put this here instead of the header
00014 using namespace std; 
00015 
00016 #include <math.h>
00017 
00018 #ifndef PI
00019 #define PI M_PI
00020 #endif
00021 
00022 const size_t MAX_WIDTH = 208;
00023 const size_t MAX_HEIGHT = 160;
00024 const size_t LAYERM_WIDTH = 104;
00025 const size_t LAYERM_HEIGHT = 80;
00026 
00027 const double FIELD_VIEW_H = 56.9*(PI/180);
00028 const double FIELD_VIEW_V = 45.2*(PI/180);
00029 const double FOCAL_LENGTH = 192.0; // in pixel units (.5*WIDTH/tan(.5*FIELD_VIEW_H))
00030 const unsigned int IMAGE_WIDTH = 208;
00031 const unsigned int IMAGE_HEIGHT = 160;
00032 
00033 const double BODY_TILT = -13*PI/180; // Negative is head closer to ground
00034 
00035 const double BODY_WIDTH = 134.4;
00036 const double BODY_LENGTH = 130.0;
00037 
00038 const size_t NUM_LEG = 4;
00039 const size_t NUM_LEG_JOINT = 3*NUM_LEG;
00040 
00041 // Should optimize by also storing LENGTH and ANGLE of each segment:
00042 const double LEG_FORE_UPPER_Z = 69.5;
00043 const double LEG_FORE_UPPER_Y = 9.0;
00044 const double LEG_FORE_LOWER_Z = 76.4;  // From (71.5, 28.3) @ 30 deg.
00045 const double LEG_FORE_LOWER_Y = -9.0;
00046 
00047 const double LEG_HIND_UPPER_Z = 69.5;
00048 const double LEG_HIND_UPPER_Y = 9.0;
00049 const double LEG_HIND_LOWER_Z = 78.9; // From (76.5, 21.3) @ 30 deg.
00050 const double LEG_HIND_LOWER_Y = -9.0;
00051 //const double LEG_HIND_LOWER_Z = 80.0; // From (76.5, 21.3) @ 30 deg.
00052 //const double LEG_HIND_LOWER_Y = 0.0;
00053 
00054 const double NECK_TILT2_TO_CAMERA_Y = 81.0;
00055 const double NECK_TILT2_TO_CAMERA_Z = -14.6;
00056 const double NECK_TILT_TO_TILT2 = 80.0;
00057 const double SHOULDER_TO_NECK_TILT_Y = 2.5;
00058 const double SHOULDER_TO_NECK_TILT_Z = 19.5;
00059 
00060 const double MIN_SHOULDER_HEIGHT = 50.0;
00061 
00062 const double TURN_OFFSET = 75.0;
00063 
00064 
00065 
00066 // Maximum parameters for walk:
00067 
00068 
00069 // Imitating Paul's walk:
00070 
00071 const double STANCE_BODY_TILT = 0*PI/180;
00072 const double STANCE_SHOULDER_HEIGHT = 105.;
00073 
00074 const double STANCE_FORE_X0 = 7.;
00075 //const double STANCE_FORE_Y0 = 50.;
00076 const double STANCE_FORE_Y0 = 60.;
00077 const double STANCE_HIND_X0 = 2.;
00078 const double STANCE_HIND_Y0 = -45.;
00079 
00080 const int WALK_QUARTER_PERIOD = 3;
00081 const double WALK_MAX_DISTANCE = 13.; // 390 (mm/sec) /30 frames = 13
00082 
00083 const double WALK_FORE_LIFT_INITIAL = 25;
00084 const double WALK_FORE_LIFT_FINAL = 45;
00085 
00086 const double WALK_HIND_LIFT_INITIAL = 25;
00087 const double WALK_HIND_LIFT_FINAL = 25;
00088 
00089 const double WALK_FORE_XMIN = -10;
00090 const double WALK_FORE_XMAX = 30;
00091 const double WALK_FORE_YMIN = 25;
00092 //const double WALK_FORE_YMAX = 85;
00093 const double WALK_FORE_YMAX = 90;
00094 
00095 const double WALK_HIND_XMIN = -15;
00096 const double WALK_HIND_XMAX = 35;
00097 const double WALK_HIND_YMIN = -70;
00098 const double WALK_HIND_YMAX = -15;
00099 
00100 
00101 /*
00102 // Imitating 2004 US Open walk:
00103 const double STANCE_BODY_TILT = -15*PI/180;
00104 const double STANCE_SHOULDER_HEIGHT = 95.;
00105 
00106 const double STANCE_FORE_X0 = 5.;
00107 const double STANCE_FORE_Y0 = 70.;
00108 const double STANCE_HIND_X0 = 10.;
00109 const double STANCE_HIND_Y0 = -40.;
00110 
00111 const int WALK_QUARTER_PERIOD = 4;
00112 const double WALK_MAX_DISTANCE = 8.; // 390 (mm/sec) /30 frames = 13
00113 
00114 const double WALK_FORE_LIFT_INITIAL = 20;
00115 const double WALK_FORE_LIFT_FINAL = 30;
00116 const double WALK_HIND_LIFT_INITIAL = 30;
00117 const double WALK_HIND_LIFT_FINAL = 20;
00118 
00119 const double WALK_FORE_XMIN = -20;
00120 const double WALK_FORE_XMAX = 40;
00121 const double WALK_FORE_YMIN = 0;
00122 const double WALK_FORE_YMAX = 100;
00123 
00124 const double WALK_HIND_XMIN = -20;
00125 const double WALK_HIND_XMAX = 50;
00126 const double WALK_HIND_YMIN = -150;
00127 const double WALK_HIND_YMAX = 20;
00128 */
00129 
00130 
00131 enum LegIdentifier {
00132   LEG_LEFT_FORE = 0,
00133   LEG_LEFT_HIND = 1,
00134   LEG_RIGHT_FORE = 2,
00135   LEG_RIGHT_HIND = 3
00136 };
00137 
00138 UPennWalkMC::UPennWalkMC()
00139   : MotionCommand(), xVel(0), yVel(0), aVel(0),
00140     // Default stance parameters:
00141     body_tilt(STANCE_BODY_TILT), shoulder_height(STANCE_SHOULDER_HEIGHT),
00142     fore_x0(STANCE_FORE_X0), fore_y0(STANCE_FORE_Y0),
00143     hind_x0(STANCE_HIND_X0), hind_y0(STANCE_HIND_Y0),
00144     // Default walk parameters:
00145     walk_phase(0),walk_phase_direction(1),
00146     walk_quarter_period(WALK_QUARTER_PERIOD), walk_max_distance(WALK_MAX_DISTANCE),
00147     walk_fore_lift_initial(WALK_FORE_LIFT_INITIAL), walk_fore_lift_final(WALK_FORE_LIFT_FINAL),
00148     walk_hind_lift_initial(WALK_HIND_LIFT_INITIAL), walk_hind_lift_final(WALK_HIND_LIFT_FINAL),
00149     walk_fore_xmin(WALK_FORE_XMIN), walk_fore_xmax(WALK_FORE_XMAX),
00150     walk_fore_ymin(WALK_FORE_YMIN), walk_fore_ymax(WALK_FORE_YMAX),
00151     walk_hind_xmin(WALK_HIND_XMIN), walk_hind_xmax(WALK_HIND_XMAX),
00152     walk_hind_ymin(WALK_HIND_YMIN), walk_hind_ymax(WALK_HIND_YMAX)
00153 {
00154   for (int i = 0; i < 4; i++) {
00155     walk_current_x[i] = 0.0;
00156     walk_current_y[i] = 0.0;
00157   }
00158 }
00159 
00160 void
00161 UPennWalkMC::SetLegJoints(double * x) {
00162 #ifdef TGT_HAS_REK_LEGS
00163   motman->setOutput(this,LFrLegOffset+RotatorOffset,(float)x[LEG_LEFT_FORE*JointsPerLeg+0]);
00164   motman->setOutput(this,LFrLegOffset+ElevatorOffset,(float)x[LEG_LEFT_FORE*JointsPerLeg+1]);
00165   motman->setOutput(this,LFrLegOffset+KneeOffset,(float)x[LEG_LEFT_FORE*JointsPerLeg+2]);
00166   
00167   motman->setOutput(this,RFrLegOffset+RotatorOffset,(float)x[LEG_RIGHT_FORE*JointsPerLeg+0]);
00168   motman->setOutput(this,RFrLegOffset+ElevatorOffset,(float)x[LEG_RIGHT_FORE*JointsPerLeg+1]);
00169   motman->setOutput(this,RFrLegOffset+KneeOffset,(float)x[LEG_RIGHT_FORE*JointsPerLeg+2]);
00170   
00171   motman->setOutput(this,LBkLegOffset+RotatorOffset,(float)x[LEG_LEFT_HIND*JointsPerLeg+0]);
00172   motman->setOutput(this,LBkLegOffset+ElevatorOffset,(float)x[LEG_LEFT_HIND*JointsPerLeg+1]);
00173   motman->setOutput(this,LBkLegOffset+KneeOffset,(float)x[LEG_LEFT_HIND*JointsPerLeg+2]);
00174   
00175   motman->setOutput(this,RBkLegOffset+RotatorOffset,(float)x[LEG_RIGHT_HIND*JointsPerLeg+0]);
00176   motman->setOutput(this,RBkLegOffset+ElevatorOffset,(float)x[LEG_RIGHT_HIND*JointsPerLeg+1]);
00177   motman->setOutput(this,RBkLegOffset+KneeOffset,(float)x[LEG_RIGHT_HIND*JointsPerLeg+2]);
00178 #endif
00179 }
00180 
00181 void
00182 UPennWalkMC::SetStanceParameters(double bodyTilt, double shoulderHeight,
00183           double foreX0, double foreY0,
00184           double hindX0, double hindY0) {
00185   body_tilt = bodyTilt;
00186   shoulder_height = shoulderHeight;
00187   fore_x0 = foreX0;
00188   fore_y0 = foreY0;
00189   hind_x0 = hindX0;
00190   hind_y0 = hindY0;
00191 }
00192 
00193 void
00194 UPennWalkMC::SetWalkSpeeds(int quarterPeriod, double maxDistance,
00195         double foreLiftInitial, double foreLiftFinal,
00196         double hindLiftInitial, double hindLiftFinal) {
00197   walk_quarter_period = quarterPeriod;
00198   walk_max_distance = maxDistance;
00199   walk_fore_lift_initial = foreLiftInitial;
00200   walk_fore_lift_final = foreLiftFinal;
00201   walk_hind_lift_initial = hindLiftInitial;
00202   walk_hind_lift_final = hindLiftFinal;
00203 }
00204 
00205 void
00206 UPennWalkMC::SetWalkWorkspace(double foreXMin, double foreXMax,
00207        double foreYMin, double foreYMax,
00208        double hindXMin, double hindXMax,
00209        double hindYMin, double hindYMax) {
00210   walk_fore_xmin = foreXMin;
00211   walk_fore_xmax = foreXMax;
00212   walk_fore_ymin = foreYMin;
00213   walk_fore_ymax = foreYMax;
00214 
00215   walk_hind_xmin = hindXMin;
00216   walk_hind_xmax = hindXMax;
00217   walk_hind_ymin = hindYMin;
00218   walk_hind_ymax = hindYMax;
00219 }
00220 
00221 // Calculate 12 leg joint angles from leg positions
00222 // Note positions are relative to stance parameters
00223 // so all zero inputs -> stance angles
00224 void
00225 UPennWalkMC::LegPositionsToAngles(double *a)
00226 {
00227   double cosTilt = cos(body_tilt);
00228   double sinTilt = sin(body_tilt);
00229 
00230   double foreHeight = shoulder_height;
00231   double hindHeight = shoulder_height - BODY_LENGTH*sinTilt;
00232 
00233   for (int iLeg = 0; iLeg < 4; iLeg++) {
00234     double posX=0, posY=0, posZ=0;
00235     double dUpperZ = 0.0, dUpperY = 0.0, dLowerZ = 0.0, dLowerY = 0.0;
00236 
00237     switch (iLeg) {
00238     case LEG_LEFT_FORE:
00239       // Left Fore: Reverse x
00240       a[0] -= fore_x0;
00241       a[1] += fore_y0;
00242       a[2] -= foreHeight;
00243 
00244       posX = -(a[0]);
00245       posY = (cosTilt*a[1]+sinTilt*a[2]);
00246       posZ = (-sinTilt*a[1]+cosTilt*a[2]);
00247       dUpperZ = LEG_FORE_UPPER_Z;
00248       dUpperY = LEG_FORE_UPPER_Y;
00249       dLowerZ = LEG_FORE_LOWER_Z;
00250       dLowerY = LEG_FORE_LOWER_Y;
00251       break;
00252     case LEG_LEFT_HIND:
00253       // Left Hind: Reverse x,y
00254       a[0] -= hind_x0;
00255       a[1] += hind_y0;
00256       a[2] -= hindHeight;
00257 
00258       posX = -(a[0]);
00259       posY = -(cosTilt*a[1]+sinTilt*a[2]);
00260       posZ = (-sinTilt*a[1]+cosTilt*a[2]);
00261 
00262       dUpperZ = LEG_HIND_UPPER_Z;
00263       dUpperY = LEG_HIND_UPPER_Y;
00264       dLowerZ = LEG_HIND_LOWER_Z;
00265       dLowerY = LEG_HIND_LOWER_Y;
00266       break;
00267     case LEG_RIGHT_FORE:
00268       // Right Fore:
00269       a[0] += fore_x0;
00270       a[1] += fore_y0;
00271       a[2] -= foreHeight;
00272 
00273       posX = (a[0]);
00274       posY = (cosTilt*a[1]+sinTilt*a[2]);
00275       posZ = (-sinTilt*a[1]+cosTilt*a[2]);
00276 
00277       dUpperZ = LEG_FORE_UPPER_Z;
00278       dUpperY = LEG_FORE_UPPER_Y;
00279       dLowerZ = LEG_FORE_LOWER_Z;
00280       dLowerY = LEG_FORE_LOWER_Y;
00281       break;
00282     case LEG_RIGHT_HIND:
00283       // Right Hind: Reverse y
00284       a[0] += hind_x0;
00285       a[1] += hind_y0;
00286       a[2] -= hindHeight;
00287 
00288       posX = (a[0]);
00289       posY = -(cosTilt*a[1]+sinTilt*a[2]);
00290       posZ = (-sinTilt*a[1]+cosTilt*a[2]);
00291 
00292       dUpperZ = LEG_HIND_UPPER_Z;
00293       dUpperY = LEG_HIND_UPPER_Y;
00294       dLowerZ = LEG_HIND_LOWER_Z;
00295       dLowerY = LEG_HIND_LOWER_Y;
00296       break;
00297     default:
00298       cerr << "UPennWalkMC::LegPositionsToAngles(): Unknown leg.\n" << endl;
00299     }
00300 
00301     double dUpper = sqrt(dUpperY*dUpperY+dUpperZ*dUpperZ);
00302     double angleUpper = tan(dUpperY/dUpperZ);  // Positive
00303 
00304     double dLower = sqrt(dLowerY*dLowerY+dLowerZ*dLowerZ);
00305     double angleLower = tan(dLowerY/dLowerZ);  // Negative
00306 
00307     double posSumSq = posX*posX+posY*posY+posZ*posZ;
00308     
00309     double cosJ3 = .5*(posSumSq-dUpper*dUpper-dLower*dLower)/(dUpper*dLower);
00310     cosJ3 = clip(cosJ3, -1.0, 1.0);
00311     // Correct for angle offsets of leg segments
00312     a[2] = acos(cosJ3)+angleUpper-angleLower;
00313 
00314     double aZ = -dUpperZ-dLower*cos(a[2]+angleLower);
00315     double aY = dUpperY+dLower*sin(a[2]+angleLower);
00316 
00317     double sinJ2 = -posX/aZ;
00318     sinJ2 = clip(sinJ2, -1.0, 1.0);
00319     a[1] = asin(sinJ2);
00320 
00321     double J1a = atan2(aZ*cos(a[1]), aY);
00322     double J1b = atan2(posZ, posY);
00323     double J1 = J1b-J1a;
00324     while (J1 > PI) J1 -= 2*PI;
00325     while (J1 < -PI) J1 += 2*PI;
00326     a[0] = J1;
00327 
00328     a += 3;
00329   }
00330 }
00331 
00332 void
00333 UPennWalkMC::StandLegs(double x/*=0*/, double y/*=0*/, double z/*=0*/)
00334 {
00335   static double leg_joints[NUM_LEG_JOINT];
00336   double *a = leg_joints;
00337 
00338   for (int iLeg = 0; iLeg < 4; iLeg++) {
00339     double center_x = 0, center_y = 0;
00340     switch (iLeg) {
00341     case LEG_LEFT_FORE:
00342       center_x = -fore_x0;
00343       center_y = fore_y0;
00344       break;
00345     case LEG_LEFT_HIND:
00346       center_x = -hind_x0;
00347       center_y = hind_y0;
00348       break;
00349     case LEG_RIGHT_FORE:
00350       center_x = fore_x0;
00351       center_y = fore_y0;
00352       break;
00353     case LEG_RIGHT_HIND:
00354       center_x = hind_x0;
00355       center_y = hind_y0;
00356       break;
00357     default:
00358       cerr << "UPennWalkMC::StandLegs(): Unknown leg.\n" << endl;
00359     }
00360 
00361     a[0] = -x;
00362     a[1] = -y;
00363     a[2] = -z;
00364 
00365     walk_current_x[iLeg] = center_x - x;
00366     walk_current_y[iLeg] = center_y - y;
00367 
00368     // Advance pointer to next leg angles:
00369     a += 3;
00370   }
00371 
00372   LegPositionsToAngles(leg_joints);
00373   SetLegJoints(leg_joints);
00374 
00375 }
00376 
00377 int
00378 UPennWalkMC::GetWalkPhase() {
00379   return walk_phase;
00380 }
00381 
00382 void
00383 UPennWalkMC::SetWalkPhase(int phase) {
00384   walk_phase = phase;
00385 }
00386 
00387 
00388 void
00389 UPennWalkMC::WalkLegs(double xWalk/*=0.0*/, double yWalk/*=0.0*/, double aWalk/*=0.0*/)
00390 {
00391   // Check to see if legs should stand rather than walk
00392   if ((walk_phase == 0) &&
00393       (xWalk == 0.0) && (yWalk == 0.0) && (aWalk == 0.0)) {
00394     //StandLegs(0, 0, 0);
00395     return;
00396   }
00397   
00398   static double leg_joints[NUM_LEG_JOINT];
00399   double *a = leg_joints;
00400   bool switch_phase_direction = false;
00401 
00402   //  double afactor = .7*BODY_LENGTH*aWalk; // 1/2*sqrt(2)
00403   double afactor = .85*BODY_LENGTH*aWalk; // 1/2*sqrt(2)
00404   double rnorm = sqrt(afactor*afactor + xWalk*xWalk + yWalk*yWalk);
00405   if (rnorm > walk_max_distance) {
00406     double scale = walk_max_distance/rnorm;
00407     aWalk *= scale;
00408     xWalk *= scale;
00409     yWalk *= scale;
00410   }
00411 
00412   //  printf("WalkLegs: phase = %d, phase_direction = %d\n", walk_phase, walk_phase_direction);
00413   int phase_diff_from_switch = walk_quarter_period+walk_phase_direction*walk_phase;
00414   int phase_diff_to_switch = walk_quarter_period-walk_phase_direction*walk_phase;
00415 
00416   double half_width = .5*BODY_WIDTH;
00417   double half_length = .5*BODY_LENGTH*cos(body_tilt);
00418 
00419   for (int iLeg = 0; iLeg < 4; iLeg++) {
00420     double center_x = 0, center_y = 0; // Stance position center
00421     double leg_offset_x = 0, leg_offset_y = 0; // Relative to center of body
00422     double leg_lift_initial = 0, leg_lift_final = 0; // Lift heights
00423     double xmin = 0.0, xmax = 0.0, ymin = 0.0, ymax = 0.0; // Workspace limits relative to shoulder
00424     int leg_sign = 1;
00425 
00426     double current_x = walk_current_x[iLeg];
00427     double current_y = walk_current_y[iLeg];
00428     
00429     switch (iLeg) {
00430     case LEG_LEFT_FORE:
00431       leg_sign = 1;
00432       center_x = -fore_x0;
00433       center_y = fore_y0;
00434 
00435       leg_offset_x = -half_width+center_x;
00436       leg_offset_y = half_length+center_y;
00437 
00438       leg_lift_initial = walk_fore_lift_initial;
00439       leg_lift_final = walk_fore_lift_final;
00440 
00441       xmin = -walk_fore_xmax; xmax = -walk_fore_xmin;
00442       ymin = walk_fore_ymin; ymax = walk_fore_ymax;
00443       break;
00444     case LEG_LEFT_HIND:
00445       leg_sign = -1;
00446       center_x = -hind_x0;
00447       center_y = hind_y0;
00448 
00449       leg_offset_x = -half_width+center_x;
00450       leg_offset_y = -half_length+center_y;
00451 
00452       leg_lift_initial = walk_hind_lift_initial;
00453       leg_lift_final = walk_hind_lift_final;
00454 
00455       xmin = -walk_hind_xmax; xmax = -walk_hind_xmin;
00456       ymin = walk_hind_ymin; ymax = walk_hind_ymax;
00457       break;
00458     case LEG_RIGHT_FORE:
00459       leg_sign = -1;
00460       center_x = fore_x0;
00461       center_y = fore_y0;
00462 
00463       leg_offset_x = half_width+center_x;
00464       leg_offset_y = half_length+center_y;
00465 
00466       leg_lift_initial = walk_fore_lift_initial;
00467       leg_lift_final = walk_fore_lift_final;
00468 
00469       xmin = walk_fore_xmin; xmax = walk_fore_xmax;
00470       ymin = walk_fore_ymin; ymax = walk_fore_ymax;
00471       break;
00472     case LEG_RIGHT_HIND:
00473       leg_sign = 1;
00474       center_x = hind_x0;
00475       center_y = hind_y0;
00476 
00477       leg_offset_x = half_width+center_x;
00478       leg_offset_y = -half_length+center_y;
00479 
00480       leg_lift_initial = walk_hind_lift_initial;
00481       leg_lift_final = walk_hind_lift_final;
00482 
00483       xmin = walk_hind_xmin; xmax = walk_hind_xmax;
00484       ymin = walk_hind_ymin; ymax = walk_hind_ymax;
00485       break;
00486     default:
00487       cerr << "UPennWalkMC::WalkLegs(): Unknown leg.\n" << endl;
00488     }
00489 
00490     // Make relative to stance center:
00491     current_x -= center_x;
00492     current_y -= center_y;
00493     xmin -= center_x;
00494     xmax -= center_x;
00495     ymin -= center_y;
00496     ymax -= center_y;
00497 
00498     double dx, dy;
00499 
00500     // leg is up if leg_sign == walk_phase_direction
00501     if (leg_sign == walk_phase_direction) {
00502       // Leg is up
00503       if (phase_diff_from_switch > 0) {
00504 
00505   dx = xWalk + (cos(aWalk)-1)*leg_offset_x-sin(aWalk)*leg_offset_y;
00506   dy = yWalk + sin(aWalk)*leg_offset_x+(cos(aWalk)-1)*leg_offset_y;
00507 
00508   double destination_x = walk_quarter_period*dx;
00509   double destination_y = walk_quarter_period*dy;
00510 
00511       //      printf("Leg %d destination: %g, %g\n", iLeg, destination_x, destination_y);
00512   dx = (destination_x-current_x)/(phase_diff_to_switch+1);
00513   dy = (destination_y-current_y)/(phase_diff_to_switch+1);
00514 
00515   current_x += dx;
00516   current_y += dy;
00517       }
00518 
00519       current_x = clip(current_x, xmin, xmax);
00520       current_y = clip(current_y, ymin, ymax);
00521 
00522       a[0] = current_x;
00523       a[1] = current_y;
00524       a[2] = (phase_diff_from_switch*leg_lift_final+
00525         phase_diff_to_switch*leg_lift_initial)/(2*walk_quarter_period);
00526 
00527     }
00528     else {
00529       // Leg is down
00530 
00531       leg_offset_x += current_x;
00532       leg_offset_y += current_y;
00533       dx = xWalk + (cos(aWalk)-1)*leg_offset_x-sin(aWalk)*leg_offset_y;
00534       dy = yWalk + sin(aWalk)*leg_offset_x+(cos(aWalk)-1)*leg_offset_y;
00535 
00536       current_x -= dx; // Travels opposite direction as dx
00537       current_y -= dy; // Travels opposite direction as dy
00538 
00539       a[0] = current_x;
00540       a[1] = current_y;
00541       a[2] = 0;
00542 
00543       // Check if leg is going outside workspace:
00544       // This check is after writing leg positions to give extra reach
00545       current_x = clip(current_x, xmin, xmax);
00546       current_y = clip(current_y, ymin, ymax);
00547 
00548       /*
00549       Old code to advance phase to speed up cycle
00550       if (walk_current_x[iLeg] < xmin) {
00551   walk_current_x[iLeg] = xmin;
00552   // Only switch direction after quarter_period has elapsed:
00553   if (walk_phase_direction*walk_phase > 0)
00554     switch_phase_direction = true;
00555       }
00556       else if (walk_current_x[iLeg] > xmax) {
00557   walk_current_x[iLeg] = xmax;
00558   if (walk_phase_direction*walk_phase > 0)
00559     switch_phase_direction = true;
00560       }
00561       if (walk_current_y[iLeg] < ymin) {
00562   walk_current_y[iLeg] = ymin;
00563   if (walk_phase_direction*walk_phase > 0)
00564     switch_phase_direction = true;
00565       }
00566       else if (walk_current_y[iLeg] > ymax) {
00567   walk_current_y[iLeg] = ymax;
00568   if (walk_phase_direction*walk_phase > 0)
00569     switch_phase_direction = true;
00570       }
00571       */
00572 
00573     }
00574 
00575     //    printf("iLeg = %d: %g %g %g\n", iLeg, a[0],a[1],a[2]);
00576 
00577     // Store current leg positions in coordinates relative to shoulder:
00578     walk_current_x[iLeg] = current_x+center_x;
00579     walk_current_y[iLeg] = current_y+center_y;
00580 
00581     // Shift pointer to next leg:
00582     a += 3;
00583   }
00584 
00585   /*
00586   if (switch_phase_direction)
00587   printf("WalkLegs: workspace switch: phase = %d, phase_direction = %d\n", walk_phase, walk_phase_direction);
00588   */
00589 
00590   // walk_phase goes oscillates between
00591   // -walk_quarter_period to +walk_quarter_period:
00592   walk_phase += walk_phase_direction;
00593   if ((walk_phase > walk_quarter_period) ||
00594       (walk_phase < -walk_quarter_period)) {
00595     switch_phase_direction = true;
00596   }
00597 
00598   if (switch_phase_direction) {
00599     // Switch legs:
00600     walk_phase = walk_phase_direction*walk_quarter_period;
00601     walk_phase_direction = -walk_phase_direction;
00602   }
00603   
00604   LegPositionsToAngles(leg_joints);
00605   SetLegJoints(leg_joints);
00606 
00607   // Update odometry:
00608   // Commenting out to put odometry control in Perl:
00609   //  Self.world->AddMotionUpdate(xWalk, yWalk, aWalk);
00610   
00611 }
00612 
00613 
00614 
00615 
00616 /*! @file
00617  * @brief Defines UPennWalkMC, which uses the UPennalizers' 2004 RoboCup code to compute walking gaits
00618  * @author UPennalizers 2004 (Creator)
00619  * @author ejt (Ported)
00620  *
00621  * The UPennalizers code was released under the GPL:\n
00622  *  ------------------------------------------------------------------------- \n
00623  *    This software is distributed under the GNU General Public License,      \n
00624  *    version 2.  If you do not have a copy of this licence, visit            \n
00625  *    www.gnu.org, or write: Free Software Foundation, 59 Temple Place,       \n
00626  *    Suite 330 Boston, MA 02111-1307 USA.  This program is distributed       \n
00627  *    in the hope that it will be useful, but WITHOUT ANY WARRANTY,           \n
00628  *    including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.          \n
00629  *  ------------------------------------------------------------------------- \n
00630  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:52 2016 by Doxygen 1.6.3