Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/PotentialFields/Pfield.cpp

Go to the documentation of this file.
00001 /**
00002 * @file Pfield.cpp
00003 * 
00004 * Implementation of class Potentialfield
00005 * This file was originally named Potentialfield.cpp but had to be renamed
00006 * because of another Potentialfield.cpp in this project.
00007 *
00008 * @author <a href="mailto:timlaue@informatik.uni-bremen.de">Tim Laue</a>
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 //blockForM == MILLISECONDS
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)   //No ELSE here, value of currentlySelected may change!
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 * $Log: Pfield.cpp,v $
00244 * Revision 1.2  2004/06/07 18:19:39  tim
00245 * removed dynamic_cast and RTTI
00246 *
00247 * Revision 1.1.1.1  2004/05/22 17:37:31  cvsadm
00248 * created new repository GT2004_WM
00249 *
00250 * Revision 1.1  2004/01/20 15:42:19  tim
00251 * Added potential fields implementation
00252 *
00253 * Revision 1.6  2003/06/13 14:27:58  tim
00254 * added random generator and tangential fields
00255 *
00256 * Revision 1.5  2003/06/09 20:00:04  tim
00257 * Changed potentialfield architecture
00258 *
00259 * Revision 1.4  2003/04/03 15:47:32  tim
00260 * Added modelling for teammates
00261 *
00262 * Revision 1.3  2003/04/02 14:39:12  tim
00263 * Changed Bremen Byters Behavior
00264 *
00265 * Revision 1.2  2003/03/23 20:32:37  loetzsch
00266 * removed green compiler warning: no newline at end of file
00267 *
00268 * Revision 1.1  2003/03/23 17:51:27  tim
00269 * Added potentialfields
00270 *
00271 */

Generated on Thu Sep 23 19:57:41 2004 for GT2004 by doxygen 1.3.6