Goby Underwater Autonomy Project
Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
|
00001 // copyright 2008, 2009, 2010 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 #include "message_var_float.h" 00021 00022 #include "goby/util/sci.h" 00023 00024 goby::acomms::DCCLMessageVarFloat::DCCLMessageVarFloat(double max /*= std::numeric_limits<double>::max()*/, double min /*= 0*/, double precision /*= 0*/) 00025 : DCCLMessageVar(), 00026 max_(max), 00027 min_(min), 00028 precision_(precision), 00029 max_delta_(acomms::NaN) 00030 { } 00031 00032 int goby::acomms::DCCLMessageVarFloat::calc_total_size() const 00033 { 00034 if(using_delta_differencing()) 00035 // key frame + N-1 delta frames 00036 return key_size() + (array_length_-1)*delta_size(); 00037 else 00038 // size of array * bits / element 00039 return array_length_*key_size(); 00040 } 00041 00042 void goby::acomms::DCCLMessageVarFloat::initialize_specific() 00043 { 00044 // flip max and min if needed 00045 if(max_ < min_) 00046 { 00047 double tmp = max_; 00048 max_ = min_; 00049 min_ = tmp; 00050 } 00051 00052 if(using_delta_differencing() && max_delta_ < 0) 00053 max_delta_ = -max_delta_; 00054 } 00055 00056 void goby::acomms::DCCLMessageVarFloat::pre_encode(DCCLMessageVal& v) 00057 { 00058 double r; 00059 if(v.get(r)) v = util::unbiased_round(r,precision_); 00060 } 00061 00062 00063 boost::dynamic_bitset<unsigned char> goby::acomms::DCCLMessageVarFloat::encode_specific(const DCCLMessageVal& v) 00064 { 00065 double r; 00066 00067 if(!v.get(r) || (r < min() || r > max())) return boost::dynamic_bitset<unsigned char>(); 00068 00069 // delta-differencing 00070 if(is_delta()) 00071 { 00072 r += max_delta_ - double(key_val_); 00073 if(r > 2*max_delta_ || r < 0) return boost::dynamic_bitset<unsigned char>(); 00074 } 00075 else 00076 { 00077 r -= min_; 00078 } 00079 00080 r *= pow(10.0, double(precision_)); 00081 //r = util::unbiased_round(r, 0); 00082 00083 return boost::dynamic_bitset<unsigned char>(calc_size(), static_cast<unsigned long>(r)+1); 00084 } 00085 00086 goby::acomms::DCCLMessageVal goby::acomms::DCCLMessageVarFloat::decode_specific(boost::dynamic_bitset<unsigned char>& b) 00087 { 00088 unsigned long t = b.to_ulong(); 00089 if(!t) return DCCLMessageVal(); 00090 00091 --t; 00092 if(is_delta()) 00093 return cast(double(t) / (pow(10.0, double(precision_))) - double(max_delta_) + double(key_val_), precision_); 00094 else 00095 return cast(double(t) / (pow(10.0, double(precision_))) + min_, precision_); 00096 } 00097 00098 void goby::acomms::DCCLMessageVarFloat::get_display_specific(std::stringstream& ss) const 00099 { 00100 ss << "\t\t[min, max] = [" << min_ << "," << max_ << "]" << std::endl; 00101 ss << "\t\tprecision: {" << precision_ << "}" << std::endl; 00102 00103 if(using_delta_differencing()) 00104 { 00105 ss << "\t\tmax_delta: {" << max_delta_ << "}" << std::endl; 00106 ss << "\t\tdelta element size [bits]: [" << delta_size() << "]" << std::endl; 00107 } 00108 }