00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "GT2004HeadPathPlanner.h"
00012 #include "Tools/Math/Geometry.h"
00013
00014 const double GT2004HeadPathPlanner::minimumHeadSpeed=0.004;
00015
00016 void GT2004HeadPathPlanner::init(const Vector3<double>* vectors, long* durations,int numberOfVectors, bool optimizeTimings)
00017 {
00018 const RobotDimensions& robotDimensions = getRobotConfiguration().getRobotDimensions();
00019 if (numberOfVectors>maxNumberOfPoints-1) numberOfVectors=maxNumberOfPoints-1;
00020
00021 enum {FRAMEQUOTIENT = 8};
00022
00023 const Range<double> jointRangeNeckTilt(robotDimensions.jointLimitNeckTiltN,robotDimensions.jointLimitNeckTiltP);
00024 const Range<double> jointRangeHeadPan( robotDimensions.jointLimitHeadPanN, robotDimensions.jointLimitHeadPanP);
00025 const Range<double> jointRangeHeadTilt(robotDimensions.jointLimitHeadTiltN,robotDimensions.jointLimitHeadTiltP);
00026
00027
00028 points[0].x = jointRangeNeckTilt.limit(lastNeckTilt);
00029 points[0].y = jointRangeHeadPan.limit(lastHeadPan);
00030 points[0].z = jointRangeHeadTilt.limit(lastHeadTilt);
00031
00032 if (points[0].x != lastNeckTilt || points[0].y != lastHeadPan || points[0].z != lastHeadTilt)
00033 {
00034 points[0].x = jointRangeNeckTilt.limit(vectors[0].x);
00035 points[0].y = jointRangeHeadPan.limit(vectors[0].y);
00036 points[0].z = jointRangeHeadTilt.limit(vectors[0].z);
00037 durations[0]=8;
00038 }
00039
00040 currentPoint = 0;
00041 numberOfPoints = numberOfVectors;
00042 currentFrame = 0;
00043
00044
00045 int i;
00046 for (i=0;i<numberOfVectors;i++)
00047 {
00048
00049 points[i+1].x = jointRangeNeckTilt.limit(vectors[i].x);
00050 points[i+1].y = jointRangeHeadPan.limit(vectors[i].y);
00051 points[i+1].z = jointRangeHeadTilt.limit(vectors[i].z);
00052 if (optimizeTimings)
00053 {
00054 long tempTime = calculateHeadTiming(points[i],points[i+1]);
00055 if (durations[i] < tempTime)
00056 durations[i] = tempTime;
00057 }
00058 }
00059
00060 long overAllDuration = calculateDurationsSum(durations, numberOfVectors);
00061 numberOfFrames = overAllDuration / FRAMEQUOTIENT;
00062
00063
00064 firstFrame[0] = 0;
00065 for (i=0;i<numberOfVectors;i++)
00066 {
00067 firstFrame[i + 1] = firstFrame[i] + (durations[i] / FRAMEQUOTIENT);
00068 }
00069 }
00070
00071 long GT2004HeadPathPlanner::calculateDurationsSum(long* duration, int durations)
00072 {
00073 long sum=0;
00074 for (int i=0;i<durations;i++)
00075 {
00076
00077 if (duration[i]<8) duration[i]=8;
00078 sum+=duration[i];
00079 }
00080 return sum;
00081 }
00082
00083
00084 bool GT2004HeadPathPlanner::headPositionReached(Vector3<double> pos)
00085 {
00086 double grad2Rad = toMicroRad(pi / 180);
00087 Vector3<long> posInMicroRad;
00088
00089 posInMicroRad.x = (long) toMicroRad(pos.x);
00090 posInMicroRad.y = (long) toMicroRad(pos.y);
00091 posInMicroRad.z = (long) toMicroRad(pos.z);
00092
00093 if ( abs(sensorDataBuffer.lastFrame().data[SensorData::neckTilt]-posInMicroRad.x) < 8 * grad2Rad
00094 && abs(sensorDataBuffer.lastFrame().data[SensorData::headPan]-posInMicroRad.y) < 8 * grad2Rad
00095 && abs(sensorDataBuffer.lastFrame().data[SensorData::headTilt]-posInMicroRad.z) < 10 * grad2Rad)
00096 return true;
00097 return false;
00098 }
00099
00100
00101 bool GT2004HeadPathPlanner::getAngles(double& neckTilt, double& headPan, double& headTilt)
00102 {
00103 if (currentFrame<numberOfFrames)
00104 {
00105 currentFrame++;
00106 while ((currentFrame>firstFrame[currentPoint+1])&&
00107 (currentPoint<numberOfPoints-1)&&
00108 (currentFrame<numberOfFrames))
00109 {
00110 currentPoint++;
00111 }
00112
00113 double distanceInFrames=0;
00114 if (currentPoint<numberOfPoints)
00115 distanceInFrames = firstFrame[currentPoint+1]-firstFrame[currentPoint];
00116
00117 if (distanceInFrames==0)
00118 {
00119 neckTilt = points[currentPoint].x;
00120 headPan = points[currentPoint].y;
00121 headTilt = points[currentPoint].z;
00122 }
00123 else
00124 {
00125 double leftFactor = (firstFrame[currentPoint+1]-currentFrame)/distanceInFrames;
00126 double rightFactor = 1-leftFactor;
00127 neckTilt = (leftFactor*points[currentPoint].x + rightFactor*points[currentPoint+1].x);
00128 headPan = (leftFactor*points[currentPoint].y + rightFactor*points[currentPoint+1].y);
00129 headTilt = (leftFactor*points[currentPoint].z + rightFactor*points[currentPoint+1].z);
00130 }
00131 }
00132 else
00133 {
00134 neckTilt = (points[currentPoint+1].x);
00135 headPan = (points[currentPoint+1].y);
00136 headTilt = (points[currentPoint+1].z);
00137 }
00138 return (currentFrame>=numberOfFrames);
00139 }
00140
00141 long GT2004HeadPathPlanner::calculateHeadTiming(Vector3<double> &pos1,Vector3<double> &pos2)
00142 {
00143 Vector3<double> minSpeed;
00144 minSpeed.x = fabs(pos1.x-pos2.x)/headPathSpeedNeckTilt;
00145 minSpeed.y = fabs(pos1.y-pos2.y)/headPathSpeedHeadPan;
00146 minSpeed.z = fabs(pos1.z-pos2.z)/headPathSpeedHeadTilt;
00147
00148
00149 return (long) max(max(minSpeed.x,minSpeed.y),minSpeed.z);
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192