00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <labust/tritech/USBLManager.hpp>
00038 #include <pluginlib/class_list_macros.h>
00039
00040 #include <boost/integer/integer_mask.hpp>
00041
00042 #include <geometry_msgs/Point.h>
00043
00044 #include <algorithm>
00045
00046 PLUGINLIB_DECLARE_CLASS(usbl,USBLManager,labust::tritech::USBLManager, nodelet::Nodelet)
00047
00048 using namespace labust::tritech;
00049
00050 USBLManager::USBLManager():
00051 state(initDiver),
00052 newMessage(false),
00053 validNav(false),
00054 kmlEndValidation(std::make_pair(kmlNotSent,-1)),
00055 initValidation(),
00056 timeout(80),
00057 emptyIterations(0),
00058 diverOriginLat(0),
00059 diverOriginLon(0),
00060 lastKmlIdxSent(-1)
00061 {
00062 dispatch[DiverMsg::PositionInitAck] = boost::bind(&USBLManager::init_diver,this);
00063
00064
00065 dispatch[DiverMsg::DefReply] = dispatch[DiverMsg::MsgDefReply] =
00066 dispatch[DiverMsg::MsgReply] = boost::bind(&USBLManager::incoming_def_txt,this);
00067 dispatch[DiverMsg::KmlReply] = boost::bind(&USBLManager::incoming_kml,this);
00068 };
00069
00070 USBLManager::~USBLManager(){};
00071
00072 void USBLManager::onInit()
00073 {
00074 ros::NodeHandle nh = this->getNodeHandle();
00075 navData = nh.subscribe<auv_msgs::NavSts>("usblFiltered", 1, boost::bind(&USBLManager::onNavMsg,this,_1));
00076 incoming = nh.subscribe<std_msgs::String>("incoming_data", 1, boost::bind(&USBLManager::onIncomingMsg,this,_1));
00077 intext = nh.subscribe<std_msgs::String>("usbl_text", 1, boost::bind(&USBLManager::onIncomingText,this,_1));
00078 inDefaults = nh.subscribe<std_msgs::Int32>("usbl_defaults", 1, boost::bind(&USBLManager::onIncomingDefaults,this,_1));
00079 inKml = nh.subscribe<std_msgs::Float64MultiArray>("kml_array", 1, boost::bind(&USBLManager::onIncomingKML,this,_1));
00080 timeoutNotification = nh.subscribe<std_msgs::Bool>("usbl_timeout", 1, boost::bind(&USBLManager::onUSBLTimeout,this,_1));
00081 forceState = nh.subscribe<std_msgs::Int32>("usbl_force_state", 1, boost::bind(&USBLManager::onIncomingForceState,this,_1));
00082
00083 outgoing = nh.advertise<std_msgs::String>("outgoing_data",1);
00084 diverText = nh.advertise<std_msgs::String>("diver_text",1);
00085 diverDefaults = nh.advertise<std_msgs::Int32>("diver_defaults",1);
00086 auto_mode = nh.advertise<std_msgs::Bool>("auto_mode",1);
00087 diverOrigin = nh.advertise<geometry_msgs::Point>("diver_origin",1);
00088 outCurState = nh.advertise<std_msgs::Int32>("usbl_current_state",1);
00089
00090 worker = boost::thread(boost::bind(&USBLManager::run,this));
00091 }
00092
00093 void USBLManager::init_diver()
00094 {
00095 static int sentLat, sentLon;
00096
00097 if (!validNav)
00098 {
00099 NODELET_ERROR("No valid diver navigation stats received.");
00100 return;
00101 }
00102
00103
00104 std_msgs::Bool data;
00105 data.data = false;
00106 auto_mode.publish(data);
00107
00108 if ((state == initDiver) && (validNav))
00109 {
00110
00111 outgoing_package.data = outgoing_msg.toString(DiverMsg::PositionInit);
00112 sentLat = outgoing_msg.data[DiverMsg::lat];
00113 sentLon = outgoing_msg.data[DiverMsg::lon];
00114 diverOriginLat = outgoing_msg.latitude;
00115 diverOriginLon = outgoing_msg.longitude;
00116 outgoing.publish(outgoing_package);
00117
00118
00119 changeState(waitForReply);
00120 }
00121 else if ((lastState == initDiver) && (state == waitForReply))
00122 {
00123
00124
00125 if ((sentLat == incoming_msg.data[DiverMsg::lat]) && (sentLon == incoming_msg.data[DiverMsg::lon]))
00126 {
00127 NODELET_INFO("Diver initialization successful.");
00128 publishDiverOrigin();
00129 changeState(transmission);
00130 }
00131 else
00132 {
00133 NODELET_ERROR("Diver initialization failed. Sent (%d, %d) and received (%lld, %lld)",
00134 sentLat, sentLon, incoming_msg.data[DiverMsg::lat], incoming_msg.data[DiverMsg::lon]);
00135
00136
00137 outgoing.publish(outgoing_package);
00138 }
00139 }
00140 }
00141
00142 void USBLManager::incoming_def_txt()
00143 {
00144
00145 DiverMsg::BitMap& map = DiverMsg::diverMap.at(incoming_msg.data[DiverMsg::type]);
00146
00147
00148 if (map[DiverMsg::def])
00149 {
00150
00151 std_msgs::Int32 mdef;
00152 mdef.data = incoming_msg.data[DiverMsg::def];
00153
00154 if (mdef.data == kmlEndValidation.second)
00155 {
00156 NODELET_DEBUG("Kml default validated.");
00157 kmlEndValidation.first = kmlSentAndValid;
00158 }
00159
00160 if (mdef.data == DiverMsg::initReq)
00161 {
00162 NODELET_INFO("Init requested. Sending init.");
00163 lastState = initDiver;
00164 }
00165
00166 diverDefaults.publish(mdef);
00167 }
00168
00169
00170 if (map[DiverMsg::msg])
00171 {
00172
00173 std_msgs::String text;
00174 text.data = intToMsg(map[DiverMsg::msg]/AsciiInternal::char_size);
00175 diverText.publish(text);
00176 }
00177 }
00178
00179 void USBLManager::incoming_kml()
00180 {
00181 if (kmlVec.size())
00182 {
00183 int kmlno = incoming_msg.data[DiverMsg::kmlno];
00184 if (kmlno < kmlVec.size())
00185 {
00186 NODELET_DEBUG("Received kml idx: %d",kmlno);
00187 bool valid = kmlVec[kmlno].first == incoming_msg.data[DiverMsg::kmlx];
00188 valid = valid && kmlVec[kmlno].second == incoming_msg.data[DiverMsg::kmly];
00189 NODELET_INFO("Kml message sent (%d - %d,%d) and received (%d - %lld,%lld).",
00190 lastKmlIdxSent, kmlVec[kmlno].first, kmlVec[kmlno].second, kmlno,
00191 incoming_msg.data[DiverMsg::kmlx], incoming_msg.data[DiverMsg::kmly]);
00192
00193 if (valid)
00194 {
00195 kmlValidIdx[kmlno] = kmlSentAndValid;
00196 }
00197
00198 }
00199 else
00200 {
00201 NODELET_ERROR("Received kmlno=%d from diver "
00202 "but the kml vector has size %d.",kmlno, kmlVec.size());
00203 }
00204 }
00205 else
00206 {
00207 NODELET_INFO("Received new KML point from diver.");
00208 }
00209 }
00210
00211 std::string USBLManager::intToMsg(int len)
00212 {
00213 std::string retVal(len,'\0');
00214 int64_t msg = incoming_msg.data[DiverMsg::msg];
00215
00216
00217 for (int i=0; i<len; ++i)
00218 {
00219 retVal[i] = AsciiInternal::int2Ascii(msg & boost::low_bits_mask_t<AsciiInternal::char_size>::sig_bits);
00220 msg >>= AsciiInternal::char_size;
00221 }
00222 std::reverse(retVal.begin(), retVal.end());
00223 return retVal;
00224 }
00225
00226 int USBLManager::msgToInt(int len)
00227 {
00228 int retVal(0);
00229
00230 while (textBuffer.size() < len) textBuffer.push(AsciiInternal::zero_char);
00231
00232 for (int i=0; i<len; ++i)
00233 {
00234 retVal |= textBuffer.front() & boost::low_bits_mask_t<AsciiInternal::char_size>::sig_bits;
00235
00236 textBuffer.pop();
00237 if (i < len-1) retVal <<= AsciiInternal::char_size;
00238 }
00239
00240 return retVal;
00241 }
00242
00243 void USBLManager::send_msg()
00244 {
00245
00246 bool hasMsg(textBuffer.size());
00247 bool hasKml(kmlBuffer.size() || kmlVec.size());
00248 bool hasDefault(defaultMsgs.size());
00249
00250 if (hasDefault || hasMsg)
00251 {
00252 if (hasDefault)
00253 {
00254 if (hasMsg)
00255 {
00256 outgoing_msg.data[DiverMsg::def] = defaultMsgs.front();
00257 defaultMsgs.pop();
00258 int msglen = DiverMsg::topsideMap[DiverMsg::PositionMsgDef][DiverMsg::msg]/AsciiInternal::char_size;
00259 outgoing_msg.data[DiverMsg::msg] = msgToInt(msglen);
00260 outgoing_msg.data[DiverMsg::type] = DiverMsg::PositionMsgDef;
00261 NODELET_INFO("Send PositionMsgDef: %lld, %lld", outgoing_msg.data[DiverMsg::msg],
00262 outgoing_msg.data[DiverMsg::def]);
00263 }
00264 else
00265 {
00266
00267 outgoing_msg.data[DiverMsg::def] = defaultMsgs.front();
00268 defaultMsgs.pop();
00269 outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_14Def;
00270 NODELET_INFO("Send Position_14Def: %lld", outgoing_msg.data[DiverMsg::def]);
00271 }
00272 }
00273 else
00274 {
00275 int msglen = DiverMsg::topsideMap[DiverMsg::PositionMsg][DiverMsg::msg]/AsciiInternal::char_size;
00276 outgoing_msg.data[DiverMsg::msg] = msgToInt(msglen);
00277 outgoing_msg.data[DiverMsg::type] = DiverMsg::PositionMsg;
00278 NODELET_INFO("Send PositionMsg: %lld", outgoing_msg.data[DiverMsg::msg]);
00279 }
00280 }
00281 else if (hasKml)
00282 {
00283 kml_send();
00284 }
00285 else
00286 {
00287
00288
00289
00290 NODELET_INFO("Send Position_18: lat=%f, long=%f", outgoing_msg.latitude, outgoing_msg.longitude);
00291 outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_18;
00292 }
00293
00294
00295 outgoing_package.data = outgoing_msg.toString();
00296 outgoing.publish(outgoing_package);
00297 changeState(waitForReply);
00298 }
00299
00301 void USBLManager::kml_send()
00302 {
00303 static int kml_send_size = 1 << DiverMsg::topsideMap.at(DiverMsg::PositionKml)[DiverMsg::kmlno];
00304
00305 if (kmlVec.size() == 0)
00306 {
00307 int i=0;
00308
00309 while (!kmlBuffer.empty() && i<kml_send_size)
00310 {
00311 ++i;
00312 kmlVec.push_back(kmlBuffer.front());
00313 kmlValidIdx.push_back(0);
00314 kmlBuffer.pop();
00315 }
00316 kmlEndValidation.first = kmlNotSent;
00317 }
00318
00319
00320 int idx=0;
00321 for(int i=0; i<kmlValidIdx.size(); ++i, ++idx)
00322 {
00323 if (kmlValidIdx[i] == kmlNotSent)
00324 {
00325 kmlValidIdx[idx] = kmlSent;
00326 break;
00327 }
00328 }
00329
00330
00331 if (idx == kmlValidIdx.size())
00332 {
00333 idx = 0;
00334 for(int i=0; i<kmlValidIdx.size(); ++i, ++idx) if (kmlValidIdx[i] != kmlSentAndValid) break;
00335
00336
00337 if (idx == kmlValidIdx.size())
00338 {
00339 if (kmlEndValidation.first == kmlNotSent || kmlEndValidation.first == kmlWaitValidation)
00340 {
00341
00342 outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_14Def;
00343 outgoing_msg.data[DiverMsg::def] = kmlBuffer.empty()?DiverMsg::endOfKML:
00344 DiverMsg::nextKMLSet;
00345 kmlEndValidation.first = kmlSent;
00346 kmlEndValidation.second = outgoing_msg.data[DiverMsg::def];
00347
00348 if (kmlBuffer.empty())
00349 {
00350 NODELET_INFO("Sending end kml.");
00351 lastKmlIdxSent = kml_send_size+1;
00352 }
00353 else
00354 {
00355 NODELET_INFO("Sending next kml.");
00356 lastKmlIdxSent = kml_send_size;
00357 }
00358 }
00359 else if (kmlEndValidation.first == kmlSent)
00360 {
00361 outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_18;
00362 NODELET_INFO("Sending position while wait for kml reply.");
00363 kmlEndValidation.first = kmlWaitValidation;
00364 }
00365 else if (kmlEndValidation.first == kmlSentAndValid)
00366 {
00367
00368 kmlVec.clear();
00369 kmlValidIdx.clear();
00370
00371 if (kmlEndValidation.second == DiverMsg::nextKMLSet)
00372 {
00373 kml_send();
00374 }
00375 else
00376 {
00377 outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_18;
00378 }
00379 }
00380 return;
00381 }
00382 else
00383 {
00384 int kmlUnvalidated = 0;
00385
00386 for(int i=0; i<kmlValidIdx.size(); ++i) if (kmlValidIdx[i] != kmlSentAndValid) ++kmlUnvalidated;
00387
00388
00389 if (kmlUnvalidated == 1)
00390 {
00391
00392
00393 if (kmlValidIdx[idx] != kmlWaitValidation)
00394 {
00395
00396 outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_18;
00397
00398 kmlValidIdx[idx] = kmlWaitValidation;
00399 return;
00400 }
00401
00402 else
00403 {
00404
00405 kmlValidIdx[idx] = kmlSent;
00406 }
00407 }
00408 else
00409 {
00410 for(int i=0; i<kmlValidIdx.size(); ++i)
00411 {
00412 if (kmlValidIdx[i] == kmlSent) kmlValidIdx[i] = kmlNotSent;
00413 }
00414
00415 idx = 0;
00416 for(int i=0; i<kmlValidIdx.size(); ++i, ++idx)
00417 {
00418 if (kmlValidIdx[i] == kmlNotSent)
00419 {
00420 kmlValidIdx[idx] = kmlSent;
00421 break;
00422 }
00423 }
00424 }
00425 }
00426 }
00427
00428
00429 outgoing_msg.data[DiverMsg::type] = DiverMsg::PositionKml;
00430 outgoing_msg.data[DiverMsg::kmlno] = idx;
00431 outgoing_msg.data[DiverMsg::kmlx] = kmlVec[idx].first;
00432 outgoing_msg.data[DiverMsg::kmly] = kmlVec[idx].second;
00433 lastKmlIdxSent = idx;
00434 NODELET_INFO("Sent PositionKml: %d, (%lld,%lld)",idx,
00435 outgoing_msg.data[DiverMsg::kmlx],
00436 outgoing_msg.data[DiverMsg::kmly]);
00437 }
00438
00441 void USBLManager::run()
00442 {
00443 double freq;
00444 ros::NodeHandle ph("~");
00445 ph.param("rate",freq,10.0);
00446 ros::Rate rate(freq);
00447
00448 timeout = 10*freq;
00449 std_msgs::String package;
00450
00451 while (ros::ok())
00452 {
00453 switch (state)
00454 {
00455 case idle: break;
00456 case waitForReply:
00457 if (++emptyIterations > timeout) resendLastPackage();
00458 break;
00459 case initDiver:
00460 this->init_diver();
00461 break;
00462 case transmission:
00463
00464 NODELET_INFO("\nManager transmit:");
00465 this->send_msg();
00466 break;
00467 default:
00468 NODELET_ERROR("Unknown state.");
00469 state = idle;
00470 }
00471
00472
00473
00474
00475 newMessage = false;
00476 std_msgs::Int32Ptr curstate(new std_msgs::Int32());
00477 curstate->data = state;
00478 outCurState.publish(curstate);
00479 publishDiverOrigin();
00480
00481
00482 rate.sleep();
00483 ros::spinOnce();
00484 }
00485 }
00486
00487 void USBLManager::onNavMsg(const auv_msgs::NavSts::ConstPtr nav)
00488 {
00489 NODELET_DEBUG("Received nav message.");
00490 validNav = true;
00491 outgoing_msg.latitude = nav->global_position.latitude;
00492 outgoing_msg.longitude = nav->global_position.longitude;
00493 outgoing_msg.depth = nav->position.depth;
00494 }
00495
00496 void USBLManager::onIncomingMsg(const std_msgs::String::ConstPtr msg)
00497 {
00498 NODELET_INFO("Received modem message with type: %d",DiverMsg::testType(msg->data));
00499
00500
00501 emptyIterations = 0;
00502
00503 try
00504 {
00505 incoming_msg.fromString(msg->data);
00506 incoming_package = *msg;
00507 int msg_type = incoming_msg.data[DiverMsg::type];
00508
00509 if (dispatch.find(msg_type) != dispatch.end())
00510 {
00511 dispatch[msg_type]();
00512 }
00513 else
00514 {
00515 NODELET_ERROR("No handler for message type %d",msg_type);
00516 }
00517 }
00518 catch (std::exception& e)
00519 {
00520 NODELET_ERROR("Exception caught on incoming msg: %s",e.what());
00521 }
00522
00523 if (state == waitForReply) changeState(lastState);
00524 }
00525
00526 void USBLManager::onIncomingText(const std_msgs::String::ConstPtr msg)
00527 {
00528 for (int i=0; i<msg->data.size(); ++i)
00529 {
00530 textBuffer.push(AsciiInternal::ascii2Int(msg->data[i]));
00531 }
00532 }
00533
00534 void USBLManager::onUSBLTimeout(const std_msgs::Bool::ConstPtr msg)
00535 {
00536 if (msg->data && state == waitForReply)
00537 {
00538
00539 resendLastPackage();
00540 }
00541 }
00542
00543 void USBLManager::resendLastPackage()
00544 {
00545
00546
00547 NODELET_INFO("Timeout - resending last package. Iterations: %d",emptyIterations);
00548 outgoing_package.data = outgoing_msg.toString();
00549 outgoing.publish(outgoing_package);
00550
00551
00552 emptyIterations = 0;
00553 }
00554
00555
00556 void USBLManager::onIncomingDefaults(const std_msgs::Int32::ConstPtr msg)
00557 {
00558
00559 defaultMsgs.push(msg->data);
00560 }
00561
00562 void USBLManager::onIncomingForceState(const std_msgs::Int32::ConstPtr msg)
00563 {
00564
00565 if (msg->data < lastStateNum)
00566 {
00567 this->lastState = msg->data;
00568 }
00569 else
00570 {
00571 ROS_ERROR("Unknown state %d",msg->data);
00572 }
00573 }
00574
00575 void USBLManager::onIncomingKML(const std_msgs::Float64MultiArray::ConstPtr msg)
00576 {
00577 int len = msg->data.size();
00578 if (len % 2 != 0)
00579 {
00580 --len;
00581 NODELET_WARN("The kml array should have a even lengths. Pairs of {lat0,lon0,...,latN,lonN}");
00582 }
00583
00584 LatLon2Bits llEncoder;
00585 static int kmlbits = DiverMsg::topsideMap.at(DiverMsg::PositionKml)[DiverMsg::kmlx];
00586 for (int i=0; i<len; i+=2)
00587 {
00588 llEncoder.convert(msg->data[i],msg->data[i+1], kmlbits);
00589 kmlBuffer.push(std::make_pair(llEncoder.lat,llEncoder.lon));
00590 }
00591 }
00592
00593 void USBLManager::publishDiverOrigin()
00594 {
00595 geometry_msgs::PointPtr msg(new geometry_msgs::Point());
00596 msg->x = diverOriginLat;
00597 msg->y = diverOriginLon;
00598 diverOrigin.publish(msg);
00599 }
00600