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 < PotentialFieldsObject* >::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 < PotentialFieldsObject* >::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 }