FormationReconfiguration.cpp
Go to the documentation of this file.
00001 /*
00002  * FormationReconfiguration.cpp
00003  *
00004  *  Created on: Nov 12, 2011
00005  *      Author: mriedel
00006  */
00007 
00008 #include "FormationReconfiguration.hpp"
00009 
00010 #include <telekyb_base/ROS.hpp>
00011 
00012 #include <geometry_msgs/PointStamped.h>
00013 
00014 #include "Neighbor.hpp"
00015 
00016 #include <telekyb_base/Time.hpp>
00017 
00018 #define INTERNAL_SUB_STEP 0.001
00019 
00020 // Declare
00021 PLUGINLIB_DECLARE_CLASS(tk_formation, FormationReconfiguration, telekyb_behavior::FormationReconfiguration, TELEKYB_NAMESPACE::Behavior);
00022 
00023 namespace telekyb_behavior {
00024 
00025 FormationReconfiguration::FormationReconfiguration()
00026         : AbstractGraphNode("tk_be_common/FormationReconfiguration", BehaviorType::Air),
00027           obsPotential("ID/" + getIDString() + "/FormationReconfigurationObstaclePotential")
00028 {
00029 
00030 }
00031 
00032 void FormationReconfiguration::obsPointCB(const telekyb_msgs::StampedPointArray::ConstPtr& obsPointsMsg)
00033 {
00034 //      ROS_INFO("Received Obstacle Points");
00035         //boost::mutex::scoped_lock lastObstaclePointsLock(lastObstaclePointsMutex);
00036         lastObstaclePoints.resize(obsPointsMsg->points.size());
00037 
00038         for (unsigned int i = 0; i < lastObstaclePoints.size(); ++i) {
00039                 lastObstaclePoints[i](0) = obsPointsMsg->points[i].x;
00040                 lastObstaclePoints[i](1) = obsPointsMsg->points[i].y;
00041                 lastObstaclePoints[i](2) = obsPointsMsg->points[i].z;
00042         }
00043 }
00044 
00045 void FormationReconfiguration::initialize()
00046 {
00047         tNeighbors = addOption<std::vector<int> >("tNeighbors",
00048                         "Neighbors",
00049                         std::vector<int>(), false, false);
00050         tNeighborDistances = addOption<std::vector<double> >("tNeighborDistances",
00051                         "Distances to Neighbors",
00052                         std::vector<double>(), false, false);
00053 
00054         //tFormationUsePositionMode = addOption("tFormationUsePositionMode", "Integrates Position from Velocity input.", true, false, false);
00055         //tJoystickYawRateScale = addOption("tFormationYawRateScale","Commanded Yaw Rate is scaled to this value", 1.0, false ,false);
00056 
00057 
00058         tObsPointsTopicName = addOption<std::string>("tObsPointsTopicName", "Topic Name of Obstacle Points",
00059                         "undef", true, false);
00060 
00061 
00062         tFormationRepulMinDist = addOption<double>("tFormationRepulMinDist",
00063                         "Distances to Neighbors",
00064                         0.7, false, false);
00065         tFormationAttrGain = addOption<double>("tFormationAttrGain",
00066                         "Distances to Neighbors",
00067                         0.2, false, false);
00068         tFormationRepulGain = addOption<double>("tFormationRepulGain",
00069                         "Distances to Neighbors",
00070                         2.0, false, false);
00071         tFormationReconfFinalYawAngle = addOption<double>("tFormationReconfFinalYawAngle",
00072                         "Yaw Angle to reach at the end.",
00073                         0.0, false, false);
00074 
00075         tMaxYawRate = addOption<double>("tMaxYawRate",
00076                         "Max Yaw Rate",
00077                         50*(M_PI/180), false, false);
00078 
00079         // no Parameters
00080         //parameterInitialized = true;
00081 }
00082 
00083 void FormationReconfiguration::destroy()
00084 {
00085 
00086 }
00087 
00088 bool FormationReconfiguration::willBecomeActive(const TKState& currentState, const Behavior& previousBehavior)
00089 {
00090         ROS_WARN("Robot %d: willBecomeActive()", nodeID);
00091         virtualPoint = currentState.position;
00092 
00093         // add Neighbors
00094         std::vector<int> neighborVector = tNeighbors->getValue();
00095         // get desired Distances
00096         distanceVector = tNeighborDistances->getValue();
00097 
00098         if (neighborVector.size() != distanceVector.size()) {
00099                 ROS_ERROR("# Neighbors != # of default distances");
00100                 return false;
00101         }
00102 
00103         // put to right size
00104 //      distanceVector.resize(neighborVector.size());
00105 
00106 //      if (neighborVector.size() != distanceVector.size()) {
00107 //              ROS_ERROR("Distance and Neighbor Vector not matching!");
00108 //              return false;
00109 //      }
00110 
00111         for (unsigned int i = 0; i < neighborVector.size(); i++) {
00112                 addNeighbor(neighborVector[i]);
00113         }
00114 
00115 
00116         // Wait for all neighboring Points.
00117         bool receivedAll = false;
00118         Timer timeout;
00119         while (!receivedAll) {
00120                 receivedAll = true;
00121                 for (unsigned int i = 0; i < neighborVector.size(); i++) {
00122                         if (!neighbors[ neighborVector[i] ]->receivedOnce()) {
00123                                 receivedAll = false;
00124                                 break;
00125                         }
00126                 }
00127 
00128                 if (timeout.getElapsed().toDSec() > 2.0) {
00129                         ROS_ERROR("Robot %d: Could not get neighbor states within timeout!", nodeID);
00130                         return false;
00131                 }
00132 
00133                 // short sleep 10ms
00134                 usleep(10 * 1000);
00135                 publishVP(virtualPoint); // send out own.
00136         }
00137 
00138 
00139         // fill Distance Vector // Create Potential Functions
00140         formationRepulsiveGradientVector.resize(neighborVector.size());
00141         formationAttractiveGradientVector.resize(neighborVector.size());
00142         for (unsigned int i = 0; i < neighborVector.size(); i++) {
00143                 Position3D neighborVP = neighbors[ neighborVector[i] ]->getVirtualPoint();
00144                 double currentDistance = (currentState.position - neighborVP).norm();
00145 
00146                 ROS_INFO("Current Distance (%d-%d): %f Desired: %f", nodeID, neighborVector[i], currentDistance, distanceVector[i]);
00147 
00148                 formationRepulsiveGradientVector[i] = new CoTanRepulsiveGradient(
00149                                 "ID/" + getIDString() + "/FormationRepulsiveGradient_Neighbor_" + boost::lexical_cast<std::string>(neighborVector[i]),
00150                                 distanceVector[i], distanceVector[i]-0.1, 0.3, 100);
00151                 formationAttractiveGradientVector[i] = new CoTanAttractiveGradient(
00152                                 "ID/" + getIDString() + "/FormationAttractiveGradient_Neighbor_" + boost::lexical_cast<std::string>(neighborVector[i]),
00153                                 distanceVector[i], distanceVector[i]+0.1, 0.3, 100);
00154 //              ROS_ERROR("Distance to (QC %d): %f", neighborVector[i], distanceVector[i]);
00155         }
00156 
00157         // Subscribe
00158         obsPointSub = nodeHandle.subscribe(tObsPointsTopicName->getValue(), 1, &FormationReconfiguration::obsPointCB, this);
00159 //      joySub = nodeHandle.subscribe(tJoystickTopic->getValue()
00160 //                                      , 10, &Formation::joystickCB, this);
00161 //      if (tVelocityInputEnabled->getValue()) {
00162 //              userInputSub = nodeHandle.subscribe(tVelocityInputTopic->getValue(), 1, &Formation::userVelocityCB, this);
00163 //      }
00164 
00165 
00166 
00167         timeout.reset();
00168         // done setting up
00169         bool allDone = false;
00170         while (!allDone) {
00171                 publishInitDone();
00172                 allDone = true;
00173                 for (unsigned int i = 0; i < neighborVector.size(); i++) {
00174                         if (!neighbors[ neighborVector[i] ]->initDone()) {
00175                                 allDone = false;
00176                                 //break;
00177                         }
00178                 }
00179 
00180                 if (timeout.getElapsed().toDSec() > 2.0) {
00181                         ROS_ERROR("Robot %d: Did not receive initDone Msg from all Neighbors!", nodeID);
00182                         publishInitDone(false);
00183 
00184                         std::vector<int> neighborVector = tNeighbors->getValue();
00185                         for (unsigned int i = 0; i < neighborVector.size(); i++) {
00186                                 removeNeighbor(neighborVector[i]);
00187                                 delete formationRepulsiveGradientVector[i];
00188                                 delete formationAttractiveGradientVector[i];
00189                         }
00190 
00191                         return false;
00192                 }
00193 
00194                 usleep(1000 * 10);
00195                 publishVP(virtualPoint); // send out own.
00196                 publishInitDone(); // we are done
00197         }
00198 
00199         // switch into Behavior
00200         valid = true;
00201 
00202         posModeLastInputTime = Time();
00203         return true;
00204 }
00205 
00206 void FormationReconfiguration::didBecomeActive(const TKState& currentState, const Behavior& previousBehavior)
00207 {
00208 
00209 }
00210 
00211 void FormationReconfiguration::willBecomeInActive(const TKState& currentState, const Behavior& nextBehavior)
00212 {
00213         obsPointSub.shutdown();
00214 
00215 
00216         std::vector<int> neighborVector = tNeighbors->getValue();
00217         for (unsigned int i = 0; i < neighborVector.size(); i++) {
00218                 removeNeighbor(neighborVector[i]);
00219                 delete formationRepulsiveGradientVector[i];
00220                 delete formationAttractiveGradientVector[i];
00221         }
00222 }
00223 
00224 void FormationReconfiguration::didBecomeInActive(const TKState& currentState, const Behavior& nextBehavior)
00225 {
00226         // not used
00227 }
00228 
00229 void FormationReconfiguration::trajectoryStepCreation(const TKState& currentState, TKTrajectory& generatedTrajInput)
00230 {
00231         generatedTrajInput.setVelocity( Velocity3D::Zero() );
00232         generatedTrajInput.setYawRate( 0.0 );
00233 }
00234 
00235 void FormationReconfiguration::trajectoryStepActive(const TKState& currentState, TKTrajectory& generatedTrajInput)
00236 {
00237         double timeDiffSec = (Time() - posModeLastInputTime).toDSec();
00238         posModeLastInputTime = Time();
00239 
00240 
00241         Eigen::Vector3d totalVel = Velocity3D::Zero();
00242         for(double internalTime=0.0;internalTime < timeDiffSec; internalTime += INTERNAL_SUB_STEP){
00243                 double internalTimeStep = fmin(INTERNAL_SUB_STEP,timeDiffSec - internalTime);
00244 //              printf("internalTimeStep: %f\n", internalTimeStep);
00245 
00246                 /*other virtual points*/
00247                 totalVel = getFormationVirtPointVel();
00248                 totalVel += obsPotential.getObstacleVelocity(virtualPoint, lastObstaclePoints);
00249                 /*external commanded velocity*/
00250 //              totalVel += lastVelocityInput;
00251 
00252                 virtualPoint += totalVel * internalTimeStep;
00253 
00254 
00255         }
00256 
00257         publishVP(virtualPoint);
00258 
00259         generatedTrajInput.setPosition(virtualPoint, totalVel);
00260 
00261         generatedTrajInput.setYawAngle(tFormationReconfFinalYawAngle->getValue());
00262 
00263 }
00264 
00265 void FormationReconfiguration::trajectoryStepTermination(const TKState& currentState, TKTrajectory& generatedTrajInput)
00266 {
00267         generatedTrajInput.setVelocity( Velocity3D::Zero() );
00268         generatedTrajInput.setYawRate( 0.0 );
00269 }
00270 
00271 bool FormationReconfiguration::isValid(const TKState& currentState) const
00272 {
00273 //      ROS_INFO("Robot %d: Distance Error: %f", nodeID, getMeanDistanceError());
00274 
00275         bool conditionDone = false;
00276         if (getMeanDistanceError() < 0.01) {
00277                 conditionDone = true;
00278                 publishConditionDone(conditionDone);
00279         } else if (getMeanDistanceError() > 0.02) {
00280                 publishConditionDone(conditionDone);
00281         } else {
00282                 // don;t send anything.
00283         }
00284 
00285 //      if (!allNeighborsValid()) {
00286 //              ROS_ERROR("Robot %d leaving Formation because not all Neighbors are valid!", nodeID);
00287 //              return false;
00288 //      }
00289 
00290         std::vector<int> neighborVector = tNeighbors->getValue();
00291         bool allConditionsMet = conditionDone;
00292         for(unsigned int i = 0; i < neighborVector.size(); i++) {
00293                 allConditionsMet &= neighbors.at( neighborVector.at(i) )->formationConditionDone();
00294 //              Position3D posDiff = virtualPoint - neighbors[ neighborVector[i] ]->posDiff();
00295         }
00296 
00297         if (allConditionsMet) {
00298                 ROS_WARN("Robot %d: Leaving Behavior.", nodeID);
00299         }
00300 
00301         // valid as long as all conditions are met.
00302         return !allConditionsMet;
00303 //      return getMeanDistanceError() > 0.03;
00304 //      return  && true;
00305 }
00306 
00307 double FormationReconfiguration::getMeanDistanceError() const {
00308         double distError = 0;
00309         std::vector<int> neighborVector = tNeighbors->getValue();
00310         for(unsigned int i = 0; i < neighborVector.size(); i++) {
00311                 Position3D posDiff = virtualPoint - neighbors.at( neighborVector.at(i) )->getVirtualPoint();
00312                 double neighborDist = posDiff.norm();
00313                 distError += fabs(neighborDist - distanceVector.at(i));
00314         }
00315 
00316         return distError /  neighborVector.size();
00317 }
00318 
00319 Velocity3D FormationReconfiguration::getFormationVirtPointVel() {
00320         Velocity3D totalVel(0.0,0.0,0.0);
00321 
00322         std::vector<int> neighborVector = tNeighbors->getValue();
00323 
00324         for(unsigned int i = 0; i < neighborVector.size(); i++) {
00325                 Position3D posDiff = virtualPoint - neighbors[ neighborVector[i] ]->getVirtualPoint();
00326                 double neighborDist = posDiff.norm();
00327                 Position3D posDiffUnit = posDiff.normalized();
00328 
00329                 // Repulsive Gradient
00330                 totalVel += formationRepulsiveGradientVector[i]->getPotential(neighborDist) * posDiffUnit;
00331 
00332                 // Attractive Gradient (//beware -)
00333                 totalVel -= formationAttractiveGradientVector[i]->getPotential(neighborDist) * posDiffUnit;
00334 
00335         }
00336 
00337 //      ROS_INFO_STREAM("TotalVelocity("<< nodeID <<"): " << std::endl << totalVel);
00338 
00339         return totalVel;
00340 
00341 }
00342 
00343 
00344 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines


tk_formation
Author(s): Martin Riedel
autogenerated on Mon Nov 11 2013 11:14:18