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 #ifndef DIVERMSG_HPP_
00038 #define DIVERMSG_HPP_
00039 #include <labust/tritech/detail-tks/message_preprocess.hpp>
00040
00041 #include <cstdint>
00042 #include <map>
00043
00044 namespace labust
00045 {
00046 namespace tritech
00047 {
00048 struct DiverMsg;
00049
00050 struct Packer
00051 {
00052 virtual ~Packer(){};
00053 virtual uint64_t pack(DiverMsg& msg) = 0;
00054 virtual void unpack(uint64_t data, DiverMsg& msg) = 0;
00055 };
00056
00057 struct DiverMsg
00058 {
00059 struct AutoTopside{};
00060 struct AutoDiver{};
00061
00062 DEFINE_TOPSIDE_MESSAGES(
00063 (PositionInit,1,0,22,0)
00064 (Position,2,7,18,1)
00065 (PositionMsg,3,7,7,23)
00066 (PositionDef,5,7,14,9))
00067
00068 DEFINE_DIVER_MESSAGES(
00069 (PositionInitAck,1,0,22,0)
00070 (Msg,2,0,0,44))
00071
00072 DiverMsg():
00073 latitude(0),
00074 longitude(0),
00075 z(0),
00076 depthRes(0.5),
00077 msgType(0)
00078 {
00079 DiverMsg::registerTopsideMessages();
00080 DiverMsg::registerDiverMessages();
00081 };
00082
00083
00084 template <class msg>
00085 uint64_t pack()
00086 {
00087 msgType = msg::type;
00088 fullmsg = msg::type;
00089 fullmsg <<= msg::depthSize;
00090 fullmsg |= int(z/depthRes) & boost::low_bits_mask_t<msg::depthSize>::sig_bits;
00091 fullmsg <<= msg::latlonSize;
00092 latlonToBits<msg::latlonSize>(latitude,longitude);
00093 fullmsg |= lat & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00094 fullmsg <<= msg::latlonSize;
00095 fullmsg |= lon & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00096 fullmsg <<= msg::msgSize;
00097 fullmsg |= this->msg & boost::low_bits_mask_t<msg::msgSize>::sig_bits;
00098 return fullmsg;
00099 }
00100
00101 static inline uint8_t testType(uint64_t data, size_t msgSize = 48)
00102 {
00103 return (data >> (msgSize - 4)) & 0xF;
00104 }
00105
00106 template <class msg>
00107 void unpack(uint64_t data)
00108 {
00109 fullmsg=data;
00110 this->msg = data & boost::low_bits_mask_t<msg::msgSize>::sig_bits;
00111 data >>= msg::msgSize;
00112 lon = data & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00113 data >>= msg::latlonSize;
00114 lat = data & boost::low_bits_mask_t<msg::latlonSize>::sig_bits;
00115 data >>= msg::latlonSize;
00116 depth = data & boost::low_bits_mask_t<msg::depthSize>::sig_bits;
00117 data >>= msg::depthSize;
00118 msgType = data & 0x0F;
00119 assert((msgType == msg::type) &&
00120 "DiverMsg desired unpack type and received data type do not match.");
00121 };
00122
00123 template <size_t precission>
00124 std::pair<int,int> latlonToBits(double lat, double lon){return std::pair<int,int>(lat,lon);};
00125
00126 double latitude, longitude, z, depthRes;
00127 uint64_t fullmsg;
00128 uint8_t depth, msgType;
00129 int lat,lon;
00130 uint64_t msg;
00131
00132
00133
00134 private:
00135 std::map<int, boost::shared_ptr<Packer> > topsideMap, diverMap;
00136 };
00137
00138 template <>
00139 inline uint64_t DiverMsg::pack<DiverMsg::AutoTopside>()
00140 {
00141 assert(topsideMap.find(msgType) != topsideMap.end());
00142 return topsideMap[msgType]->pack(*this);
00143 }
00144
00145 template <>
00146 inline void DiverMsg::unpack<DiverMsg::AutoTopside>(uint64_t data)
00147 {
00148 testType(data);
00149 assert(topsideMap.find(msgType) != topsideMap.end());
00150 topsideMap[msgType]->unpack(data, *this);
00151 }
00152
00153 template <>
00154 inline uint64_t DiverMsg::pack<DiverMsg::AutoDiver>()
00155 {
00156 assert(diverMap.find(msgType) != diverMap.end());
00157 return diverMap[msgType]->pack(*this);
00158 }
00159
00160 template <>
00161 inline void DiverMsg::unpack<DiverMsg::AutoDiver>(uint64_t data)
00162 {
00163 testType(data);
00164 assert(diverMap.find(msgType) != diverMap.end());
00165 diverMap[msgType]->unpack(data,*this);
00166 }
00167
00168 template <>
00169 inline std::pair<int,int> DiverMsg::latlonToBits<22>(double lat, double lon)
00170 {
00171 double min = (lon - int(lon))*60;
00172 this->lon = int((int(lon)+180)*10000 + min*100);
00173
00174 min = (lat - int(lat))*60;
00175 this->lat = int((int(lat)+90)*10000 + min*100);
00176
00177 return std::pair<int,int>(this->lat,this->lon);
00178 }
00179
00180 template <>
00181 inline std::pair<int,int> DiverMsg::latlonToBits<18>(double lat, double lon)
00182 {
00183 this->lat = int((lat - int(lat))*600000)%100000;
00184 this->lon = int((lon - int(lon))*600000)%100000;
00185 return std::pair<int,int>(this->lat,this->lon);
00186 }
00187
00188 template <>
00189 std::pair<int,int> DiverMsg::latlonToBits<14>(double lat, double lon)
00190 {
00191 double min = (lon - int(lon))*60;
00192 this->lon = int((min - int(min))*10000);
00193
00194 min = (lat - int(lat))*60;
00195 this->lat = int((min - int(min))*10000);
00196
00197 return std::pair<int,int>(this->lat,this->lon);
00198 }
00199
00200 template <>
00201 inline std::pair<int,int> DiverMsg::latlonToBits<7>(double lat, double lon)
00202 {
00203 latlonToBits<14>(lat,lon);
00204 this->lat%=100;
00205 this->lon%=100;
00206 return std::pair<int,int>(this->lat,this->lon);
00207 }
00208 }
00209 }
00210
00211 #include <labust/tritech/detail-tks/message_preprocess_undef.hpp>
00212
00213
00214 #endif
00215
00216
00217