DiverMsg.hpp
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: 29.04.2013.
00036  *********************************************************************/
00037 #ifndef DIVERMSG_HPP_
00038 #define DIVERMSG_HPP_
00039 #include <labust/tools/BitPacker.hpp>
00040 #include <labust/tritech/detail/message_preprocess.hpp>
00041 
00042 #include <boost/preprocessor/tuple/rem.hpp>
00043 #include <boost/scoped_ptr.hpp>
00044 
00045 #include <iostream>
00046 #include <bitset>
00047 
00048 #include <string>
00049 #include <map>
00050 #include <stdexcept>
00051 
00052 namespace labust
00053 {
00054         namespace tritech
00055         {
00062                 class LatLon2Bits
00063                 {
00064                 public:
00065                         void convert(double lat, double lon, int bits = 7);
00066 
00067                         int lat, lon;
00068 
00069                 protected:
00070                         template <size_t precission>
00071                         void latlonToBits(double lat, double lon);
00072                 };
00073 
00074                 template <> void LatLon2Bits::latlonToBits<7>(double lat, double lon);
00075                 template <> void LatLon2Bits::latlonToBits<10>(double lat, double lon);
00076                 template <> void LatLon2Bits::latlonToBits<14>(double lat, double lon);
00077                 template <> void LatLon2Bits::latlonToBits<18>(double lat, double lon);
00078                 template <> void LatLon2Bits::latlonToBits<22>(double lat, double lon);
00079 
00091                 struct DiverMsg
00092                 {
00096                         enum {msgByteCount = 6};
00100                         enum {nextKMLSet=6, endOfKML=7, initReq=8};
00104                         enum {type=0,
00105                                 z,
00106                                 lat,
00107                                 lon,
00108                                 def,
00109                                 msg,
00110                                 kmlno,
00111                                 kmlx,
00112                                 kmly,
00113                                 img,
00114                                 empty,
00115                                 chksum,
00116                                 num_elements};
00117 
00118                         typedef std::vector<int> BitMap;
00119                         typedef std::map<int, BitMap > BitsCollection;
00120                         static BitsCollection topsideMap, diverMap;
00121 
00122                         DEFINE_MAPPED_MESSAGES(topsideMap,
00123 //                                                                name,         code, (z,lat,lon,def,msg,kmlno,kmlx,kmly,img,emp,chk)
00124                                         (PositionInit,                  0,      (0, 22, 22, 0,  0,      0,              0,              0,      0,      0,      0))
00125                                         (Position_18,                           1,      (7,     18,     18,     0,      0,      0,              0,              0,      0,      1,      0))
00126                                         (PositionMsg,                           2,      (7,      7,     7,      0, 18,  0,              0,              0,      0,      5,      0))
00127                                         (PositionImg,                           3,      (7,      7,     0,      0,      0,      0,              0,              0, 23,  0,      0))
00128                                         (Position_14Def,                4,      (7,     14,     14, 5,  0,      0,              0,              0,      0,      4,      0))
00129                                         (PositionMsgDef,                5,      (7,      7,      7, 5, 18,      0,              0,              0,      0,      0,      0))
00130                                         (PositionImgDef,                6,      (7,      7,      7,     5,      0,      0,              0,              0, 18,  0,      0))
00131                                         (PositionKml,                           7,      (7,      7,      7,     0,      0,      3,       10,     10,    0,      0,      0))
00132                                         (PositionChk,                           8,      (7,      7,  7, 0,      0,      0,              0,              0,      0, 17,  6))
00133                                         (PositionMsgChk,                9,      (7,      7,      7,     0, 12,  0,              0,              0,      0,      5,      6))
00134                                         (PositionImgChk,                10,     (7,      7,      7, 0,  0,      0,              0,              0, 17,  0,      6))
00135                                         (PositionDefChk,                11,     (7,      7,      7,     5,      0,      0,              0,              0,      0, 12,  6))
00136                                         (PositionMsgDefChk,     12,     (7,      7,      7, 5,  12,     0,              0,              0,      0,      0,      6))
00137                                         (PositionImgDefChk,     13,     (7,      7,      7, 5,  0,      0,              0,              0, 12,  0,      6)));
00138 
00139                         DEFINE_MAPPED_MESSAGES(diverMap,
00140 //                                                                              name,           code, (z,lat,lon,def,msg,kmlno,kmlx,kmly,img,emp,chk)
00141                                         (PositionInitAck,                       0,      (0,     22,     22,     0,      0,      0,              0,              0,      0,      0,      0))
00142                                         (MsgReply,                                              1,      (0,     0,      0,      0, 42,  0,              0,              0,      0,      2,      0))
00143                                         (ImgReply,                                              2,      (0,     0,      0,      0,      0,      0,              0,              0, 44,  0,      0))
00144                                         (DefReply,                                              3,      (0,     0,      0,      5,      0,      0,              0,              0,      0, 39,  0))
00145                                         (MsgDefReply,                                   4,      (0,     0,      0,      5, 36,  0,              0,              0,      0,      3,      0))
00146                                         (ImgDefReply,                                   5,      (0,     0,      0,      5, 39,  0,              0,              0,      0,      0,      0))
00147                                         (MsgChkReply,                                   6,      (0,     0,      0,      0, 36,  0,              0,              0,      0,      2,      6))
00148                                         (ImgChkReply,                                   7,      (0,     0,      0,      0,      0,      0,              0,              0, 38,  0,      6))
00149                                         (KmlReply,                                       11,    (0,     0,      0,      0,      0,      3,       10,     10,    0, 21,  0)));
00150 
00151                         DiverMsg(bool default_topside = true):
00152                                 latitude(0),
00153                                 longitude(0),
00154                                 depth(0),
00155                                 depthRes(0.5),
00156                                 data(num_elements,0),
00157                                 default_topside(true)
00158                         {
00159                                 DiverMsg::register_topsideMap();
00160                                 DiverMsg::register_diverMap();
00161                         };
00162 
00163                         struct AutoDiver
00164                         {
00165                                 inline static const DiverMsg::BitsCollection& map(){return DiverMsg::diverMap;};
00166                         };
00167 
00168                         struct AutoTopside
00169                         {
00170                                 inline static const DiverMsg::BitsCollection& map()     {return DiverMsg::topsideMap;};
00171                         };
00172 
00173                         template <class MsgType>
00174                         uint64_t encode(int msg_type = -1)
00175                         {
00176                                 if (msg_type != -1) data[type] = msg_type;
00177                                 //assert(MsgType::map().find(data[type]) != MsgType::map().end());
00178                                 if (MsgType::map().find(type) == MsgType::map().end())
00179                                 {
00180                                   throw std::invalid_argument("DiverMsg::encode : Unknown message type, skipping encoding.");
00181                                 }
00182 
00183                                 const BitMap& map =MsgType::map().at(data[type]);
00184                                 llEncoder.convert(latitude,longitude, map[lat]);
00185                                 data[lat] = llEncoder.lat;
00186                                 data[lon] = llEncoder.lon;
00187                                 data[z] = int(depth/depthRes);
00188                                 return labust::tools::BitPacker::pack(map, data);
00189                         }
00190 
00191                         inline uint64_t encode(int type = -1)
00192                         {
00193                                 return (default_topside?encode<AutoTopside>(type):encode<AutoDiver>(type));
00194                         }
00195 
00196                         template <class MsgType>
00197                         std::string toString(int type = -1)
00198                         {
00199                                 std::string retVal(msgByteCount+1,'\0');
00200                                 retVal[0] = msgByteCount*8;
00201                                 uint64_t data = encode<MsgType>(type);
00202                                 const char* p=reinterpret_cast<const char*>(&data);
00203                                 //Flip bytes
00204                                 for (int i=0; i<msgByteCount; ++i) retVal[i+1] = p[(msgByteCount-1)-i];
00205                                 return retVal;
00206                         }
00207 
00208                         inline std::string toString(int type = -1)
00209                         {
00210                                 return (default_topside?toString<AutoTopside>(type):toString<AutoDiver>(type));
00211                         }
00212 
00213                         template <class MsgType>
00214                         void decode(uint64_t data, int type = -1)
00215                         {
00216                                 if (type == -1) type = testType(data);
00217                                 //assert(MsgType::map().find(data[type]) != MsgType::map().end());
00218                                 if (MsgType::map().find(type) == MsgType::map().end())
00219                                 {
00220                                   throw std::invalid_argument("DiverMsg::decode : Unknown message type, skipping decoding.");
00221                                 }
00222                                 labust::tools::BitPacker::unpack(data,MsgType::map().at(type), this->data);
00223                         }
00224 
00225                         inline void decode(uint64_t data, int type = -1)
00226                         {
00227                                 default_topside?decode<AutoDiver>(data,type):decode<AutoTopside>(data,type);
00228                         }
00229 
00230                         template <class MsgType>
00231                         void fromString(const std::string& msg, int type = -1)
00232                         {
00233                                 if (msg.size() <msgByteCount)
00234                                 {
00235                                   throw std::invalid_argument("DiverMsg::fromString : Wrong message size.");
00236                                 }
00237                                 uint64_t data;
00238                                 char* ret=reinterpret_cast<char*>(&data);
00239                                 /*std::cout<<"Bytes:";*/
00240                                 for (int i=0; i<msgByteCount; ++i)
00241                                 {
00242                                  
00243                                  ret[i] = msg[1+(msgByteCount-1)-i];
00244                                  //std::cout<<std::bitset<8>(ret[i])<<" ";
00245                                 }                               
00246                                 /*std::cout<<std::endl;*/
00247                                 decode<MsgType>(data, type);
00248                         }
00249 
00250                         void fromString(const std::string& msg, int type = -1)
00251                         {
00252                                 default_topside?fromString<AutoDiver>(msg,type):fromString<AutoTopside>(msg,type);
00253                         }
00254 
00255                         static inline uint8_t testType(const std::string& data)
00256                         {
00257                                 return (data[1] >> 4) & 0xF;
00258                         }
00259 
00260                         static inline uint8_t testType(uint64_t data, size_t msgSize = 48)
00261                         {
00262                                 return (data >> (msgSize - 4)) & 0xF;
00263                         }
00264 
00265                         std::vector<int64_t> data;
00266                         LatLon2Bits llEncoder;
00267                         double latitude, longitude, depth, depthRes, kml_latitude, kml_longitude;
00268                         bool default_topside;
00269                 };
00270 
00271 #include <labust/tritech/detail/message_preprocess_undef.hpp>
00272         }
00273 }
00274 /* DIVERMSG_HPP_ */
00275 #endif
00276 
00277 
00278 


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