00001
00002 #include <string.h>
00003 #include <stdio.h>
00004 #include <math.h>
00005 #include <check.h>
00006 #include "check_utils.h"
00007
00008 #include <rtcm3.h>
00009
00010 START_TEST(test_rtcm3_check_frame)
00011 {
00012
00013 u8 test_data[] = {
00014
00015 0xD3, 0x00, 0x13,
00016
00017 0x3E, 0xD7, 0xD3, 0x02, 0x02, 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD,
00018 0x62, 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33,
00019
00020 0x36, 0x0B, 0x98
00021 };
00022
00023
00024 s16 ret = rtcm3_check_frame(test_data);
00025 fail_unless(ret == 19,
00026 "Should return length 19 for test_data, got %d", ret);
00027
00028
00029 test_data[0] = 0x22;
00030 ret = rtcm3_check_frame(test_data);
00031 fail_unless(ret == -1,
00032 "Should return -1 for test_data with invalid preamble, got %d", ret);
00033
00034
00035 test_data[0] = 0xD3;
00036 test_data[4] = 0x22;
00037 ret = rtcm3_check_frame(test_data);
00038 fail_unless(ret == -2,
00039 "Should return -2 for test_data with invalid CRC, got %d", ret);
00040 }
00041 END_TEST
00042
00043 START_TEST(test_rtcm3_write_frame)
00044 {
00045 u8 test_data[] = {
00046
00047 0x22, 0x22, 0x22,
00048
00049 0x3E, 0xD7, 0xD3, 0x02, 0x02, 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD,
00050 0x62, 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33,
00051
00052 0x22, 0x22, 0x22
00053 };
00054
00055
00056 u8 test_data_expected[] = {
00057
00058 0xD3, 0x00, 0x13,
00059
00060 0x3E, 0xD7, 0xD3, 0x02, 0x02, 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD,
00061 0x62, 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33,
00062
00063 0x36, 0x0B, 0x98
00064 };
00065
00066 u8 test_empty[] = {
00067
00068 0x22, 0x22, 0x22,
00069
00070 0x22, 0x22, 0x22
00071 };
00072
00073 u8 test_empty_expected[] = {
00074
00075 0xD3, 0x00, 0x00,
00076
00077 0x47, 0xEA, 0x4B
00078 };
00079
00080 s8 ret = rtcm3_write_frame(2222, NULL);
00081
00082 fail_unless(ret == -1,
00083 "Should return -1 if length is larger than 1023, got %d", ret);
00084
00085 fail_unless(rtcm3_write_frame(0, test_empty) == 0,
00086 "Returned error on test_in_empty");
00087
00088 fail_unless(memcmp(test_empty, test_empty_expected, 6) == 0,
00089 "test_empty != test_empty_expected");
00090
00091 fail_unless(rtcm3_write_frame(sizeof(test_data)-6, test_data) == 0,
00092 "Returned error on test_in_empty");
00093
00094 fail_unless(memcmp(test_data, test_data_expected, sizeof(test_data)) == 0,
00095 "test_data != test_data_expected");
00096 }
00097 END_TEST
00098
00099 START_TEST(test_rtcm3_read_write_header)
00100 {
00101 u8 buff[22];
00102
00103 gps_time_t t = {
00104 .wn = 22,
00105 .tow = 22.222
00106 };
00107
00108 rtcm3_write_header(buff, 1234, 2269, t, 1, 22, 1, 6);
00109
00110 u16 type, id;
00111 u8 sync, n_sat, div_free, smooth;
00112 double tow;
00113
00114 rtcm3_read_header(buff, &type, &id, &tow, &sync, &n_sat, &div_free, &smooth);
00115
00116 fail_unless(type == 1234, "type decode error, decoded %d, expected 1234", type);
00117 fail_unless(id == 2269, "id decode error, decoded %d, expected 2269", id);
00118 fail_unless(fabs(tow - t.tow) < 1e-3, "TOW decode error, decoded %f, expected %f", tow, t.tow);
00119 fail_unless(sync == 1, "id decode error, decoded %d, expected 1", id);
00120 fail_unless(n_sat == 22, "n_sat decode error, decoded %d, expected 22", n_sat);
00121 fail_unless(div_free == 1, "div_free decode error, decoded %d, expected 1", div_free);
00122 fail_unless(smooth == 6, "smooth decode error, decoded %d, expected 6", smooth);
00123 }
00124 END_TEST
00125
00126
00127 START_TEST(test_rtcm3_encode_decode)
00128 {
00129 navigation_measurement_t nm_orig[22];
00130 navigation_measurement_t nm[22];
00131
00132 seed_rng();
00133
00134 for (u8 i=0; i<22; i++) {
00135 nm[i].prn = i;
00136 nm[i].raw_pseudorange = frand(19e6, 21e6);
00137 nm[i].carrier_phase = frand(-5e5, 5e5);
00138 nm[i].lock_time = frand(0, 1000);
00139 nm[i].snr = frand(0, 20);
00140 }
00141
00142 memcpy(nm_orig, nm, sizeof(nm));
00143
00144 gps_time_t t = {
00145 .wn = 1234,
00146 .tow = frand(0, 604800)
00147 };
00148
00149 u8 buff[355];
00150
00151 rtcm3_encode_1002(buff, 1234, t, 22, nm, 0);
00152
00153 navigation_measurement_t nm_out[22];
00154 double tow_out;
00155 u8 sync, n_sat = 222;
00156 u16 id;
00157
00158 s8 ret = rtcm3_decode_1002(buff, &id, &tow_out, &n_sat, 0, &sync);
00159
00160 fail_unless(ret >= 0, "rtcm3_decode_1002 returned an error (%d)", ret);
00161 fail_unless(id == 1234, "decoded station id as %d, expected 1234", id);
00162 fail_unless(n_sat == 22, "decoded n_sat as %d, expected 22", n_sat);
00163 fail_unless(fabs(tow_out - t.tow) < 1e-3, "decoded TOW as %f, expected %f, error %f",
00164 tow_out, t.tow, tow_out - t.tow);
00165
00166 ret = rtcm3_decode_1002(buff, &id, &tow_out, &n_sat, nm_out, &sync);
00167
00168 for (u8 i=0; i<22; i++) {
00169 fail_unless(nm[i].prn == nm_out[i].prn, "[%d] PRNs not equal - "
00170 "decoded %d, expected %d", i, nm_out[i].prn, nm[i].prn);
00171
00172 double pr_err = nm[i].raw_pseudorange - nm_out[i].raw_pseudorange;
00173 fail_unless(fabs(pr_err) < 0.02, "[%d] pseudorange error > 0.04m - "
00174 "decoded %f, expected %f, error %f", i, nm_out[i].raw_pseudorange, nm[i].raw_pseudorange, pr_err);
00175
00176 double carr_err = nm[i].carrier_phase - nm_out[i].carrier_phase;
00177 fail_unless(fabs(carr_err) < 0.003, "carrier phase error (fractional part) > 0.003 cycles - "
00178 "[%d] decoded %f, expected %f, error %f", i, nm_out[i].carrier_phase, nm[i].carrier_phase, carr_err);
00179
00180 double snr_err = nm[i].snr - nm_out[i].snr;
00181
00182 double err_bound = nm[i].snr * (pow(10.0, 1.0 / 40.0) - 1);
00183 fail_unless(fabs(snr_err) < err_bound, "SNR error > 0.003 - "
00184 "[%d] decoded %f, expected %f, error %f, bound %f", i, nm_out[i].snr, nm[i].snr, snr_err, err_bound);
00185
00186 fail_unless((nm_out[i].lock_time == 0) && (nm[i].lock_time == 0),
00187 "lock time should be zero when adjusting int. amb. - [%d] decoded %f",
00188 i, nm_out[i].lock_time, nm[i].lock_time);
00189
00190 double cp_adj = nm[i].carrier_phase - nm_orig[i].carrier_phase;
00191 fail_unless(fmod(cp_adj, 1.0) == 0,
00192 "carrier phase adjusted by non integer amount %f -> %f (%f)",
00193 nm_orig[i].carrier_phase, nm[i].carrier_phase, cp_adj);
00194 }
00195
00196
00197
00198
00199 for (u8 i=0; i<22; i++)
00200 nm[i].lock_time = frand(0, 1000);
00201
00202 rtcm3_encode_1002(buff, 1234, t, 22, nm, 0);
00203 rtcm3_decode_1002(buff, &id, &tow_out, &n_sat, nm_out, &sync);
00204
00205 for (u8 i=0; i<22; i++) {
00206 double cp_adj = nm_out[i].carrier_phase - nm[i].carrier_phase;
00207 fail_unless(cp_adj < 0.003, "carrier phase re-adjusted %f -> %f (%f)",
00208 nm[i].carrier_phase, nm_out[i].carrier_phase, cp_adj);
00209
00210 fail_unless(nm_out[i].lock_time <= nm[i].lock_time,
00211 "lock time error, should always be less than input lock time - [%d] decoded %f, expected %f",
00212 i, nm_out[i].lock_time, nm[i].lock_time);
00213 }
00214 }
00215 END_TEST
00216
00217
00218 Suite* rtcm3_suite(void)
00219 {
00220 Suite *s = suite_create("RTCMv3");
00221
00222 TCase *tc_core = tcase_create("Core");
00223 tcase_add_test(tc_core, test_rtcm3_check_frame);
00224 tcase_add_test(tc_core, test_rtcm3_write_frame);
00225 tcase_add_test(tc_core, test_rtcm3_read_write_header);
00226 tcase_add_test(tc_core, test_rtcm3_encode_decode);
00227 suite_add_tcase(s, tc_core);
00228
00229 return s;
00230 }
00231