Example #1
0
// IMO Circ 289 - Tidal Window
// See also Circ 236
Ais6_1_14::Ais6_1_14(const char *nmea_payload, const size_t pad)
    : Ais6(nmea_payload, pad), utc_month(0), utc_day(0) {
  // TODO(schwehr): untested - no sample of the correct length yet
  assert(dac == 1);
  assert(fi == 14);

  if (num_bits != 376) {
    status = AIS_ERR_BAD_BIT_COUNT;
    return;
  }

  AisBitset bs;
  const AIS_STATUS r = bs.ParseNmeaPayload(nmea_payload, pad);
  if (r != AIS_OK) {
    status = r;
    return;
  }

  bs.SeekTo(88);
  utc_month = bs.ToUnsignedInt(88, 4);
  utc_day = bs.ToUnsignedInt(92, 5);

  for (size_t window_num = 0; window_num < 3; window_num++) {
    Ais6_1_14_Window w;
    const size_t start = 97 + window_num * 93;
    // Reversed order for lng/lat.
    float y = bs.ToInt(start, 27) / 600000.;
    float x = bs.ToInt(start + 27, 28) / 600000.;
    w.position = AisPoint(x, y);
    w.utc_hour_from = bs.ToUnsignedInt(start + 55, 5);
    w.utc_min_from = bs.ToUnsignedInt(start + 60, 6);
    w.utc_hour_to = bs.ToUnsignedInt(start + 66, 5);
    w.utc_min_to = bs.ToUnsignedInt(start + 71, 6);
    w.cur_dir = bs.ToUnsignedInt(start + 77, 9);
    w.cur_speed  = bs.ToUnsignedInt(start + 86, 7) / 10.;

    windows.push_back(w);
  }

  assert(bs.GetRemaining() == 0);
  status = AIS_OK;
}
Example #2
0
// IMO Circ 289 - VTS Generated/Synthetic Targets
// See also Circ 236
Ais8_1_17::Ais8_1_17(const char *nmea_payload, const size_t pad)
    : Ais8(nmea_payload, pad) {
  assert(dac == 1);
  assert(fi == 17);

  if (!CheckStatus()) {
    return;
  }

  const size_t num_targets = (num_bits - 56) / 120;
  const size_t extra_bits = (num_bits - 56) % 120;

  if (extra_bits || num_targets > 4) {
    status = AIS_ERR_BAD_BIT_COUNT;
    return;
  }

  bits.SeekTo(56);
  for (size_t target_num = 0; target_num < num_targets; target_num++) {
    Ais8_1_17_Target target;
    const size_t start = 56 + (120 * target_num);
    target.type = bits.ToUnsignedInt(start, 2);
    target.id = bits.ToString(start + 2, 42);
    target.spare = bits.ToUnsignedInt(start + 44, 4);
    // booo - lat, lon inverse order
    double y = bits.ToInt(start + 48, 24) / 60000.0;
    double x = bits.ToInt(start + 72, 25) / 60000.0;
    target.position = AisPoint(x, y);

    target.cog = bits.ToUnsignedInt(start + 97, 9);
    target.timestamp = bits.ToUnsignedInt(start + 106, 6);
    target.sog = bits.ToUnsignedInt(start + 112, 8);
  }

  assert(bits.GetRemaining() == 0);
  status = AIS_OK;
}
Example #3
0
Ais8_1_11::Ais8_1_11(const char *nmea_payload, const size_t pad)
    : Ais8(nmea_payload, pad), day(0), hour(0), minute(0), wind_ave(0),
      wind_gust(0), wind_dir(0), wind_gust_dir(0), air_temp(0.0), rel_humid(0),
      dew_point(0.0), air_pres(0.0), air_pres_trend(0), horz_vis(0.0),
      water_level(0.0), water_level_trend(0), surf_cur_speed(0.0),
      surf_cur_dir(0), cur_speed_2(0.0), cur_dir_2(0), cur_depth_2(0),
      cur_speed_3(0.0), cur_dir_3(0), cur_depth_3(0), wave_height(0.0),
      wave_period(0), wave_dir(0), swell_height(0.0), swell_period(0),
      swell_dir(0), sea_state(0), water_temp(0.0), precip_type(0),
      salinity(0.0), ice(0), spare2(0), extended_water_level(0) {
  assert(dac == 1);
  assert(fi == 11);

  if (!CheckStatus()) {
    return;
  }
  if (num_bits != 352) {
    status = AIS_ERR_BAD_BIT_COUNT;
    return;
  }

  // 352 + 2 spares to be 6 bit aligned

  bits.SeekTo(56);
  // Reverse order lat/lng!
  // TODO(schwehr): Reverse order, or just reverse bit count? Compare 6.1.14!
  double y = bits.ToInt(56, 24) / 60000.0;
  double x = bits.ToInt(80, 25) / 60000.0;
  position = AisPoint(x, y);

  day = bits.ToUnsignedInt(105, 5);
  hour = bits.ToUnsignedInt(110, 5);
  minute = bits.ToUnsignedInt(115, 6);
  wind_ave = bits.ToUnsignedInt(121, 7);
  wind_gust = bits.ToUnsignedInt(128, 7);
  wind_dir = bits.ToUnsignedInt(135, 9);
  wind_gust_dir = bits.ToUnsignedInt(144, 9);
  air_temp = bits.ToUnsignedInt(153, 11) / 10. - 60;
  rel_humid = bits.ToUnsignedInt(164, 7);
  dew_point = bits.ToUnsignedInt(171, 10) / 10. - 20;  // TODO(schwehr): verify
  air_pres = bits.ToUnsignedInt(181, 9) + 800;
  air_pres_trend = bits.ToUnsignedInt(190, 2);
  horz_vis = bits.ToUnsignedInt(192, 8) / 10.;
  // TODO(schwehr): verify for -10.0 to 30.0
  water_level = bits.ToUnsignedInt(200, 9) / 10. - 10;
  water_level_trend = bits.ToUnsignedInt(209, 2);
  surf_cur_speed = bits.ToUnsignedInt(211, 8) / 10.;
  surf_cur_dir = bits.ToUnsignedInt(219, 9);
  cur_speed_2 = bits.ToUnsignedInt(228, 8) / 10.;
  cur_dir_2 = bits.ToUnsignedInt(236, 9);
  cur_depth_2 = bits.ToUnsignedInt(245, 5);
  cur_speed_3 = bits.ToUnsignedInt(250, 8) / 10.;
  cur_dir_3 = bits.ToUnsignedInt(258, 9);
  cur_depth_3 = bits.ToUnsignedInt(267, 5);

  wave_height = bits.ToUnsignedInt(272, 8) / 10.;
  wave_period = bits.ToUnsignedInt(280, 6);
  wave_dir = bits.ToUnsignedInt(286, 9);
  swell_height = bits.ToUnsignedInt(295, 8) / 10.;
  swell_period = bits.ToUnsignedInt(303, 6);
  swell_dir = bits.ToUnsignedInt(309, 9);

  sea_state = bits.ToUnsignedInt(318, 4);
  // TODO(schwehr): verify for -10.0 to +50.0
  water_temp = bits.ToUnsignedInt(322, 10) / 10. - 10;
  precip_type = bits.ToUnsignedInt(332, 3);
  salinity = bits.ToUnsignedInt(335, 9) / 10.0;  // Part per mil (1/1000).
  ice = bits.ToUnsignedInt(344, 2);
  // There is no way to know which meaning to attach to the following 6 bits
  // TODO(schwehr): how to treat this spare vrs water level?
  spare2 = bits.ToUnsignedInt(346, 6);
  bits.SeekRelative(-6);
  extended_water_level = bits.ToUnsignedInt(346, 6);

  assert(bits.GetRemaining() == 0);
  status = AIS_OK;
}
Example #4
0
// IMO Circ 289 - Weather observation report from ship
// See also Circ 236
Ais8_1_21::Ais8_1_21(const char *nmea_payload, const size_t pad)
    : Ais8(nmea_payload, pad), type_wx_report(0), location(), utc_day(0),
      utc_hour(), utc_min(), horz_viz(0.0), humidity(0), wind_speed(0),
      wind_dir(0), pressure(0.0), pressure_tendency(0), air_temp(0.0),
      water_temp(0.0), wave_period(0), wave_height(0.0), wave_dir(0),
      swell_height(0.0), swell_dir(0), swell_period(0), spare2(0),
      utc_month(0), cog(0), sog(0.0), heading(0), rel_pressure(0.0),
      wind_speed_ms(0.0), wind_dir_rel(0), wind_speed_rel(0.0),
      wind_gust_speed(0.0), wind_gust_dir(0), air_temp_raw(0),
      water_temp_raw(0), wx(), cloud_total(0), cloud_low(0),
      cloud_low_type(0), cloud_middle_type(0), cloud_high_type(0),
      alt_lowest_cloud_base(0.0), swell_dir_2(0), swell_period_2(0),
      swell_height_2(0.0), ice_thickness(0.0), ice_accretion(0),
      ice_accretion_cause(0), sea_ice_concentration(0), amt_type_ice(0),
      ice_situation(0), ice_devel(0), bearing_ice_edge(0) {
  assert(dac == 1);
  assert(fi == 21);

  if (!CheckStatus()) {
    return;
  }
  if (num_bits != 360) {
    status = AIS_ERR_BAD_BIT_COUNT;
    return;
  }

  bits.SeekTo(56);
  type_wx_report = bits[56];
  if (!type_wx_report) {
    // WX obs from ship
    location = bits.ToString(57, 120);
    position = bits.ToAisPoint(177, 49);
    utc_day = bits.ToUnsignedInt(226, 5);
    utc_hour = bits.ToUnsignedInt(231, 5);
    utc_min = bits.ToUnsignedInt(236, 6);
    wx[0] = bits.ToUnsignedInt(242, 4);  // TODO(schwehr): set wx[1] and wx[2]?
    horz_viz = bits.ToUnsignedInt(246, 8) / 10.;  // nautical miles
    humidity = bits.ToUnsignedInt(254, 7);  // %
    wind_speed = bits.ToUnsignedInt(261, 7);  // ave knots
    wind_dir = bits.ToUnsignedInt(268, 9);
    pressure = bits.ToUnsignedInt(277, 9);  // hPa
    pressure_tendency = bits.ToUnsignedInt(286, 4);
    // TODO(schwehr): is air_temp correct?
    air_temp = bits.ToInt(290, 11) / 10.;  // C
    water_temp = bits.ToUnsignedInt(301, 10) / 10. - 10;  // C
    wave_period = bits.ToUnsignedInt(311, 6);  // s
    wave_height = bits.ToUnsignedInt(317, 8) / 10.;
    wave_dir = bits.ToUnsignedInt(325, 9);
    swell_height = bits.ToUnsignedInt(334, 8) / 10.;  // m
    swell_dir = bits.ToUnsignedInt(342, 9);
    swell_period = bits.ToUnsignedInt(351, 6);  // s
    spare2 = bits.ToUnsignedInt(357, 3);
  } else {
    // Type 1: WMO OBS from ship.
    double x = (bits.ToUnsignedInt(57, 16) / 100.0) - 180;
    double y = (bits.ToUnsignedInt(73, 15) / 100.0) - 180;
    position = AisPoint(x, y);

    utc_month = bits.ToUnsignedInt(88, 4);
    utc_day = bits.ToUnsignedInt(92, 6);
    utc_hour = bits.ToUnsignedInt(98, 5);
    utc_min = bits.ToUnsignedInt(102, 3) * 10;
    cog = bits.ToUnsignedInt(106, 7) * 5;
    sog = bits.ToUnsignedInt(113, 5) * 0.5;
    heading = bits.ToUnsignedInt(118, 7) *5;  // Assume this is true degrees????
    pressure = bits.ToUnsignedInt(125, 11) / 10. + 900;
    rel_pressure = bits.ToUnsignedInt(136, 10) / 10. -50;
    pressure_tendency = bits.ToUnsignedInt(146, 4);
    wind_dir = bits.ToUnsignedInt(150, 7) * 5;
    wind_speed_ms = bits.ToUnsignedInt(157, 8) * 0.5;  // m/s
    wind_dir_rel = bits.ToUnsignedInt(165, 7) * 5;
    wind_speed_rel = bits.ToUnsignedInt(172, 8) * 0.5;  // m/s
    wind_gust_speed = bits.ToUnsignedInt(180, 8) * 0.5;  // m/s
    wind_gust_dir = bits.ToUnsignedInt(188, 7) * 5;
    // 0C = 273.15 Kelvin
    // TODO(schwehr): change this to celsius
    air_temp_raw = bits.ToUnsignedInt(195, 10);
    humidity = bits.ToUnsignedInt(205, 7);
    water_temp_raw = bits.ToUnsignedInt(212, 9);  // TODO(schwehr): Change to C.

    auto pow2 = [](unsigned int val) { return val * val; };
    horz_viz = pow2(bits.ToUnsignedInt(221, 6)) * 13.073;  // m
    wx[0] = bits.ToUnsignedInt(227, 9);  // current
    wx[1] = bits.ToUnsignedInt(236, 5);  // past 1
    wx[2] = bits.ToUnsignedInt(241, 5);  // past 2
    cloud_total = bits.ToUnsignedInt(246, 4) * 10;
    cloud_low = bits.ToUnsignedInt(250, 4);
    cloud_low_type = bits.ToUnsignedInt(254, 6);
    cloud_middle_type = bits.ToUnsignedInt(260, 6);
    cloud_high_type = bits.ToUnsignedInt(266, 6);
    alt_lowest_cloud_base = pow2(bits.ToUnsignedInt(272, 7)) * 0.16;
    wave_period = bits.ToUnsignedInt(279, 5);  // s
    wave_height = bits.ToUnsignedInt(284, 6) * 0.5;  // m
    swell_dir = bits.ToUnsignedInt(290, 6) * 10;
    swell_period = bits.ToUnsignedInt(296, 5);  // s
    swell_height = bits.ToUnsignedInt(301, 6) * 0.5;  // m
    swell_dir_2 = bits.ToUnsignedInt(307, 6) * 10;
    swell_period_2 = bits.ToUnsignedInt(313, 5);  // s
    swell_height_2 = bits.ToUnsignedInt(318, 6) * 0.5;  // m
    ice_thickness = bits.ToUnsignedInt(324, 7) / 100.;  // m.  Network is cm,
    ice_accretion = bits.ToUnsignedInt(331, 3);
    ice_accretion_cause = bits.ToUnsignedInt(334, 3);
    sea_ice_concentration = bits.ToUnsignedInt(337, 5);
    amt_type_ice = bits.ToUnsignedInt(342, 4);
    ice_situation = bits.ToUnsignedInt(346, 5);
    ice_devel = bits.ToUnsignedInt(351, 5);
    bearing_ice_edge = bits.ToUnsignedInt(356, 4) * 45;
  }

  assert(bits.GetRemaining() == 0);
  status = AIS_OK;
}