USBLManager.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, LABUST, UNIZG-FER
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the LABUST nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  Author: Dula Nad
00035  *  Created: 02.04.2013.
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         //Handle multiple combination with one handler
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         //Turn off auto-interrogation   
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                 //Change to transmission state
00119                 changeState(waitForReply);
00120         }
00121         else if ((lastState == initDiver) && (state == waitForReply))
00122         {
00123                 //incoming_msg.fromString<DiverMsg::AutoDiver>(incoming_package.data, DiverMsg::PositionInitAck);
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                         //Republish the last message due
00136                         //We need this due to one message lag in the communication
00137                         outgoing.publish(outgoing_package);
00138                 }
00139         }
00140 }
00141 
00142 void USBLManager::incoming_def_txt()
00143 {
00144         //Current diver message type
00145         DiverMsg::BitMap& map = DiverMsg::diverMap.at(incoming_msg.data[DiverMsg::type]);
00146 
00147         //If the message has a default
00148         if (map[DiverMsg::def])
00149         {
00150                 //Publish the default value
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         //If the message has a default
00170         if (map[DiverMsg::msg])
00171         {
00172                 //Decode
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         //NODELET_DEBUG("Decoding text message with size: %d",len);
00216         //std::cout<<"Message:"<<std::bitset<42>(msg)<<std::endl;
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         //Fill with zero chars if needed.
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                 //NODELET_DEBUG("Message encoding: %c to %d",textBuffer.front(), retVal);
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         //This can be replaced with a switch statement
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                                 //Copy the message to the outgoing package
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                 //Send position only.
00288                 //outgoing_msg.latitude += 0.001;
00289                 //outgoing_msg.longitude += 0.001;
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         //Send message
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         //If none are scheduled for sending
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         //Find first non sent point, increment idx in for declaration
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         //If all sent try to find a non-validated
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                 //If all validated
00337                 if (idx == kmlValidIdx.size())
00338                 {
00339                         if (kmlEndValidation.first == kmlNotSent || kmlEndValidation.first == kmlWaitValidation)
00340                         {
00341                                 //Send KML end default message
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                                 //Clear vector
00368                                 kmlVec.clear();
00369                                 kmlValidIdx.clear();
00370                                 //recurse 
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                         //count unvalidated
00386                         for(int i=0; i<kmlValidIdx.size(); ++i) if (kmlValidIdx[i] != kmlSentAndValid) ++kmlUnvalidated;
00387                         //For the last non-validated kml value we have to send some
00388                         //random message to try and get a validation
00389                         if (kmlUnvalidated == 1)
00390                         {
00391                                 //In order to validate the last message we have to do a pull with some message
00392                                 //Send a position update message as a pull message
00393                                 if (kmlValidIdx[idx] != kmlWaitValidation)
00394                                 {
00395                                         //Do not send a kml message
00396                                         outgoing_msg.data[DiverMsg::type] = DiverMsg::Position_18;
00397                                         //Send a position message
00398                                         kmlValidIdx[idx] = kmlWaitValidation;
00399                                         return;
00400                                 }
00401                                 //but if we sent a position message and no validation occured resend the last kml
00402                                 else
00403                                 {
00404                                         //Resend the last unvalidated kml
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         //Send KML message if we did not return till now from the function
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         //8 sec. 
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                         //Send the different messages and navigation data
00464                         NODELET_INFO("\nManager transmit:");
00465                         this->send_msg();
00466                         break;
00467                 default:
00468                         NODELET_ERROR("Unknown state.");
00469                         state = idle;
00470                 }
00471 
00472                 //NODELET_INFO("Manager running.");
00473 
00474                 //Reset the turn-around flag
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         //Reset the empty iterations counter.
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                 //NODELET_INFO("Disptach message: %d",msg_type);
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                 //resend last package
00539                 resendLastPackage();
00540         }
00541 }
00542 
00543 void USBLManager::resendLastPackage()
00544 {
00545                 //resend last package
00546                 //repack the message with possibly new navigation data.
00547                 NODELET_INFO("Timeout - resending last package. Iterations: %d",emptyIterations);
00548                 outgoing_package.data = outgoing_msg.toString();
00549                 outgoing.publish(outgoing_package);
00550 
00551                 //Reset the empty iterations counter.
00552                 emptyIterations = 0;
00553 }
00554 
00555 
00556 void USBLManager::onIncomingDefaults(const std_msgs::Int32::ConstPtr msg)
00557 {
00558         //Do some checking on the default messages
00559         defaultMsgs.push(msg->data);
00560 }
00561 
00562 void USBLManager::onIncomingForceState(const std_msgs::Int32::ConstPtr msg)
00563 {
00564         //Do some checking on the default messages
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 


usbl_comms
Author(s): Gyula Nagy
autogenerated on Fri Feb 7 2014 11:36:13