DCCL v4
Loading...
Searching...
No Matches
test.cpp
1// Copyright 2011-2023:
2// GobySoft, LLC (2013-)
3// Massachusetts Institute of Technology (2007-2014)
4// Community contributors (see AUTHORS file)
5// File authors:
6// Toby Schneider <toby@gobysoft.org>
7//
8//
9// This file is part of the Dynamic Compact Control Language Library
10// ("DCCL").
11//
12// DCCL is free software: you can redistribute it and/or modify
13// it under the terms of the GNU Lesser General Public License as published by
14// the Free Software Foundation, either version 2.1 of the License, or
15// (at your option) any later version.
16//
17// DCCL is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU Lesser General Public License for more details.
21//
22// You should have received a copy of the GNU Lesser General Public License
23// along with DCCL. If not, see <http://www.gnu.org/licenses/>.
24// tests usage of Legacy CCL
25
26#include "../../ccl/ccl_compatibility.h"
27#include "../../codec.h"
28#include "../../field_codec.h"
29#include "test.pb.h"
30
31using namespace dccl::test;
32
33using dccl::operator<<;
34
35bool double_cmp(double a, double b, int precision)
36{
37 int a_whole = a;
38 int b_whole = b;
39
40 int a_part = (a - a_whole) * pow(10.0, precision);
41 int b_part = (b - b_whole) * pow(10.0, precision);
42
43 return (a_whole == b_whole) && (a_part == b_part);
44}
45
46template <typename N> void check_normal_dccl(dccl::Codec& codec)
47{
48 codec.load<N>();
49 codec.info<N>(&dccl::dlog);
50 N normal_msg, normal_msg_out;
51 normal_msg.set_a(123);
52 normal_msg.set_b(321);
53
54 std::string encoded;
55 codec.encode(&encoded, normal_msg);
56 std::cout << dccl::hex_encode(encoded) << std::endl;
57 assert(dccl::hex_encode(encoded).substr(0, 2) == "20");
58 codec.decode(encoded, &normal_msg_out);
59
60 assert(normal_msg.SerializeAsString() == normal_msg_out.SerializeAsString());
61}
62
63int main(int /*argc*/, char* /*argv*/ [])
64{
65 dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
66
67 dccl::Codec codec("dccl.ccl.id", DCCL_CCL_COMPAT_NAME);
68
69 check_normal_dccl<NormalDCCL1Byte>(codec);
70 check_normal_dccl<NormalDCCL2Byte>(codec);
71
72 codec.info<dccl::legacyccl::protobuf::CCLMDATState>(&dccl::dlog);
73
74 dccl::legacyccl::protobuf::CCLMDATState state_in, state_out;
75 std::string test_state_encoded =
76 "0e86fa11ad20c9011b4432bf47d10000002401042f0e7d87fa111620c95a200a";
77 codec.decode(dccl::hex_decode(test_state_encoded), &state_out);
78 state_in.set_latitude(25.282416667);
79 state_in.set_longitude(-77.164266667);
80 state_in.set_fix_age(4);
81
82 auto now = std::chrono::system_clock::now();
83 std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);
84 std::tm input_tm = *std::gmtime(&now_time_t); // get current year
85 input_tm.tm_mon = 2; // zero indexed March
86 input_tm.tm_mday = 4;
87 input_tm.tm_hour = 17;
88 input_tm.tm_min = 1;
89 input_tm.tm_sec = 44;
90 input_tm.tm_isdst = -1;
91 std::time_t time_date = timegm(&input_tm);
92
93 state_in.set_time_date(dccl::legacyccl::TimeDateCodec::to_uint64_time(time_date));
94 state_in.set_heading(270);
95 state_in.set_depth(2323);
96 state_in.set_mission_mode(dccl::legacyccl::protobuf::CCLMDATState::NORMAL);
97 state_in.set_faults(dccl::hex_decode("00000024"));
98 state_in.set_faults_2(dccl::hex_decode("01"));
99 state_in.set_mission_leg(4);
100 state_in.set_est_velocity(1.88);
101 state_in.set_objective_index(dccl::hex_decode("0E"));
102 state_in.set_watts(500);
103 state_in.set_lat_goal(25.282440815262891);
104 state_in.set_lon_goal(-77.167505880296929);
105 state_in.set_battery_percent(90);
106 state_in.mutable_gfi_pitch_oil()->set_gfi(0);
107 state_in.mutable_gfi_pitch_oil()->set_pitch(6);
108 state_in.mutable_gfi_pitch_oil()->set_oil(55);
109
110 assert(double_cmp(state_in.latitude(), state_out.latitude(), 4));
111 assert(double_cmp(state_in.longitude(), state_out.longitude(), 4));
112 assert(state_in.fix_age() == state_out.fix_age());
113 assert(state_in.time_date() == state_out.time_date());
114 assert(dccl::round(state_in.heading(), 0) == dccl::round(state_out.heading(), 0));
115 assert(double_cmp(state_in.depth(), state_out.depth(), 1));
116 assert(state_in.mission_mode() == state_out.mission_mode());
117
118 // test the dynamically generated message
119 std::shared_ptr<google::protobuf::Message> state_in_2 =
121 dccl::legacyccl::protobuf::CCLMDATState::descriptor());
122 state_in_2->CopyFrom(state_in);
123
124 std::string state_encoded;
125 codec.encode(&state_encoded, *state_in_2);
126
127 dccl::legacyccl::protobuf::CCLMDATState state_out_2;
128 codec.decode(state_encoded, &state_out_2);
129
130 std::cout << "in:" << state_in << std::endl;
131 std::cout << test_state_encoded << std::endl;
132 std::cout << dccl::hex_encode(state_encoded) << std::endl;
133 std::cout << std::setprecision(16) << state_out.lon_goal() << std::endl;
134 std::cout << "out:" << state_out << std::endl;
135 std::cout << "out2: " << state_out_2 << std::endl;
136
137 assert(state_out.SerializeAsString() == state_out_2.SerializeAsString());
138 assert(test_state_encoded == dccl::hex_encode(state_encoded));
139
140 std::cout << dccl::hex_encode(state_out.faults()) << std::endl;
141 std::cout << dccl::hex_encode(state_out.faults_2()) << std::endl;
142
143 codec.info<dccl::legacyccl::protobuf::CCLMDATRedirect>(&dccl::dlog);
144
145 dccl::legacyccl::protobuf::CCLMDATRedirect redirect_in, redirect_out;
146 std::string test_redirect_encoded =
147 "07522cf9113d20c99964003d6464003d640be60014142035f911ef21c9000000";
148 codec.decode(dccl::hex_decode(test_redirect_encoded), &redirect_out);
149 redirect_in.set_message_number(82);
150 redirect_in.set_latitude(25.274995002149939);
151 redirect_in.set_longitude(-77.166669030984522);
152 redirect_in.set_transit_vertical_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::ALTITUDE);
153 redirect_in.set_transit_thrust_mode(
154 dccl::legacyccl::protobuf::CCLMDATRedirect::METERS_PER_SECOND);
155 redirect_in.set_survey_vertical_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::ALTITUDE);
156 redirect_in.set_survey_thrust_mode(
157 dccl::legacyccl::protobuf::CCLMDATRedirect::METERS_PER_SECOND);
158
159 redirect_in.set_depth_goal_transit(10.0);
160 redirect_in.set_speed_transit(2.0333333);
161 redirect_in.set_device_cmd_transit(100);
162
163 redirect_in.set_depth_goal_survey(10.0);
164 redirect_in.set_speed_survey(2.0333333);
165 redirect_in.set_device_cmd_survey(100);
166
167 redirect_in.set_num_rows(11);
168 redirect_in.set_row_length(230);
169 redirect_in.set_spacing_0(20);
170 redirect_in.set_spacing_1(20);
171 redirect_in.set_heading(45.176472);
172
173 redirect_in.set_lat_start(25.275183333);
174 redirect_in.set_lon_start(-77.15735);
175
176 redirect_in.set_spare(std::string(3, '\0'));
177
178 std::string redirect_encoded;
179 codec.encode(&redirect_encoded, redirect_in);
180
181 dccl::legacyccl::protobuf::CCLMDATRedirect redirect_out_2;
182 codec.decode(redirect_encoded, &redirect_out_2);
183
184 std::cout << "in:" << redirect_in << std::endl;
185 std::cout << test_redirect_encoded << std::endl;
186 std::cout << dccl::hex_encode(redirect_encoded) << std::endl;
187 std::cout << "out:" << redirect_out << std::endl;
188 std::cout << "out2: " << redirect_out_2 << std::endl;
189
190 assert(redirect_out.SerializeAsString() == redirect_out_2.SerializeAsString());
191 assert(test_redirect_encoded == dccl::hex_encode(redirect_encoded));
192
193 codec.info<dccl::legacyccl::protobuf::CCLMDATEmpty>(&dccl::dlog);
194 codec.info<dccl::legacyccl::protobuf::CCLMDATBathy>(&dccl::dlog);
195 codec.info<dccl::legacyccl::protobuf::CCLMDATCTD>(&dccl::dlog);
196 codec.info<dccl::legacyccl::protobuf::CCLMDATError>(&dccl::dlog);
197 codec.info<dccl::legacyccl::protobuf::CCLMDATCommand>(&dccl::dlog);
198
199 std::cout << "all tests passed" << std::endl;
200}
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition codec.h:63
static GoogleProtobufMessagePointer new_protobuf_message(const std::string &protobuf_type_name, bool user_pool_first=false)
Create a new (empty) Google Protobuf message of a given type by name.
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar)
Definition logger.h:214
Unit test namespace.
Definition test.cpp:45
void hex_encode(CharIterator begin, CharIterator end, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of begin is written to index...
Definition binary.h:100
void hex_decode(const std::string &in, std::string *out)
Decodes a (little-endian) hexadecimal string to a byte string. Index 0 and 1 (first byte) of in are w...
Definition binary.h:51