Goby v2
test.cpp
1 // Copyright 2009-2018 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 //
5 //
6 // This file is part of the Goby Underwater Autonomy Project Binaries
7 // ("The Goby Binaries").
8 //
9 // The Goby Binaries are free software: you can redistribute them and/or modify
10 // them under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // The Goby Binaries are distributed in the hope that they will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
21 
22 // tests usage of a custom DCCL ID codec
23 // including Legacy CCL
24 
25 #include "dccl/ccl/protobuf/ccl.pb.h"
26 #include "goby/acomms/acomms_helpers.h"
27 #include "goby/acomms/dccl.h"
28 #include "goby/common/time.h"
29 #include "goby/util/as.h"
30 #include "goby/util/dynamic_protobuf_manager.h"
31 #include "goby/util/primitive_types.h"
32 #include "goby/util/sci.h"
33 #include "test.pb.h"
34 
35 using goby::acomms::operator<<;
36 
38 {
39  private:
40  goby::acomms::Bitset encode(const goby::uint32& wire_value);
41 
42  goby::acomms::Bitset encode() { return encode(MINI_ID_OFFSET); }
43 
44  goby::uint32 decode(goby::acomms::Bitset* bits) { return bits->to_ulong() + MINI_ID_OFFSET; }
45 
46  unsigned size() { return MINI_ID_SIZE; }
47 
48  void validate() {}
49 
50  // Add this value when decoding to put us safely in our own namespace
51  // from the normal default DCCL Codec
52  enum
53  {
54  MINI_ID_OFFSET = 1000000
55  };
56  enum
57  {
58  MINI_ID_SIZE = 6
59  };
60 };
61 
62 bool double_cmp(double a, double b, int precision)
63 {
64  int a_whole = a;
65  int b_whole = b;
66 
67  int a_part = (a - a_whole) * pow(10.0, precision);
68  int b_part = (b - b_whole) * pow(10.0, precision);
69 
70  return (a_whole == b_whole) && (a_part == b_part);
71 }
72 
73 goby::acomms::Bitset MicroModemMiniPacketDCCLIDCodec::encode(const goby::uint32& wire_value)
74 {
75  // 16 bits, only 13 are useable, so
76  // 3 "blank bits" + 3 bits for us
77  return goby::acomms::Bitset(MINI_ID_SIZE, wire_value - MINI_ID_OFFSET);
78 }
79 
80 int main(int argc, char* argv[])
81 {
82  goby::glog.add_stream(goby::common::logger::DEBUG3, &std::cerr);
83  goby::glog.set_name(argv[0]);
84 
87  cfg.set_crypto_passphrase("309ldskjfla39");
88  codec->set_cfg(cfg);
89 
90  codec->add_id_codec<MicroModemMiniPacketDCCLIDCodec>("mini_id_codec");
91  codec->set_id_codec("mini_id_codec");
92 
93  codec->validate<MiniUser>();
94  codec->info<MiniUser>(&goby::glog);
95  MiniUser mini_user_msg_in, mini_user_msg_out;
96  mini_user_msg_in.set_user(876);
97  std::string encoded;
98  codec->encode(&encoded, mini_user_msg_in);
99  codec->decode(encoded, &mini_user_msg_out);
100  assert(mini_user_msg_out.SerializeAsString() == mini_user_msg_in.SerializeAsString());
101 
102  codec->validate<MiniOWTT>();
103  codec->info<MiniOWTT>(&goby::glog);
104 
105  MiniOWTT mini_owtt_in, mini_owtt_out;
106  mini_owtt_in.set_clock_mode(3);
107  mini_owtt_in.set_tod(12);
108  mini_owtt_in.set_user(13);
109 
110  codec->encode(&encoded, mini_owtt_in);
111  std::cout << "OWTT as hex: " << goby::util::hex_encode(encoded) << std::endl;
112 
113  codec->decode(encoded, &mini_owtt_out);
114  assert(mini_owtt_out.SerializeAsString() == mini_owtt_in.SerializeAsString());
115 
116  codec->validate<MiniAbort>();
117  codec->info<MiniAbort>(&goby::glog);
118 
119  MiniAbort mini_abort_in, mini_abort_out;
120  mini_abort_in.set_user(130);
121  codec->encode(&encoded, mini_abort_in);
122  codec->decode(encoded, &mini_abort_out);
123  assert(mini_abort_out.SerializeAsString() == mini_abort_in.SerializeAsString());
124 
125  cfg.clear_crypto_passphrase();
126  codec->set_cfg(cfg);
127 
128  void* dl_handle = dlopen("libdccl_ccl_compat" SHARED_LIBRARY_SUFFIX, RTLD_LAZY);
129 
130  if (!dl_handle)
131  {
132  std::cerr << "Failed to open libdccl_ccl_compat" SHARED_LIBRARY_SUFFIX << std::endl;
133  exit(1);
134  }
135  codec->load_shared_library_codecs(dl_handle);
136  codec->set_id_codec("dccl.ccl.id");
137 
138  codec->validate<NormalDCCL>();
139  codec->info<NormalDCCL>(&goby::glog);
140  NormalDCCL normal_msg, normal_msg_out;
141  normal_msg.set_a(123);
142  normal_msg.set_b(321);
143 
144  codec->encode(&encoded, normal_msg);
145  std::cout << goby::util::hex_encode(encoded) << std::endl;
146  assert(goby::util::hex_encode(encoded).substr(0, 2) == "20");
147  codec->decode(encoded, &normal_msg_out);
148 
149  assert(normal_msg.SerializeAsString() == normal_msg_out.SerializeAsString());
150 
151  codec->info<dccl::legacyccl::protobuf::CCLMDATState>(&goby::glog);
152 
153  dccl::legacyccl::protobuf::CCLMDATState state_in, state_out;
154  std::string test_state_encoded =
155  "0e86fa11ad20c9011b4432bf47d10000002401042f0e7d87fa111620c95a200a";
156  codec->decode(goby::util::hex_decode(test_state_encoded), &state_out);
157  state_in.set_latitude(25.282416667);
158  state_in.set_longitude(-77.164266667);
159  state_in.set_fix_age(4);
160 
161  boost::posix_time::ptime time_date(
162  boost::gregorian::date(boost::gregorian::day_clock::universal_day().year(),
163  boost::date_time::Mar, 04),
164  boost::posix_time::time_duration(17, 1, 44));
165 
166  state_in.set_time_date(goby::util::as<goby::uint64>(time_date));
167  state_in.set_heading(270);
168  state_in.set_depth(2323);
169  state_in.set_mission_mode(dccl::legacyccl::protobuf::CCLMDATState::NORMAL);
170  state_in.set_faults(goby::util::hex_decode("00000024"));
171  state_in.set_faults_2(goby::util::hex_decode("01"));
172  state_in.set_mission_leg(4);
173  state_in.set_est_velocity(1.88);
174  state_in.set_objective_index(goby::util::hex_decode("0E"));
175  state_in.set_watts(500);
176  state_in.set_lat_goal(25.282440815262891);
177  state_in.set_lon_goal(-77.167505880296929);
178  state_in.set_battery_percent(90);
179  state_in.mutable_gfi_pitch_oil()->set_gfi(0);
180  state_in.mutable_gfi_pitch_oil()->set_pitch(6);
181  state_in.mutable_gfi_pitch_oil()->set_oil(55);
182 
183  assert(double_cmp(state_in.latitude(), state_out.latitude(), 4));
184  assert(double_cmp(state_in.longitude(), state_out.longitude(), 4));
185  assert(state_in.fix_age() == state_out.fix_age());
186  assert(state_in.time_date() == state_out.time_date());
187  assert(goby::util::unbiased_round(state_in.heading(), 0) ==
188  goby::util::unbiased_round(state_out.heading(), 0));
189  assert(double_cmp(state_in.depth(), state_out.depth(), 1));
190  assert(state_in.mission_mode() == state_out.mission_mode());
191 
192  // test the dynamically generated message
193  boost::shared_ptr<google::protobuf::Message> state_in_2 =
194  goby::util::DynamicProtobufManager::new_protobuf_message(
195  dccl::legacyccl::protobuf::CCLMDATState::descriptor());
196  state_in_2->CopyFrom(state_in);
197 
198  std::string state_encoded;
199  codec->encode(&state_encoded, *state_in_2);
200 
201  dccl::legacyccl::protobuf::CCLMDATState state_out_2;
202  codec->decode(state_encoded, &state_out_2);
203 
204  std::cout << "in:" << state_in << std::endl;
205  std::cout << test_state_encoded << std::endl;
206  std::cout << goby::util::hex_encode(state_encoded) << std::endl;
207  std::cout << std::setprecision(16) << state_out.lon_goal() << std::endl;
208  std::cout << "out:" << state_out << std::endl;
209  std::cout << "out2: " << state_out_2 << std::endl;
210 
211  assert(state_out.SerializeAsString() == state_out_2.SerializeAsString());
212  assert(test_state_encoded == goby::util::hex_encode(state_encoded));
213 
214  std::cout << goby::util::hex_encode(state_out.faults()) << std::endl;
215  std::cout << goby::util::hex_encode(state_out.faults_2()) << std::endl;
216 
217  codec->info<dccl::legacyccl::protobuf::CCLMDATRedirect>(&goby::glog);
218 
219  dccl::legacyccl::protobuf::CCLMDATRedirect redirect_in, redirect_out;
220  std::string test_redirect_encoded =
221  "07522cf9113d20c99964003d6464003d640be60014142035f911ef21c9000000";
222  codec->decode(goby::util::hex_decode(test_redirect_encoded), &redirect_out);
223  redirect_in.set_message_number(82);
224  redirect_in.set_latitude(25.274995002149939);
225  redirect_in.set_longitude(-77.166669030984522);
226  redirect_in.set_transit_vertical_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::ALTITUDE);
227  redirect_in.set_transit_thrust_mode(
228  dccl::legacyccl::protobuf::CCLMDATRedirect::METERS_PER_SECOND);
229  redirect_in.set_survey_vertical_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::ALTITUDE);
230  redirect_in.set_survey_thrust_mode(
231  dccl::legacyccl::protobuf::CCLMDATRedirect::METERS_PER_SECOND);
232 
233  redirect_in.set_depth_goal_transit(10.0);
234  redirect_in.set_speed_transit(2.0333333);
235  redirect_in.set_device_cmd_transit(100);
236 
237  redirect_in.set_depth_goal_survey(10.0);
238  redirect_in.set_speed_survey(2.0333333);
239  redirect_in.set_device_cmd_survey(100);
240 
241  redirect_in.set_num_rows(11);
242  redirect_in.set_row_length(230);
243  redirect_in.set_spacing_0(20);
244  redirect_in.set_spacing_1(20);
245  redirect_in.set_heading(45.176472);
246 
247  redirect_in.set_lat_start(25.275183333);
248  redirect_in.set_lon_start(-77.15735);
249 
250  redirect_in.set_spare(std::string(3, '\0'));
251 
252  std::string redirect_encoded;
253 
254  codec->encode(&redirect_encoded, redirect_in);
255 
256  dccl::legacyccl::protobuf::CCLMDATRedirect redirect_out_2;
257  codec->decode(redirect_encoded, &redirect_out_2);
258 
259  std::cout << "in:" << redirect_in << std::endl;
260  std::cout << test_redirect_encoded << std::endl;
261  std::cout << goby::util::hex_encode(redirect_encoded) << std::endl;
262  std::cout << "out:" << redirect_out << std::endl;
263  std::cout << "out2: " << redirect_out_2 << std::endl;
264 
265  assert(redirect_out.SerializeAsString() == redirect_out_2.SerializeAsString());
266  assert(test_redirect_encoded == goby::util::hex_encode(redirect_encoded));
267 
268  codec->info<dccl::legacyccl::protobuf::CCLMDATEmpty>(&goby::glog);
269  codec->info<dccl::legacyccl::protobuf::CCLMDATBathy>(&goby::glog);
270  codec->info<dccl::legacyccl::protobuf::CCLMDATCTD>(&goby::glog);
271  codec->info<dccl::legacyccl::protobuf::CCLMDATError>(&goby::glog);
272  codec->info<dccl::legacyccl::protobuf::CCLMDATCommand>(&goby::glog);
273 
274  std::cout << "all tests passed" << std::endl;
275 }
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
Definition: flex_ostream.h:67
static DCCLCodec * get()
DCCLCodec is a singleton class; use this to get a pointer to the class.
Definition: dccl.h:124
google::protobuf::uint32 uint32
an unsigned 32 bit integer
common::FlexOstream glog
Access the Goby logger through this object.
void add_stream(logger::Verbosity verbosity=logger::VERBOSE, std::ostream *os=0)
Attach a stream object (e.g. std::cout, std::ofstream, ...) to the logger with desired verbosity...
Definition: flex_ostream.h:96