00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Pfield.h"
00012 #include "Motionfield.h"
00013 #include "FieldObject.h"
00014 #include "RandomMotionGenerator.h"
00015 #include "PotentialfieldComposition.h"
00016
00017
00018
00019 Potentialfield::Potentialfield()
00020 {
00021 isActive = true;
00022 currentlySelected = false;
00023 block = 0;
00024 }
00025
00026
00027 Potentialfield::~Potentialfield()
00028 {
00029 combinedFields.clear();
00030 objects.clear();
00031 }
00032
00033
00034 void Potentialfield::getValueArray(double x1, double y1, double x2, double y2,
00035 int xSteps, int ySteps, double value[], double& max)
00036 {
00037 double stepWidthX = (x2-x1)/(double)xSteps;
00038 double stepWidthY = (y2-y1)/(double)ySteps;
00039 PfPose currentPose;
00040 currentPose.pos.x = x1;
00041 currentPose.pos.y = y1;
00042 double min = getFieldValueAt(currentPose);
00043 double mx = min;
00044 for(int y=0; y<ySteps; y++)
00045 {
00046 for(int x=0; x<xSteps; x++)
00047 {
00048 int pos = y*ySteps + x;
00049 currentPose.pos.x = x1+x*stepWidthX;
00050 currentPose.pos.y = y1+y*stepWidthY;
00051 value[pos] = getFieldValueAt(currentPose);
00052 if(value[pos]<min)
00053 {
00054 min = value[pos];
00055 }
00056 else if(value[pos]>mx)
00057 {
00058 mx = value[pos];
00059 }
00060 }
00061 }
00062 min = -1 * min;
00063 max = mx + min;
00064 for(int i = 0; i<xSteps*ySteps; i++)
00065 {
00066 value[i] += min;
00067 }
00068 }
00069
00070
00071 void Potentialfield::getDirectionArray(double x1, double y1, double x2, double y2,
00072 int xSteps, int ySteps, PfVec directions[])
00073 {
00074 double stepWidthX = (x2-x1)/(double)xSteps;
00075 double stepWidthY = (y2-y1)/(double)ySteps;
00076 PfPose currentPose;
00077 for(int y=0; y<ySteps; y++)
00078 {
00079 for(int x=0; x<xSteps; x++)
00080 {
00081 int pos = y*ySteps + x;
00082 currentPose.pos.x = x1+x*stepWidthX;
00083 currentPose.pos.y = y1+y*stepWidthY;
00084 PfVec objVec(getFieldVecAt(currentPose));
00085 if(objVec.length() >= 1.0)
00086 {
00087 objVec.normalize();
00088 }
00089 directions[pos] = objVec;
00090 }
00091 }
00092 }
00093
00094
00095 PfVec Potentialfield::getFieldVecAt(const PfPose& pose)
00096 {
00097 PfVec absVec(0.0,0.0);
00098 std::vector < Object* >::iterator object;
00099 for (object = objects.begin (); object != objects.end (); ++object)
00100 {
00101 absVec += (*object)->computeAbsFieldVecAt(pose);
00102 }
00103 if(this->getBehaviorFieldType() == MOTION_FIELD)
00104 {
00105 absVec += ((Motionfield*)(this))->getRandomVector();
00106 }
00107 return absVec;
00108 }
00109
00110
00111 double Potentialfield::getFieldValueAt(const PfPose& pose)
00112 {
00113 double result(0.0);
00114 std::vector < Object* >::iterator object;
00115 for (object = objects.begin (); object != objects.end (); ++object)
00116 {
00117 result += (*object)->computeChargeAt(pose);
00118 }
00119 return result;
00120 }
00121
00122
00123 void Potentialfield::setSelectionFeedback(bool selected)
00124 {
00125 if(selected)
00126 {
00127 if(currentlySelected)
00128 {
00129 selectedCalls++;
00130 }
00131 else
00132 {
00133 currentlySelected = true;
00134 selectedSince = getSystemTime();
00135 selectedCalls = 1;
00136 }
00137 checkForBlockAppliance();
00138 }
00139 else
00140 {
00141 if(currentlySelected)
00142 {
00143 currentlySelected = false;
00144 checkForBlockAppliance();
00145 }
00146 }
00147 }
00148
00149
00150 bool Potentialfield::isBlocked()
00151 {
00152 if(blockForM == CALLS)
00153 {
00154 if(block>0)
00155 {
00156 --block;
00157 }
00158 return (block > 0);
00159 }
00160 else
00161 {
00162 return (getSystemTime() < block);
00163 }
00164 }
00165
00166
00167 void Potentialfield::checkForBlockAppliance()
00168 {
00169 if(currentlySelected)
00170 {
00171 if(keepMaxForO == CALLS)
00172 {
00173 long sel2(static_cast< long >(selectedCalls));
00174 if(sel2 >= o)
00175 {
00176 currentlySelected = false;
00177 }
00178 }
00179 else if(o != -1)
00180 {
00181 unsigned int o2(static_cast< unsigned int>(o));
00182 if((getSystemTime() - selectedSince) > o2)
00183 {
00184 currentlySelected = false;
00185 }
00186 }
00187 }
00188 if(!currentlySelected)
00189 {
00190 if(blockForM == CALLS)
00191 {
00192 block = m;
00193 }
00194 else
00195 {
00196 block = getSystemTime()+m;
00197 }
00198 }
00199 }
00200
00201
00202 bool Potentialfield::hasToRemainActive()
00203 {
00204 if(!currentlySelected)
00205 {
00206 return false;
00207 }
00208 if(keepForN == CALLS)
00209 {
00210 return (selectedCalls < n);
00211 }
00212 else
00213 {
00214 return (getSystemTime() < (selectedSince+n));
00215 }
00216 }
00217
00218
00219 void Potentialfield::getResult(const PfPose& pose, PotentialfieldResult& result)
00220 {
00221 result.action = name;
00222 if(isBlocked() || (!isActive))
00223 {
00224 result.actionPossible = false;
00225 }
00226 else if(currentlySelected && (whatToKeep == KEEP_RESULT) &&
00227 ( ((keepForN==CALLS)&&(selectedCalls<n)) ||
00228 ((keepForN==MILLISECONDS) && (getSystemTime() < (selectedSince+n))) ) )
00229 {
00230 result = lastResult;
00231 }
00232 else
00233 {
00234 execute(pose,result);
00235 result.timeStamp = getSystemTime();
00236 lastResult = result;
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271