Giter VIP home page Giter VIP logo

libais's Introduction

Introduction

image

image

image

image

Library for decoding maritime Automatic Identification System messages.

See Also

Automatic Identification System

Other open source AIS projects:

Building

Building with Python

$ python setup.py build
$ python setup.py install

Testing with Python

$ virtualenv ve
$ source ve/bin/activate
$ python setup.py test

Building with CMake

$ cmake .
$ make

Building with legacy Makefile

$ make -f Makefile-custom test

Usage

There are two interfaces to libais, one high-level iterator based one and a low-level fast C++ only one. The iterator based interface is accessed the following way:

import ais.stream
with open("file.nmea") as f:
    for msg in ais.stream.decode(f):
        print msg

To use the low-level C++ interface directly, you need to handle multi-line messages and padding yourself:

import ais
ais.decode('15PIIv7P00D5i9HNn2Q3G?wB0t0I', 0)
ais.decode('402u=TiuaA000r5UJ`H4`?7000S:', 0)
ais.decode('55NBjP01mtGIL@CW;SM<D60P5Ld000000000000P0`<3557l0<50@kk@K5h@00000000000', 2)

There is also support for converting parsed messages to the structure output by GPSD / gpsdecode. For full compatibility, you have to write the resulting message dictionaries to a file with json.dump() and add a newline after each message.

import ais.stream
import json
import ais.compatibility.gpsd

with open("infile.nmea") as inf:
    with open("outfile.gpsd") as outf:
        for msg in ais.stream.decode(f):
            gpsdmsg = ais.compatibility.gpsd.mangle(msg)
            json.dump(gpsdmsg, outf)
            outf.write("\n")

AIS Specification Documents

  • ITU-1371, ITU-1371-{1,2,3,4]
  • e-Navigation
  • IMO Circ 236
  • IMO Circ 289
  • EU RIS

Developing

The C++ code was switched to the Google style in November, 2012. Indenting should be by 2 spaces.

http://google-styleguide.googlecode.com/svn/trunk/cpplint/

$ git clone https://github.com/schwehr/libais
$ cd libais
$ virtualenv ve
$ source ve/bin/activate
$ pip install -e .[tests]
$ python setup.py test
$ py.test --cov=ais --cov-report term-missing

or

$ git clone https://github.com/schwehr/libais
$ cd libais
$ virtualenv ve
$ source ve/bin/activate
$ pip install -e .[test]
$ python setup.py develop
$ python setup.py test
$ py.test --cov=ais --cov-report term-missing

libais's People

Contributors

andyvan-trabus avatar cchayden avatar cpetrich avatar davoli avatar geowurster avatar ianfixes avatar jamtho avatar kthy avatar lancelotsix avatar lsix avatar lukec avatar rolker avatar rutsky avatar schwehr avatar skarlsson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libais's Issues

Missing field in SAR msg 9

Looks like message 9 changed in ITU 1371-4. The bit count may be off in the original. Both 1371-[34] have Spare/DTE/Spare/Assigned mode/raim. Ver 2 seems to not have annex 8. altitude sensor flag is at the wrong bits and assigned mode flag is missing.

8:200:23 sign bit not used

In Ais8_200_23, bit zero is not properly used to set the sign of min and max. It is not using two's complement.

Better handling of constructors

Definitely need a better strategy for handling constructors. Olaf recommended making the constructors private and having a static create function that can do the error handing. This will avoid return an invalid object and allow for easier tracking of what kind of error happened. Something along the lines of

Ais8 {
  private Ais8(data) {
  }

  public static create(data, Status* status) {
    Ais8 *obj = new Ais(data);
    if (obj->hasError()) {
      delte obj;
      obj = NULL;
      if (status != NULL) {
        *status = obj->getStatus();
      }
    } 
    return obj;
  }
}

not checking slot_timeout_valid

In the file ais_py.cpp, in the function ais1_2_3_to_pydict, you assign the msg.slot_timeout variable without first checking slot_timeout_valid, even though you check the validity options for the other fields.

Decoding unknown cargo in msg 5 raises exception in gpsd mangle

The mangler should give the code when not known.

<type 'exceptions.KeyError'>
Traceback (most recent call last):
File "ais/decode.py", line 80, in main
result = gpsd.mangle(decoded)
File "ais/compatibility/gpsd.py", line 17, in call
getattr(self, method2)(res, msg)
File "ais/compatibility/gpsd.py", line 125, in mangle__type_and_cargo
res['shiptype_text'] = self.ship_types[msg['type_and_cargo']]
KeyError: 204L

Example trigger:

\g:1-2-9997,s:rORBCOMM009,c:1421971332,T:2015-01-23 00.02.12_36!AIVDM,2,1,3,B,56:;3k14wqWP88@H001<PDpN0htpN0P4t0000<k<1pQ55000000000000000,0_1D
\g:2-2-9997,s:rORBCOMM009,c:1421971332,T:2015-01-23 00.02.12_35!AIVDM,2,2,3,B,00000000000,2_24

Ais8_1_21 and Ais8_1_31 field validity check missing

In Ais8_1_21, the horz_viz field is set without regard to the special status of the most significant bit. In IMO circular 239, if the most significant bit is set to 1, then that indicates that the horizontal visibility recording equipment reached its maximum range. Thus, if that bit is 1 an incorrect ( way too large) value is set to the horz_viz term. It would make more sense to add an extra boolean member to the class indicating whether the saturation bit was set.

The same issue as in Problem 1 exists in Ais8_1_31.

Create a class about ubits/sbits

Code like this is extremely error prone.

air_pres = (ubits(bs, 182, 9) + 800) / 100.0; // Pa

So make a class that wraps the bit handling with checking.

8:1:31 air pressure

Or perhaps the reported value should just be in Pascals

Reported:

In Ais8_1_31
The line

  air_pres = ubits(bs, 182, 9);

should be

  air_pres = ubits(bs, 182, 9)+799;

so that the result is in hectoPascals.

Add 8:367:22 area notice parser

The USCG has yet another version of the area notice. They have no official publication, but Greg Johnson sent an email with the spec. The examples in Greg's spreadsheet violate the his spec (wrong values used for empty range / dist - 0, 0 instead of 0, 720).

Looks like a sentence sequence number of 0 is in common usage, but should it be used only for multisentence messages. see: EIC 61162-100 Ed.1 (paywalled).

Need a proper build system

There is a semi okay setup.py (but needs work) and Makefile-custom, but this library needs a proper install system to build static and shared libraries w/ or w/out the python module. autoconf, scons, cmake and/or what?

8:1:11 salinity needs a div by 10

In Ais8_1_11
The line
salinity = ubits(bs, 335, 9);
should be
salinity = ubits(bs, 335, 9)/10.0;
as the documentation states that the salinity is given in increments of 0.1 permil and the variable has already been declared a float.

Ais8_1_26_Wx

The line

  air_pressure = ubits(bs, offset + 37, 9);

should be

  air_pressure = ubits(bs, offset + 37, 9)+799;

so that the value is in hectoPascals.

Remove print() methods

The print() methods are just a waste of space. Make sure that stream operations and/string are available for all classes instead.

7 and 13 message size check

In Ais7_13, the line

  if (((num_bits - 40) % 32) != 0 || num_bits > 168) {

should probably be

  if (num_bits<72||((num_bits) % 32) != 0 || num_bits > 168) {

Since the message size varied from 72 to 168 bits in increments of 32 bits and a message length of zero would satisfy ((num_bits - 40) % 32) == 0.

Add gtest tests

Work through testing with google test framework (gtest) to make sure 8:1:22 area notices are bomb proof.

forcast -> forecast

In the Ais8_1_26_Wind class, the forecast member types are all misspelt (but the mispelling is consistent, so there are no compile errors). That is, it should be spelt "forecast" and not "forcast".

propagating exceptions from submessages

Need to properly and consistently handle decoding errors of Ais 6 and 8 submessages. I think the ais[68]_to_pydict functions should check had_error() and return 0 and the lower messages should set the exception with PyErr_Format.

Cannot Build the library to use it with windows

Hi I want to use this library with Python in windows but when compiling the code using "python setup.py build"

But following errors appear.

image

I installed the Visual C++ for python and did this. But nothing changed. what could be the issue? how can I solve this?

Thank You

class to handle incremental bit decoding

Need a class similar to the DecodeBits class I wrote in python in ais-areanotice-py. Requesting decoding of each field with the number of bits. Internally, it tracks the number of bits and lets you check to make sure that it has parsed the expected number of bits.

https://github.com/schwehr/ais-areanotice-py/blob/uscg8_367_22_area_notice/m367_22.py#L41

Warning: A couple messages require out of sequence reading of bits, so this could be tricky. Likely allow stepping over N bits as a method on the instance. Then when a sub parser returns, I'll need to know how many bits it read and basically seek past that point.

Multi-fragment messages

(Please correct me if I'm wrong)

I don't see any handling of multi-fragment AIVDM messages.
The tests appear to manually extract the payload before sending it off to the decoder.
Did I overlook something, or is there some code somewhere who deals with buffering and collecting fragments?

Cheers,

-Marius

comp gpsd nav status strings do not match gpsd project's json output

@redhog The compatibility/gpsd.py module has very different strings thank in the gpsd project (gspd_json.c in 3.11). Do you want to stick with the strings there ore match up the strings with gpsd?

    static char *nav_legends[] = {
    "Under way using engine",
    "At anchor",
    "Not under command",
    "Restricted manoeuverability",
    "Constrained by her draught",
    "Moored",
    "Aground",
    "Engaged in fishing",
    "Under way sailing",
    "Reserved for HSC",
    "Reserved for WIG",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Not defined",
    };

Example AIS message

!AIVDM,1,1,,B,169A91O005KbT4gUoUl9d;5j0D0U,0*2D

decoded with libais:

 {u'repeat_indicator': 0L, u'special_manoeuvre': 0L, u'slot_timeout': 5L, u'rot_over_range': False, 
u'true_heading': 354L, u'timestamp': 57L, u'nav_status': 15L, u'cog': 248.0, u'mmsi': 412371205L, u'sync_state': 0L, u'received_stations': 37L, u'rot': 0.0, u'spare': 0L, u'raim': False, 
u'position_accuracy': 0L, u'x': -60.606895446777344, u'y': -45.66791915893555, u'id': 1L, u'sog': 0.5}

mangled:

 {u'raim': False, 'lat': -45.66791915893555, u'spare': 0L, 'accuracy': False, 'scaled': True, 
'status_text': 'default (also used by AIS-SART, MOB-AIS and EPIRB-AIS under test)', 
'heading': 354L, 'turn': 0.0, u'slot_timeout': 5L, 'device': 'stdin', 'status': '15', 'speed': 0.5, 
'repeat': 0L, 'course': 248.0, u'received_stations': 37L, 'second': 57L, u'mmsi': 412371205L, 
u'sync_state': 0L, 'type': 1L, 'class': 'AIS', 'maneuver': 0L, 'lon': -60.606895446777344}

gpsd 3.11 output:

{"class":"AIS","device":"stdin","type":1,"repeat":0,"mmsi":412371205,"scaled":true,
"status":"15","status_text":"Not defined", "turn":0,"speed":0.5,"accuracy":false, 
"lon":-60.6069,"lat":-45.6679,"course":248.0,"heading":354,"second":57,"maneuver":0,
"raim":false,"radio":81957}

msg 17

In the unfinished implementation for message 17, the z-count is directly stored to an integer. However, from the standard, it looks like the z-count is a count of 0.6 second increments. It would make sense to store it as a float and multiple it by 0.6 to turn it into seconds.

msg 27 conversion issue

I need to go through the code and write up the policy for how to handle things and then comment on the reason why when it deviates or fix it to comply.

Reported:

Ais27.cpp, the sog and cog parameters are not turned into real measurements in terms of knots and degrees as is the case with the other ais messages. Thus, unlike in the other files, the sog and coq parameters for message 27 are integers and not floats.

with AIS27, your use of sog and coq is fine after all, though you are not using the same type as in the other messages. I don't have the standard, but it looks like in that message, there is, for some inexplicable reason, an extra bit in each field and the values broadcast should just never use that bit. Thus, 63 and 511 are the maximum values. I have no idea why the message would be designed with an extra bit. It is not as if negative values are allowed.

utc_month in ais8_1_21_append_pydict

In the function ais8_1_21_append_pydict, the value utc_month is set regardless of the value of msg.type_wx_report. However, looking in the file ais8.cpp, the class Ais8_1_21 only puts a value in utc_month if type_wx_report=1. Thus, if type_wx_report=0, then the utc_month field passed to python is uninitialized garbage.

slot_timeout not being set in msg 18

Ais18, there is a slot_timeout member that is only set if 0 == commstate_flag. Since other messages come with a slot_timeout_valid member, that would probably be appropriate here as well.

8:1:21 swell_height_2

Report via email:
In the Ais8_1_21 class, the entry swell_height_2 should be declared as a float, not as an int, because it is set in Ais8.cpp by dividing an integer quantity by 2. Note that the swell_height entry is already declared as a float.

Compilation issue with Visual Studio - ais8.cpp

Reported to me:

Though previously, I was using *NIX, I compiled LibAIS under Windows using Microsoft's cl compiler, which comes with Visual Studio and with the free Windows SDK and I found that I had to make a small change to get rid of an error.

In the file ais8.cpp, Microsoft's compiler will given an error at the line
horz_viz = pow(ubits(bs, 221, 6), 2) * 13.073; // m
and at the line
alt_lowest_cloud_base = pow(ubits(bs, 272, 7), 2) * 0.16;
because its compiler expects the first argument to be some type of float and it will not automatically typecast things.

Thus, to get rid of the errors, use the lines
horz_viz = pow((double)ubits(bs, 221, 6), 2) * 13.073; // m
and
alt_lowest_cloud_base = pow((double)ubits(bs, 272, 7), 2) * 0.16;
instead.

Missing dacs

The following values are on the ITU's web site at
http://www.itu.int/online/mms/glad/cga_mids.sh?lng=E
but are missing from the enum
216 Armenia (Republic of)
229 Malta
241 Greece
305 Antigua and Barbuda
370 Panama (Republic of)
373 Panama (Republic of)
412 China (People's Republic of)
414 China (People's Republic of)
437 Uzbekistan (Republic of)
451 Kyrgyz Republic
453 Macao (Special Administrative Region of China) - China (People's Republic of)
472 Tajikistan (Republic of)
478 Bosnia and Herzegovina
565 Singapore (Republic of)
566 Singapore (Republic of)
577 Vanuatu (Republic of)
620 Comoros (Union of the)
638 South Sudan (Republic of)

Must pass in pad to all decoders

I was lazy not passing in the pad bits to all decoders, but with msg 26, I have no choice but to pass pad bits to all msg decoders. This requires a python interface change.

msg 8:200:24 spelling error

A member variable of the Ais8_200_24 class is named guage_ids. Presumably, that should be gauge_ids to make sense.

msg 5 decoding fails with AIS_ERR_BAD_BIT_COUNT

virtualenv ve
source ve/bin/activate
pip install libais

ipython
import ais

ais.decode('55M4lP01Wnrhd4Ht000<PDlT<4j10TtpDE80001AE8`>>4t>0J44SmRA1CPi@0000000000')

error Traceback (most recent call last)
in ()
----> 1 ais.decode('55M4lP01Wnrhd4Ht000<PDlT<4j10TtpDE80001AE8`>>4t>0J44SmRA1CPi@0000000000')

error: Ais5: AIS_ERR_BAD_BIT_COUNT

But msg 1 still works

ais.decode('16U<7J001K9n3=;ah6ObmpPd25kH')
Out[18]:
{u'cog': 277.5,
u'id': 1L,
u'mmsi': 441649000L,
u'nav_status': 0L,
u'position_accuracy': 0L,
u'raim': True,
u'repeat_indicator': 0L,
u'rot': 0.0,
u'rot_over_range': False,

../ais/ais_msg_5.py -d '!AIVDM,1,1,1,A,55M4lP01Wnrhd4Ht000<PDlT<4j10TtpDE80001AE8`>>4t>0J44SmRA1CPi@0000000000,2*4B'
shipdata:
MessageID: 5
RepeatIndicator: 0
UserID: 366032000
AISversion: 0
IMOnumber: 6806444
callsign: KAFO@@@
name: CHEMICAL PIONEER@@@@
shipandcargo: 81
dimA: 169
dimB: 40
dimC: 14
dimD: 14
fixtype: 1
ETAmonth: 3
ETAday: 24
ETAhour: 14
ETAminute: 0
draught: 10.4
destination: PROVIDENCE@@@@@@@@@@
dte: 0
Spare: 0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.