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 <string>
00038 #include <vector>
00039 #include <cstdint>
00040 #include <bitset>
00041 #include <iostream>
00042 #include <boost/integer/integer_mask.hpp>
00043 #include <boost/preprocessor/tuple/rem.hpp>
00044 #include <cassert>
00045 #include <labust/tritech/DiverMsg.hpp>
00046
00047 #define ADD_DIVER_MESSAGE(NAME, CODE, DEPTHSIZE, \
00048 LATLONSIZE, DEFSIZE, MSGSIZE, KMLNOSIZE, KMLSIZE, IMGSIZE, VOIDSIZE, CHKSIZE) \
00049 struct NAME\
00050 {\
00051 enum{type=CODE};\
00052 enum{depthSize=DEPTHSIZE,latlonSize=LATLONSIZE,defSize=DEFSIZE, msgSize=MSGSIZE, kmlNoSize=KMLNOSIZE, \
00053 kmlSize=KMLSIZE, imgSize=IMGSIZE, voidSize=VOIDSIZE, chkSize=CHKSIZE};\
00054 };\
00055
00056
00057 struct DiverMsg2
00058 {
00059
00060 ADD_DIVER_MESSAGE(PositionInit, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0);
00061 ADD_DIVER_MESSAGE(Position_18, 1, 7, 18, 0, 0, 0, 0, 0, 1, 0);
00062 ADD_DIVER_MESSAGE(PositionMsg, 2, 7, 7, 0, 18, 0, 0, 0, 5, 0);
00063 ADD_DIVER_MESSAGE(PositionImg, 2, 7, 7, 0, 0, 0, 0, 23, 0, 0);
00064 ADD_DIVER_MESSAGE(Position_14Def, 4, 7, 14, 5, 0, 0, 0, 0, 4, 0);
00065 ADD_DIVER_MESSAGE(PositionMsgDef, 5, 7, 7, 5, 18, 0, 0, 0, 0, 0);
00066 ADD_DIVER_MESSAGE(PositionImgDef, 6, 7, 7, 5, 0, 0, 0, 18, 0, 0);
00067 ADD_DIVER_MESSAGE(PositionKml, 7, 7, 7, 0, 0, 3, 10, 0, 0, 0);
00068 ADD_DIVER_MESSAGE(PositionChk, 8, 7, 7, 0, 0, 0, 0, 0, 17, 6);
00069 ADD_DIVER_MESSAGE(PositionMsgChk, 9, 7, 7, 0, 12, 0, 0, 0, 5, 6);
00070 ADD_DIVER_MESSAGE(PositionImgChk, 10, 7, 7, 0, 0, 0, 0, 17, 0, 6);
00071 ADD_DIVER_MESSAGE(PositionDefChk, 11, 7, 7, 5, 0, 0, 0, 0, 12, 6);
00072 ADD_DIVER_MESSAGE(PositionMsgDefChk,12, 7, 7, 5, 12, 0, 0, 0, 0, 6);
00073 ADD_DIVER_MESSAGE(PositionImgDefChk,13, 7, 7, 5, 0, 0, 0, 12, 0, 6);
00074
00075
00076 ADD_DIVER_MESSAGE(PositonInitAck, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0);
00077 ADD_DIVER_MESSAGE(Msg, 1, 0, 0, 0, 0, 0, 0, 0, 44, 0);
00078
00079 DiverMsg2():
00080 latitude(0),
00081 longitude(0),
00082 z(0),
00083 depthRes(0.5){};
00084
00085
00086 template <class msg>
00087 uint64_t pack()
00088 {
00089 fullmsg = msg::type;
00090 fullmsg <<= msg::depthSize;
00091 fullmsg |= int(z/depthRes) & boost::low_bits_mask_t<msg::depthSize>::sig_bits;
00092 fullmsg <<= msg::latlonSize;
00093 latlonToBits<msg::latlonSize>(latitude,longitude);
00094 fullmsg |= lat & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00095 fullmsg <<= msg::latlonSize;
00096 fullmsg |= lon & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00097 fullmsg <<= msg::msgSize;
00098 fullmsg |= this->msg & boost::low_bits_mask_t<msg::msgSize>::sig_bits;
00099 return fullmsg;
00100 }
00101
00102 static inline uint8_t testType(uint64_t data, size_t msgSize = 48)
00103 {
00104 return (data >> (msgSize - 4)) & 0xF;
00105 }
00106
00107 template <class msg>
00108 bool unpack(uint64_t data)
00109 {
00110 fullmsg=data;
00111 this->msg = data & boost::low_bits_mask_t<msg::msgSize>::sig_bits;
00112 data >>= msg::msgSize;
00113 lon = data & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00114 data >>= msg::latlonSize;
00115 lat = data & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00116 data >>= msg::latlonSize;
00117 depth = data & boost::low_bits_mask_t<msg::depthSize>::sig_bits;
00118 data >>= msg::depthSize;
00119
00120 assert(((data & 0x0F) == msg::type) &&
00121 "DiverMsg2 desired unpack type and received data type do not match.");
00122 };
00123
00124 template <size_t precission>
00125 std::pair<int,int> latlonToBits(double lat, double lon){return std::pair<int,int>();};
00126
00127 double latitude, longitude, z, depthRes;
00128 uint64_t fullmsg;
00129 uint8_t depth;
00130 int lat,lon;
00131 uint64_t msg;
00132
00133
00134 };
00135
00136 template <>
00137 inline std::pair<int,int> DiverMsg2::latlonToBits<22>(double lat, double lon)
00138 {
00139 double min = (lon - int(lon))*60;
00140 this->lon = int((int(lon)+180)*10000 + min*100);
00141
00142 min = (lat - int(lat))*60;
00143 this->lat = int((int(lat)+90)*10000 + min*100);
00144
00145 return std::pair<int,int>(this->lat,this->lon);
00146 }
00147
00148 template <>
00149 inline std::pair<int,int> DiverMsg2::latlonToBits<18>(double lat, double lon)
00150 {
00151 this->lat = int((lat - int(lat))*600000)%100000;
00152 this->lon = int((lon - int(lon))*600000)%100000;
00153 return std::pair<int,int>(this->lat,this->lon);
00154 }
00155
00156 template <>
00157 std::pair<int,int> DiverMsg2::latlonToBits<14>(double lat, double lon)
00158 {
00159 double min = (lon - int(lon))*60;
00160 this->lon = int((min - int(min))*10000);
00161
00162 min = (lat - int(lat))*60;
00163 this->lat = int((min - int(min))*10000);
00164
00165 return std::pair<int,int>(this->lat,this->lon);
00166 }
00167
00168 template <>
00169 inline std::pair<int,int> DiverMsg2::latlonToBits<7>(double lat, double lon)
00170 {
00171 latlonToBits<14>(lat,lon);
00172 this->lat%=100;
00173 this->lon%=100;
00174 return std::pair<int,int>(this->lat,this->lon);
00175 }
00176
00177 void writeLatLon(DiverMsg2& msg)
00178 {
00179 double lat = msg.latitude;
00180 double lon = msg.longitude;
00181 std::cout<<"Sending lat-lon:"<<int(lat)<<"\° "<<(lat-int(lat))*60<<"', ";
00182 std::cout<<int(lon)<<"\° "<<(lon-int(lon))*60<<std::endl;
00183 std::cout<<"\t encoded lat-lon:"<<msg.lat<<", "<<msg.lon<<std::endl;
00184 }
00185
00186 int main(int argc, char* argv[])
00187 {
00188 double depth = 5;
00189 double lat=45.769216667, lon=16.001851667;
00190
00191 DiverMsg2 msg;
00192 msg.latitude = lat;
00193 msg.longitude = lon;
00194 msg.z = depth;
00195 msg.msg = 0;
00196 msg.pack<DiverMsg2::PositionInit>();
00197 writeLatLon(msg);
00198
00199 std::cout<<"Binary encoding:"<<std::bitset<48>(msg.fullmsg)<<std::endl;
00200
00201 using labust::tritech::DiverMsg;
00202 DiverMsg nmsg;
00203 nmsg.latitude = lat;
00204 nmsg.longitude = lon;
00205 nmsg.depth = depth;
00206
00207 uint64_t ret = nmsg.encode<DiverMsg::AutoTopside>(DiverMsg::PositionInit);
00208 std::cout<<"Binary encoding:"<<std::bitset<48>(ret)<<std::endl;
00209
00210 std::string test = nmsg.toString<DiverMsg::AutoTopside>(DiverMsg::PositionInit);
00211
00212 nmsg.decode<DiverMsg::AutoTopside>(ret);
00213 nmsg.fromString<DiverMsg::AutoDiver>(test);
00214 std::cout<<"Equal:"<<DiverMsg2::PositionInit::type<<"="<<nmsg.data[DiverMsg::type]<<std::endl;
00215 std::cout<<"Equal:"<<msg.lat<<"="<<nmsg.data[DiverMsg::lat]<<std::endl;
00216 std::cout<<"Equal:"<<msg.lon<<"="<<nmsg.data[DiverMsg::lon]<<std::endl;
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 return 0;
00286 }
00287
00288
00289