Goby Underwater Autonomy Project
Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
|
00001 // copyright 2008, 2009 t. schneider tes@mit.edu 00002 // 00003 // this file is part of the Dynamic Compact Control Language (DCCL), 00004 // the goby-acomms codec. goby-acomms is a collection of libraries 00005 // for acoustic underwater networking 00006 // 00007 // This program is free software: you can redistribute it and/or modify 00008 // it under the terms of the GNU General Public License as published by 00009 // the Free Software Foundation, either version 3 of the License, or 00010 // (at your option) any later version. 00011 // 00012 // This software is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with this software. If not, see <http://www.gnu.org/licenses/>. 00019 00020 #ifndef MESSAGE_VAR_HEAD20100317H 00021 #define MESSAGE_VAR_HEAD20100317H 00022 00023 #include "message_var.h" 00024 00025 #include "goby/util/time.h" 00026 #include "goby/util/sci.h" 00027 00028 namespace goby 00029 { 00030 namespace acomms 00031 { 00032 class DCCLMessageVarHead : public DCCLMessageVarInt 00033 { 00034 public: 00035 DCCLMessageVarHead(const std::string& default_name, int bit_size) 00036 : DCCLMessageVarInt(pow(2, bit_size)-1, 0), 00037 bit_size_(bit_size), 00038 default_name_(default_name) 00039 { set_name(default_name); } 00040 00041 int calc_size() const 00042 { return bit_size_; } 00043 00044 int calc_total_size() const 00045 { return bit_size_; } 00046 00047 00048 private: 00049 void initialize_specific() 00050 { 00051 if(default_name_ == name_) source_var_.clear(); 00052 } 00053 00054 virtual void set_defaults_specific(DCCLMessageVal& v, unsigned modem_id, unsigned id) 00055 { } 00056 00057 virtual boost::dynamic_bitset<unsigned char> encode_specific(const DCCLMessageVal& v) 00058 { return boost::dynamic_bitset<unsigned char>(calc_size(), long(v)); } 00059 00060 virtual DCCLMessageVal decode_specific(boost::dynamic_bitset<unsigned char>& b) 00061 { return DCCLMessageVal(long(b.to_ulong())); } 00062 00063 protected: 00064 int bit_size_; 00065 std::string default_name_; 00066 }; 00067 00068 class DCCLMessageVarTime : public DCCLMessageVarHead 00069 { 00070 public: 00071 DCCLMessageVarTime(): 00072 DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_TIME], 00073 acomms::HEAD_TIME_SIZE) 00074 { } 00075 00076 void set_defaults_specific(DCCLMessageVal& v, unsigned modem_id, unsigned id) 00077 { 00078 double d; 00079 v = (!v.empty() && v.get(d)) ? v : DCCLMessageVal(util::ptime2unix_double(util::goby_time())); 00080 } 00081 00082 boost::dynamic_bitset<unsigned char> encode_specific(const DCCLMessageVal& v) 00083 { 00084 // trim to time of day 00085 boost::posix_time::time_duration time_of_day = util::unix_double2ptime(v).time_of_day(); 00086 00087 return boost::dynamic_bitset<unsigned char>(calc_size(), long(util::unbiased_round(util::time_duration2double(time_of_day), 0))); 00088 } 00089 00090 DCCLMessageVal decode_specific(boost::dynamic_bitset<unsigned char>& b) 00091 { 00092 // add the date back in (assumes message sent the same day received) 00093 DCCLMessageVal v(long(b.to_ulong())); 00094 00095 using namespace boost::posix_time; 00096 using namespace boost::gregorian; 00097 00098 ptime now = util::goby_time(); 00099 date day_sent; 00100 00101 // this logic will break if there is a separation between message sending and 00102 // message receipt of greater than 1/2 day (twelve hours) 00103 00104 // if message is from part of the day removed from us by 12 hours, we assume it 00105 // was sent yesterday 00106 if(abs(now.time_of_day().total_seconds() - double(v)) > hours(12).total_seconds()) 00107 day_sent = now.date() - days(1); 00108 else // otherwise figure it was sent today 00109 day_sent = now.date(); 00110 00111 v.set(double(v) + util::ptime2unix_double(ptime(day_sent,seconds(0)))); 00112 return v; 00113 } 00114 }; 00115 00116 class DCCLMessageVarCCLID : public DCCLMessageVarHead 00117 { 00118 public: 00119 DCCLMessageVarCCLID(): 00120 DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_CCL_ID], 00121 acomms::HEAD_CCL_ID_SIZE) { } 00122 00123 void set_defaults_specific(DCCLMessageVal& v, unsigned modem_id, unsigned id) 00124 { 00125 v = long(acomms::DCCL_CCL_HEADER); 00126 } 00127 }; 00128 00129 class DCCLMessageVarDCCLID : public DCCLMessageVarHead 00130 { 00131 public: 00132 DCCLMessageVarDCCLID() 00133 : DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_DCCL_ID], 00134 acomms::HEAD_DCCL_ID_SIZE) 00135 { } 00136 00137 void set_defaults_specific(DCCLMessageVal& v, unsigned modem_id, unsigned id) 00138 { 00139 v = (!v.empty()) ? v : DCCLMessageVal(long(id)); 00140 } 00141 }; 00142 00143 class DCCLMessageVarSrc : public DCCLMessageVarHead 00144 { 00145 public: 00146 DCCLMessageVarSrc() 00147 : DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_SRC_ID], 00148 acomms::HEAD_SRC_ID_SIZE) 00149 { } 00150 00151 void set_defaults_specific(DCCLMessageVal& v, unsigned modem_id, unsigned id) 00152 { 00153 v = (!v.empty()) ? v : DCCLMessageVal(long(modem_id)); 00154 } 00155 }; 00156 00157 class DCCLMessageVarDest : public DCCLMessageVarHead 00158 { 00159 public: 00160 DCCLMessageVarDest(): 00161 DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_DEST_ID], 00162 acomms::HEAD_DEST_ID_SIZE) { } 00163 00164 void set_defaults_specific(DCCLMessageVal& v, unsigned modem_id, unsigned id) 00165 { 00166 v = (!v.empty()) ? v : DCCLMessageVal(long(acomms::BROADCAST_ID)); 00167 } 00168 }; 00169 00170 class DCCLMessageVarMultiMessageFlag : public DCCLMessageVarHead 00171 { 00172 public: 00173 DCCLMessageVarMultiMessageFlag(): 00174 DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_MULTIMESSAGE_FLAG], 00175 acomms::HEAD_FLAG_SIZE) { } 00176 00177 boost::dynamic_bitset<unsigned char> encode_specific(const DCCLMessageVal& v) 00178 { return boost::dynamic_bitset<unsigned char>(calc_size(), bool(v)); } 00179 00180 DCCLMessageVal decode_specific(boost::dynamic_bitset<unsigned char>& b) 00181 { return DCCLMessageVal(bool(b.to_ulong())); } 00182 00183 }; 00184 00185 class DCCLMessageVarBroadcastFlag : public DCCLMessageVarHead 00186 { 00187 public: 00188 DCCLMessageVarBroadcastFlag(): 00189 DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_BROADCAST_FLAG], 00190 acomms::HEAD_FLAG_SIZE) { } 00191 00192 boost::dynamic_bitset<unsigned char> encode_specific(const DCCLMessageVal& v) 00193 { return boost::dynamic_bitset<unsigned char>(calc_size(), bool(v)); } 00194 00195 DCCLMessageVal decode_specific(boost::dynamic_bitset<unsigned char>& b) 00196 { return DCCLMessageVal(bool(b.to_ulong())); } 00197 00198 }; 00199 00200 class DCCLMessageVarUnused : public DCCLMessageVarHead 00201 { 00202 public: 00203 DCCLMessageVarUnused(): 00204 DCCLMessageVarHead(acomms::DCCL_HEADER_NAMES[acomms::HEAD_UNUSED], 00205 acomms::HEAD_UNUSED_SIZE) { } 00206 00207 00208 }; 00209 00210 } 00211 } 00212 #endif