mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-15 23:10:11 -07:00
296 lines
8.4 KiB
C++
296 lines
8.4 KiB
C++
// River Information Systems ECE-TRANS-SC3-2006-10r-RIS.pdf
|
|
// http://www.unece.org/fileadmin/DAM/trans/doc/finaldocs/sc3/ECE-TRANS-SC3-176e.pdf
|
|
|
|
#include "ais.h"
|
|
|
|
namespace libais {
|
|
|
|
// Inland ship static and voyage related data
|
|
Ais8_200_10::Ais8_200_10(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad), length(0.0), beam(0.0), ship_type(0),
|
|
haz_cargo(0), draught(0.0), loaded(0), speed_qual(0), course_qual(0),
|
|
heading_qual(0), spare2(0) {
|
|
assert(dac == 200);
|
|
assert(fi == 10);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
if (num_bits != 168) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(56);
|
|
eu_id = bits.ToString(56, 48);
|
|
length = bits.ToUnsignedInt(104, 13) / 10.; // m
|
|
beam = bits.ToUnsignedInt(117, 10) / 10.; // m
|
|
ship_type = bits.ToUnsignedInt(127, 14);
|
|
haz_cargo = bits.ToUnsignedInt(141, 3);
|
|
draught = bits.ToUnsignedInt(144, 11) / 10.; // m
|
|
loaded = bits.ToUnsignedInt(155, 2);
|
|
speed_qual = bits[157];
|
|
course_qual = bits[158];
|
|
heading_qual = bits[159];
|
|
spare2 = bits.ToUnsignedInt(160, 8);
|
|
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
// ETA report
|
|
Ais8_200_21::Ais8_200_21(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad), eta_month(0), eta_day(0), eta_hour(0),
|
|
eta_minute(0), tugboats(0), air_draught(0.0) // TODO : add missing fields
|
|
{
|
|
assert(dac == 200);
|
|
assert(fi == 21);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
if (num_bits != 248) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(88);
|
|
// UN country code 12 bits
|
|
country = bits.ToString(88, 12);
|
|
|
|
// UN location code 18 bits
|
|
location = bits.ToString(100, 18);
|
|
|
|
// Fairway section number 30 bits
|
|
section = bits.ToString(118, 30);
|
|
|
|
// Terminal code 30 bits
|
|
terminal = bits.ToString(148, 30);
|
|
|
|
// Fairway hectometre 30 bits
|
|
hectometre = bits.ToString(178, 30);
|
|
|
|
// ETA at lock/bridge/terminal 20 bits
|
|
eta_month = bits.ToUnsignedInt(208, 4);
|
|
eta_day = bits.ToUnsignedInt(212, 5);
|
|
eta_hour = bits.ToUnsignedInt(217, 5);
|
|
eta_minute = bits.ToUnsignedInt(223, 6);
|
|
|
|
// Number of assisting tugboats 3 bits
|
|
tugboats = bits.ToUnsignedInt(229, 3);
|
|
|
|
// Maximum present static air draught 12 bits
|
|
air_draught = bits.ToUnsignedInt(231, 12) / 10.; // m
|
|
|
|
// Spare 5 bits
|
|
spare2 = bits.ToUnsignedInt(243, 5);
|
|
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
// RTA report
|
|
Ais8_200_22::Ais8_200_22(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad), rta_month(0), rta_day(0), rta_hour(0),
|
|
rta_minute(0) // TODO : add missing fields
|
|
{
|
|
assert(dac == 200);
|
|
assert(fi == 22);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
if (num_bits != 232) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(88);
|
|
// UN country code 12 bits
|
|
country = bits.ToString(88, 12);
|
|
|
|
// UN location code 18 bits
|
|
location = bits.ToString(100, 18);
|
|
|
|
// Fairway section number 30 bits
|
|
section = bits.ToString(118, 30);
|
|
|
|
// Terminal code 30 bits
|
|
terminal = bits.ToString(148, 30);
|
|
|
|
// Fairway hectometre 30 bits
|
|
hectometre = bits.ToString(178, 30);
|
|
|
|
// RTA at lock/bridge/terminal 20 bits
|
|
rta_month = bits.ToUnsignedInt(208, 4);
|
|
rta_day = bits.ToUnsignedInt(212, 5);
|
|
rta_hour = bits.ToUnsignedInt(217, 5);
|
|
rta_minute = bits.ToUnsignedInt(223, 6);
|
|
|
|
// Lock/bridge/terminal status 2 bits
|
|
lock_status = bits.ToUnsignedInt(229, 2);
|
|
|
|
// Spare 2 bits
|
|
spare2 = bits.ToUnsignedInt(231, 2);
|
|
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
// River Information Systems ECE-TRANS-SC3-2006-10r-RIS.pdf
|
|
Ais8_200_23::Ais8_200_23(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad), utc_year_start(0), utc_month_start(0),
|
|
utc_day_start(0), utc_year_end(0), utc_month_end(0), utc_day_end(0),
|
|
utc_hour_start(0), utc_min_start(0), utc_hour_end(0), utc_min_end(0),
|
|
type(0), min(0), max(0), classification(0), wind_dir(0), spare2(0) {
|
|
assert(dac == 200);
|
|
assert(fi == 23);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
if (num_bits != 256) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(56);
|
|
|
|
// TODO(schwehr): Figure out the correct bits & test against actual messages.
|
|
|
|
// The total for the bit column in table 2.11 of ECE/TRANS/SC.3/2006/10
|
|
// add up to 256. However, start date and end date fields are lists with
|
|
// totals of 17 bits each, but within the details, the spec refers to 18 bits
|
|
// for each. It is likely the year should be one less bit.
|
|
utc_year_start = bits.ToUnsignedInt(56, 8);
|
|
utc_month_start = bits.ToUnsignedInt(65, 4);
|
|
utc_day_start = bits.ToUnsignedInt(69, 5);
|
|
|
|
utc_year_end = bits.ToUnsignedInt(73, 8);
|
|
utc_month_end = bits.ToUnsignedInt(82, 4);
|
|
utc_day_end = bits.ToUnsignedInt(86, 5);
|
|
|
|
utc_hour_start = bits.ToUnsignedInt(90, 5);
|
|
utc_min_start = bits.ToUnsignedInt(95, 6);
|
|
utc_hour_end = bits.ToUnsignedInt(101, 5);
|
|
utc_min_end = bits.ToUnsignedInt(106, 6);
|
|
|
|
position1 = bits.ToAisPoint(112, 55);
|
|
position2 = bits.ToAisPoint(167, 55);
|
|
|
|
type = bits.ToUnsignedInt(222, 4);
|
|
// TODO(schwehr): Handle the sign bit for min and max.
|
|
min = bits.ToUnsignedInt(226, 9);
|
|
max = bits.ToUnsignedInt(235, 9);
|
|
classification = bits.ToUnsignedInt(244, 2);
|
|
wind_dir = bits.ToUnsignedInt(246, 4);
|
|
spare2 = bits.ToUnsignedInt(250, 6);
|
|
|
|
// TODO(schwehr): The above bit counts can't work.
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
|
|
// River Information Systems ECE-TRANS-SC3-2006-10r-RIS.pdf
|
|
// Water level
|
|
Ais8_200_24::Ais8_200_24(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad) {
|
|
assert(dac == 200);
|
|
assert(fi == 24);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
if (num_bits != 168) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(56);
|
|
country = bits.ToString(56, 12);
|
|
for (size_t i = 0; i < 4; i++) {
|
|
size_t start = 68 + 25*i;
|
|
gauge_ids[i] = bits.ToUnsignedInt(start, 11);
|
|
const int sign = bits[start + 11] ? 1 : -1; // 0 negative, 1 pos
|
|
// ERROR: the spec has a bit listing mistake
|
|
levels[i] = sign * bits.ToUnsignedInt(start + 12, 13);
|
|
}
|
|
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
// River Information Systems ECE-TRANS-SC3-2006-10r-RIS.pdf
|
|
Ais8_200_40::Ais8_200_40(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad), form(0), dir(0), stream_dir(0), status_raw(0),
|
|
spare2(0) {
|
|
assert(dac == 200);
|
|
assert(fi == 40);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
if (num_bits != 168) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(56);
|
|
position = bits.ToAisPoint(56, 55);
|
|
form = bits.ToUnsignedInt(111, 4);
|
|
dir = bits.ToUnsignedInt(115, 9); // degrees
|
|
stream_dir = bits.ToUnsignedInt(124, 3);
|
|
status_raw = bits.ToUnsignedInt(127, 30);
|
|
// TODO(schwehr): Convert the status_raw to the 9 signal lights.
|
|
// Appears to be a base 10 setup where each of 9 digits range from 0 to 7
|
|
// for the light level.
|
|
spare2 = bits.ToUnsignedInt(157, 11);
|
|
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
|
|
// River Information Systems ECE-TRANS-SC3-2006-10r-RIS.pdf
|
|
//
|
|
// TODO(schwehr): Search the logs for the various possible sizes and make
|
|
// tests based on those messages.
|
|
Ais8_200_55::Ais8_200_55(const char *nmea_payload, const size_t pad)
|
|
: Ais8(nmea_payload, pad), crew(0), passengers(0), yet_more_personnel(0) {
|
|
assert(dac == 200);
|
|
assert(fi == 55);
|
|
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
|
|
// The specification says that there are 51 spare bits, but it is possible
|
|
// that some transmitters may leave off the spare bits.
|
|
if (num_bits != 88 && num_bits != 136 && num_bits != 168) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
bits.SeekTo(56);
|
|
crew = bits.ToUnsignedInt(56, 8);
|
|
passengers = bits.ToUnsignedInt(64, 13);
|
|
yet_more_personnel = bits.ToUnsignedInt(77, 8);
|
|
|
|
if (num_bits == 88) {
|
|
spare2[0] = bits.ToUnsignedInt(85, 3);
|
|
} else if (num_bits == 136) {
|
|
spare2[0] = bits.ToUnsignedInt(85, 32);
|
|
spare2[1] = bits.ToUnsignedInt(117, 19);
|
|
} else {
|
|
spare2[0] = bits.ToUnsignedInt(85, 32);
|
|
spare2[1] = bits.ToUnsignedInt(117, 32);
|
|
spare2[2] = bits.ToUnsignedInt(149, 19);
|
|
}
|
|
|
|
assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
} // namespace libais
|