00001
00002
00003
00004
00005
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
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
00035
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
00055
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
00080
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
00094 std::vector<int> neighborVector = tNeighbors->getValue();
00095
00096 distanceVector = tNeighborDistances->getValue();
00097
00098 if (neighborVector.size() != distanceVector.size()) {
00099 ROS_ERROR("# Neighbors != # of default distances");
00100 return false;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 for (unsigned int i = 0; i < neighborVector.size(); i++) {
00112 addNeighbor(neighborVector[i]);
00113 }
00114
00115
00116
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
00134 usleep(10 * 1000);
00135 publishVP(virtualPoint);
00136 }
00137
00138
00139
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
00155 }
00156
00157
00158 obsPointSub = nodeHandle.subscribe(tObsPointsTopicName->getValue(), 1, &FormationReconfiguration::obsPointCB, this);
00159
00160
00161
00162
00163
00164
00165
00166
00167 timeout.reset();
00168
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
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);
00196 publishInitDone();
00197 }
00198
00199
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
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
00245
00246
00247 totalVel = getFormationVirtPointVel();
00248 totalVel += obsPotential.getObstacleVelocity(virtualPoint, lastObstaclePoints);
00249
00250
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
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
00283 }
00284
00285
00286
00287
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
00295 }
00296
00297 if (allConditionsMet) {
00298 ROS_WARN("Robot %d: Leaving Behavior.", nodeID);
00299 }
00300
00301
00302 return !allConditionsMet;
00303
00304
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
00330 totalVel += formationRepulsiveGradientVector[i]->getPotential(neighborDist) * posDiffUnit;
00331
00332
00333 totalVel -= formationAttractiveGradientVector[i]->getPotential(neighborDist) * posDiffUnit;
00334
00335 }
00336
00337
00338
00339 return totalVel;
00340
00341 }
00342
00343
00344 }