00001
00002
00003
00004
00005
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
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
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
00049 if (deadManPressed) {
00050 lastVelocityInput = Velocity3D(msg->vector.x, msg->vector.y, msg->vector.z);
00051 } else {
00052 lastVelocityInput = Velocity3D::Zero();
00053
00054 }
00055 }
00056
00057 void Formation::obsPointCB(const telekyb_msgs::StampedPointArray::ConstPtr& obsPointsMsg)
00058 {
00059
00060
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
00076
00077
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
00093
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
00118
00119 }
00120
00121 void Formation::destroy()
00122 {
00123
00124 }
00125
00126 bool Formation::willBecomeActive(const TKState& currentState, const Behavior& previousBehavior)
00127 {
00128
00129 if (nodeID < 0) {
00130 ROS_ERROR("No NodeID set!");
00131 return false;
00132 }
00133
00134
00135 virtualPoint = currentState.position;
00136
00137
00138 std::vector<int> neighborVector = tNeighbors->getValue();
00139
00140
00141 distanceVector.resize(neighborVector.size());
00142 formationRepulsiveGradientVector.resize(neighborVector.size());
00143 formationAttractiveGradientVector.resize(neighborVector.size());
00144
00145
00146
00147
00148
00149
00150 for (unsigned int i = 0; i < neighborVector.size(); i++) {
00151 addNeighbor(neighborVector[i]);
00152 }
00153
00154 lastVelocityInput = Velocity3D::Zero();
00155
00156
00157
00158
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
00176 usleep(10 * 1000);
00177 publishVP(virtualPoint);
00178 }
00179
00180
00181
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
00192 }
00193
00194 deadManPressed = false;
00195
00196
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
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
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);
00227 publishInitDone();
00228 }
00229
00230 tFormationInitialYawAngle = currentState.getEulerRPY()(2);
00231
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
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
00282
00283
00284 totalVel = getFormationVirtPointVel();
00285 totalVel += obsPotential.getObstacleVelocity(virtualPoint, lastObstaclePoints);
00286
00287 totalVel += lastVelocityInput;
00288
00289 virtualPoint += totalVel * internalTimeStep;
00290
00291
00292 }
00293
00294 publishVP(virtualPoint);
00295
00296 generatedTrajInput.setPosition(virtualPoint, totalVel);
00297
00298
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
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
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
00340 totalVel += formationRepulsiveGradientVector[i]->getPotential(neighborDist) * posDiffUnit;
00341
00342
00343 totalVel -= formationAttractiveGradientVector[i]->getPotential(neighborDist) * posDiffUnit;
00344
00345 }
00346
00347 return totalVel;
00348
00349 }
00350
00351
00352 }