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 < 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 //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 }