23 #include <boost/algorithm/string.hpp> 24 #include <boost/math/special_functions/fpclassify.hpp> 26 #include "goby/acomms/dccl.h" 27 #include "goby/util/sci.h" 29 #include "moos_translator.h" 31 const double NaN = std::numeric_limits<double>::quiet_NaN();
33 void goby::moos::MOOSTranslator::initialize(
double lat_origin,
double lon_origin,
34 const std::string& modem_id_lookup_path)
36 transitional::DCCLAlgorithmPerformer* ap = transitional::DCCLAlgorithmPerformer::getInstance();
39 ap->add_algorithm(
"power_to_dB", &alg_power_to_dB);
40 ap->add_algorithm(
"dB_to_power", &alg_dB_to_power);
41 ap->add_adv_algorithm(
"TSD_to_soundspeed", &alg_TSD_to_soundspeed);
42 ap->add_algorithm(
"to_lower", &alg_to_lower);
43 ap->add_algorithm(
"to_upper", &alg_to_upper);
44 ap->add_algorithm(
"angle_0_360", &alg_angle_0_360);
45 ap->add_algorithm(
"angle_-180_180", &alg_angle_n180_180);
46 ap->add_algorithm(
"lat2hemisphere_initial", &alg_lat2hemisphere_initial);
47 ap->add_algorithm(
"lon2hemisphere_initial", &alg_lon2hemisphere_initial);
49 ap->add_algorithm(
"lat2nmea_lat", &alg_lat2nmea_lat);
50 ap->add_algorithm(
"lon2nmea_lon", &alg_lon2nmea_lon);
52 ap->add_algorithm(
"unix_time2nmea_time", &alg_unix_time2nmea_time);
54 ap->add_algorithm(
"abs", &alg_abs);
56 ap->add_adv_algorithm(
"add", &alg_add);
57 ap->add_adv_algorithm(
"subtract", &alg_subtract);
59 if (!modem_id_lookup_path.empty())
61 std::string id_lookup_output = modem_lookup_.read_lookup_file(modem_id_lookup_path);
64 ap->add_algorithm(
"modem_id2name",
65 boost::bind(&MOOSTranslator::alg_modem_id2name,
this, _1));
66 ap->add_algorithm(
"modem_id2type",
67 boost::bind(&MOOSTranslator::alg_modem_id2type,
this, _1));
68 ap->add_algorithm(
"name2modem_id",
69 boost::bind(&MOOSTranslator::alg_name2modem_id,
this, _1));
77 if (!(boost::math::isnan)(lat_origin) && !(boost::math::isnan)(lon_origin))
79 if (geodesy_.Initialise(lat_origin, lon_origin))
81 ap->add_adv_algorithm(
"lat2utm_y",
82 boost::bind(&MOOSTranslator::alg_lat2utm_y,
this, _1, _2));
83 ap->add_adv_algorithm(
"lon2utm_x",
84 boost::bind(&MOOSTranslator::alg_lon2utm_x,
this, _1, _2));
85 ap->add_adv_algorithm(
"utm_x2lon",
86 boost::bind(&MOOSTranslator::alg_utm_x2lon,
this, _1, _2));
87 ap->add_adv_algorithm(
"utm_y2lat",
88 boost::bind(&MOOSTranslator::alg_utm_y2lat,
this, _1, _2));
93 void goby::moos::alg_power_to_dB(transitional::DCCLMessageVal& val_to_mod)
95 val_to_mod = 10 * log10(
double(val_to_mod));
98 void goby::moos::alg_dB_to_power(transitional::DCCLMessageVal& val_to_mod)
100 val_to_mod = pow(10.0,
double(val_to_mod) / 10.0);
104 void goby::moos::alg_TSD_to_soundspeed(transitional::DCCLMessageVal& val,
105 const std::vector<transitional::DCCLMessageVal>& ref_vals)
107 val.set(goby::util::mackenzie_soundspeed(val, ref_vals[0], ref_vals[1]), 3);
110 void goby::moos::alg_angle_0_360(transitional::DCCLMessageVal& angle)
113 while (a < 0) a += 360;
114 while (a >= 360) a -= 360;
118 void goby::moos::alg_angle_n180_180(transitional::DCCLMessageVal& angle)
121 while (a < -180) a += 360;
122 while (a >= 180) a -= 360;
126 void goby::moos::MOOSTranslator::alg_lat2utm_y(
127 transitional::DCCLMessageVal& mv,
const std::vector<transitional::DCCLMessageVal>& ref_vals)
130 double lon = ref_vals[0];
134 if (!(boost::math::isnan)(lat) && !(boost::math::isnan)(lon))
135 geodesy_.LatLong2LocalUTM(lat, lon, y, x);
139 void goby::moos::MOOSTranslator::alg_lon2utm_x(
140 transitional::DCCLMessageVal& mv,
const std::vector<transitional::DCCLMessageVal>& ref_vals)
143 double lat = ref_vals[0];
147 if (!(boost::math::isnan)(lat) && !(boost::math::isnan)(lon))
148 geodesy_.LatLong2LocalUTM(lat, lon, y, x);
152 void goby::moos::MOOSTranslator::alg_utm_x2lon(
153 transitional::DCCLMessageVal& mv,
const std::vector<transitional::DCCLMessageVal>& ref_vals)
156 double y = ref_vals[0];
160 if (!(boost::math::isnan)(y) && !(boost::math::isnan)(x))
161 geodesy_.UTM2LatLong(x, y, lat, lon);
163 const int LON_INT_DIGITS = 3;
165 goby::util::unbiased_round(lon, std::numeric_limits<double>::digits10 - LON_INT_DIGITS - 1);
169 void goby::moos::MOOSTranslator::alg_utm_y2lat(
170 transitional::DCCLMessageVal& mv,
const std::vector<transitional::DCCLMessageVal>& ref_vals)
173 double x = ref_vals[0];
177 if (!(boost::math::isnan)(x) && !(boost::math::isnan)(y))
178 geodesy_.UTM2LatLong(x, y, lat, lon);
180 const int LAT_INT_DIGITS = 2;
182 goby::util::unbiased_round(lat, std::numeric_limits<double>::digits10 - LAT_INT_DIGITS - 1);
186 void goby::moos::MOOSTranslator::alg_modem_id2name(transitional::DCCLMessageVal& in)
188 bool is_numeric =
true;
189 BOOST_FOREACH (
const char c, std::string(in))
198 in = modem_lookup_.get_name_from_id(boost::lexical_cast<unsigned>(std::string(in)));
201 void goby::moos::MOOSTranslator::alg_modem_id2type(transitional::DCCLMessageVal& in)
203 bool is_numeric =
true;
204 BOOST_FOREACH (
const char c, std::string(in))
214 in = modem_lookup_.get_type_from_id(boost::lexical_cast<unsigned>(std::string(in)));
217 void goby::moos::MOOSTranslator::alg_name2modem_id(transitional::DCCLMessageVal& in)
219 std::stringstream ss;
220 ss << modem_lookup_.get_id_from_name(std::string(in));
224 void goby::moos::alg_to_upper(transitional::DCCLMessageVal& val_to_mod)
226 val_to_mod = boost::algorithm::to_upper_copy(std::string(val_to_mod));
229 void goby::moos::alg_to_lower(transitional::DCCLMessageVal& val_to_mod)
231 val_to_mod = boost::algorithm::to_lower_copy(std::string(val_to_mod));
234 void goby::moos::alg_lat2hemisphere_initial(transitional::DCCLMessageVal& val_to_mod)
236 double lat = val_to_mod;
243 void goby::moos::alg_lon2hemisphere_initial(transitional::DCCLMessageVal& val_to_mod)
245 double lon = val_to_mod;
252 void goby::moos::alg_abs(transitional::DCCLMessageVal& val_to_mod)
254 val_to_mod = std::abs(
double(val_to_mod));
257 void goby::moos::alg_unix_time2nmea_time(transitional::DCCLMessageVal& val_to_mod)
259 double unix_time = val_to_mod;
263 boost::format f(
"%02d%02d%02d.%06d");
264 f % ptime.time_of_day().hours() % ptime.time_of_day().minutes() %
265 ptime.time_of_day().seconds() %
266 (ptime.time_of_day().fractional_seconds() * 1000000 /
267 boost::posix_time::time_duration::ticks_per_second());
269 val_to_mod = f.str();
272 void goby::moos::alg_lat2nmea_lat(transitional::DCCLMessageVal& val_to_mod)
274 double lat = val_to_mod;
277 boost::format f(
"%02d%02d.%04d");
279 int degrees = std::floor(lat);
280 int minutes = std::floor((lat - degrees) * 60);
281 int ten_thousandth_minutes = std::floor(((lat - degrees) * 60 - minutes) * 10000);
283 f % degrees % minutes % ten_thousandth_minutes;
285 val_to_mod = f.str();
288 void goby::moos::alg_lon2nmea_lon(transitional::DCCLMessageVal& val_to_mod)
290 double lon = val_to_mod;
293 boost::format f(
"%03d%02d.%04d");
295 int degrees = std::floor(lon);
296 int minutes = std::floor((lon - degrees) * 60);
297 int ten_thousandth_minutes = std::floor(((lon - degrees) * 60 - minutes) * 10000);
299 f % degrees % minutes % ten_thousandth_minutes;
301 val_to_mod = f.str();
304 void goby::moos::alg_subtract(transitional::DCCLMessageVal& val_to_mod,
305 const std::vector<transitional::DCCLMessageVal>& ref_vals)
307 double diff = val_to_mod;
309 for (std::vector<transitional::DCCLMessageVal>::const_iterator it = ref_vals.begin(),
310 end = ref_vals.end();
312 diff -= static_cast<double>(*it);
317 void goby::moos::alg_add(transitional::DCCLMessageVal& val_to_mod,
318 const std::vector<transitional::DCCLMessageVal>& ref_vals)
320 double sum = val_to_mod;
322 for (std::vector<transitional::DCCLMessageVal>::const_iterator it = ref_vals.begin(),
323 end = ref_vals.end();
325 sum += static_cast<double>(*it);
common::FlexOstream glog
Access the Goby logger through this object.
boost::posix_time::ptime unix_double2ptime(double given_time)
convert to boost date_time ptime from the number of seconds (including fractional) since 1/1/1970 0:0...