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