00001
00002 #ifndef INCLUDED_XWalkParameters_h_
00003 #define INCLUDED_XWalkParameters_h_
00004
00005 #include "Shared/plist.h"
00006
00007
00008
00009
00010
00011 class XWalkParameters : public virtual plist::Dictionary {
00012 protected:
00013 static const float EPSILON;
00014
00015 public:
00016
00017 XWalkParameters()
00018 : plist::Dictionary(), groundPlane(4,0,false), gravityVector(3,0,false),
00019 offsetX(0), offsetY(0), offsetA(0), resetOnStop(true), frictionCoef(0), strideLenX(100), strideLenY(60), adaptiveLegOrder(true), rotateBodyMotion(true), transitionDuration(1500),
00020 bounce(), sway(), surge(), legParams(NumLegs), nonLegJoints()
00021 {
00022 init();
00023 }
00024
00025
00026 XWalkParameters(const XWalkParameters& p)
00027 : plist::Dictionary(), groundPlane(4,0,false), gravityVector(3,0,false),
00028 offsetX(0), offsetY(0), offsetA(0), resetOnStop(true), frictionCoef(0), strideLenX(100), strideLenY(60), adaptiveLegOrder(true), rotateBodyMotion(true), transitionDuration(1500),
00029 bounce(), sway(), surge(), legParams(NumLegs), nonLegJoints()
00030 {
00031 init();
00032 *this = p;
00033 }
00034
00035
00036 static void projectToGround(const fmat::Column<3>& ground, float height, const fmat::Column<3>& gravity, fmat::Column<3>& tgt);
00037
00038
00039
00040 void packGroundGravity(const fmat::SubVector<3>& ground, const fmat::SubVector<3> gravity) const;
00041
00042 float getMaxXVel() const;
00043 float getMaxYVel() const;
00044 float getMaxAVel() const;
00045
00046 fmat::Column<2> computeNeutralPos(unsigned int leg) const;
00047
00048
00049
00050
00051
00052
00053
00054 plist::ArrayOf<plist::Primitive<float> > groundPlane;
00055
00056
00057
00058
00059
00060
00061
00062
00063 plist::ArrayOf<plist::Primitive<float> > gravityVector;
00064
00065
00066
00067 plist::Primitive<float> offsetX;
00068
00069
00070
00071 plist::Primitive<float> offsetY;
00072
00073
00074 plist::Primitive<float> offsetA;
00075
00076
00077
00078 plist::Primitive<bool> resetOnStop;
00079
00080
00081 plist::Primitive<float> frictionCoef;
00082
00083
00084
00085
00086
00087 plist::Primitive<float> strideLenX;
00088
00089
00090 plist::Primitive<float> strideLenY;
00091
00092
00093 plist::Primitive<bool> adaptiveLegOrder;
00094
00095
00096 plist::Primitive<bool> rotateBodyMotion;
00097
00098
00099 plist::Primitive<unsigned int> transitionDuration;
00100
00101
00102 class SinusoidalParameters : public virtual plist::Dictionary {
00103 public:
00104 plist::Primitive<float> magnitude;
00105 plist::Primitive<float> phase;
00106 plist::Primitive<float> baseline;
00107 plist::Primitive<float> freqScale;
00108 plist::Primitive<int> legLink;
00109
00110 SinusoidalParameters() : plist::Dictionary(), magnitude(0), phase(0), baseline(0), freqScale(2), legLink(-1) {
00111 addEntry("Magnitude",magnitude);
00112 addEntry("Phase",phase);
00113 addEntry("Baseline",baseline);
00114 addEntry("FreqScale",freqScale);
00115 addEntry("LegLink",legLink);
00116 setLoadSavePolicy(FIXED,SYNC);
00117 }
00118 inline float operator()(float globPhase, float* legPhases) {
00119 if(magnitude==0)
00120 return baseline;
00121 unsigned int leg = static_cast<unsigned int>(legLink);
00122 if(leg<NumLegs)
00123 return baseline-magnitude*std::cos((legPhases[leg] - phase)*freqScale*2*float(M_PI));
00124 else
00125 return baseline-magnitude*std::cos((globPhase - phase)*freqScale*2*float(M_PI));
00126 }
00127 };
00128 SinusoidalParameters bounce;
00129 SinusoidalParameters sway;
00130 SinusoidalParameters surge;
00131
00132
00133
00134 class LegParameters : public virtual plist::Dictionary {
00135 public:
00136 plist::Primitive<bool> usable;
00137
00138 plist::Primitive<float> stanceWidth;
00139 plist::Primitive<float> strideBias;
00140 plist::Primitive<float> strideMargin;
00141
00142 plist::Primitive<float> flightHeight;
00143 plist::Primitive<float> flightPhase;
00144 plist::Primitive<unsigned int> flightDuration;
00145 plist::Primitive<unsigned int> raiseDuration;
00146 plist::Primitive<unsigned int> lowerDuration;
00147
00148 LegParameters() : plist::Dictionary(), usable(true), stanceWidth(250), strideBias(0), strideMargin(75), flightHeight(35), flightPhase(0), flightDuration(400), raiseDuration(250), lowerDuration(250) {
00149 addEntry("Usable",usable);
00150 addEntry("StanceWidth",stanceWidth);
00151 addEntry("StrideBias",strideBias);
00152 addEntry("StrideMargin",strideMargin);
00153 addEntry("FlightHeight",flightHeight);
00154 addEntry("FlightPhase",flightPhase);
00155 addEntry("FlightDuration",flightDuration);
00156 addEntry("RaiseDuration",raiseDuration);
00157 addEntry("LowerDuration",lowerDuration);
00158 setLoadSavePolicy(FIXED,SYNC);
00159 }
00160
00161 unsigned int totalDuration() const { return raiseDuration + flightDuration + lowerDuration; }
00162 };
00163 plist::ArrayOf<LegParameters> legParams;
00164
00165 plist::DictionaryOf<SinusoidalParameters> nonLegJoints;
00166
00167 protected:
00168 void init() {
00169 addEntry("GroundPlane",groundPlane,
00170 "Specifies the ground plane relative to the base frame (in millimeters),\n"
00171 "of the form: p₁·x + p₂·y + p₃·z = p₄\n"
00172 "The first 3 entries should be normalized, so that the fourth is the\n"
00173 "distance from the origin.");
00174 addEntry("GravityVector",gravityVector,
00175 "Specifies an offset to be added to the GroundPlane normal vector to specify\n"
00176 "the direction of gravity. This influences the projection of the foot positions\n"
00177 "onto the ground plane, magnitude is arbitrary.");
00178 addEntry("OffsetX",offsetX,"Bias the position of the body relative to the ground (in millimeters), so increasing this parameter moves the robot forward, parallel to the ground.");
00179 addEntry("OffsetY",offsetY,"Bias the position of the body relative to the ground (in millimeters), so increasing this parameter moves the robot left, parallel to the ground.");
00180 addEntry("OffsetA",offsetA,"Bias the orientation of the body relative to the ground (in radians), so increasing this parameter turns the robot counter-clockwise.");
00181 addEntry("ResetOnStop",resetOnStop,"Causes the feet to redistribute to their central positions when motion stops.");
00182 addEntry("FrictionCoefficient",frictionCoef,"Coefficient of friction with the ground (aka µ), limits the amount of non-normal force which can be applied");
00183 addEntry("StrideLengthX",strideLenX,"The size of forward (x-axis) step (mm) to take with each leg (all legs have the same period and travel same speed, so must have the same length of stride)");
00184 addEntry("StrideLengthY",strideLenY,"The size of sideways (y-axis) step (mm) to take with each leg (all legs have the same period and travel same speed, so must have the same length of stride)");
00185 addEntry("AdaptiveLegOrder",adaptiveLegOrder,"If true, re-orders the leg flights based on direction of motion");
00186 addEntry("RotateBodyMotion",rotateBodyMotion,"If true, rotate the sway and surge motions to match direction of motion");
00187 addEntry("TransitionDuration",transitionDuration,"How much time to use getting into initial position, or when parameters change (milliseconds)");
00188 addEntry("Bounce",bounce,"Movement up and down while walking");
00189 addEntry("Sway",sway,"Movement left and right while walking");
00190 addEntry("Surge",surge,"Movement forward and backward while walking");
00191 addEntry("LegParameters",legParams);
00192 addEntry("NonLegJoints",nonLegJoints,"Controls motion of non-leg joints, e.g. swaying arms to balance legs");
00193 nonLegJoints.setLoadSavePolicy(SYNC,SYNC);
00194 setLoadSavePolicy(FIXED,SYNC);
00195 groundPlane[2]=1;
00196 groundPlane[3]=0;
00197 float dur = 1.f/(NumLegs+NumWheels);
00198 float phase = 0;
00199 for(unsigned int i=NumLegs-1; i<NumLegs; i-=4) {
00200 if(i+1<NumLegs) {
00201 legParams[i+1].flightPhase=phase;
00202 phase+=dur;
00203 }
00204 legParams[i].flightPhase=phase;
00205 phase+=dur;
00206 }
00207 for(unsigned int i=NumLegs-2; i<NumLegs; i-=4) {
00208 legParams[i].flightPhase=phase;
00209 phase+=dur;
00210 if(i-1U<NumLegs) {
00211 legParams[i-1U].flightPhase=phase;
00212 phase+=dur;
00213 }
00214 }
00215 }
00216
00217 float nominalPeriod() const;
00218 float minPeriod() const;
00219 };
00220
00221
00222
00223
00224
00225
00226 #endif