Note: Goby version 1 (shown here) is now considered obsolete. Please use version 2 for new projects, and consider upgrading old projects.

Goby Underwater Autonomy Project  Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
acomms/libdccl/message_var_head.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends