-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New ais encoded/decoder for message 18 and 24
- Loading branch information
1 parent
49610d8
commit c8b6af8
Showing
15 changed files
with
832 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from ais_tools.transcode import DecodeError | ||
from ais_tools.transcode import MessageTranscoder | ||
from ais_tools.transcode import UintTranscoder as Uint | ||
from ais_tools.transcode import bits_to_nmea | ||
from ais_tools.transcode import nmea_to_bits | ||
from ais_tools.transcode import byte_align | ||
from ais_tools import ais18 | ||
from ais_tools import ais24 | ||
from ais_tools import ais25 | ||
|
||
|
||
message_types = { | ||
18: [ais18.AIS18Transcoder()], | ||
24: [ais24.AIS24Transcoder()], | ||
25: [ais25.AIS25Transcoder()], | ||
} | ||
|
||
|
||
class AISMessageTypeTranscoder(MessageTranscoder): | ||
|
||
def get_fields(self, message=None): | ||
msg_type = message.get('id') | ||
if msg_type not in message_types: | ||
raise DecodeError('AIS: Unknown message type {}'.format(msg_type)) | ||
fields = message_types.get(msg_type, []) | ||
return fields | ||
|
||
|
||
ais_fields = [ | ||
Uint(name='id', nbits=6, default=0), | ||
AISMessageTypeTranscoder(), | ||
] | ||
|
||
|
||
class AISMessageTranscoder(MessageTranscoder): | ||
def __init__(self): | ||
super().__init__(ais_fields) | ||
|
||
def encode_nmea(self, message): | ||
return bits_to_nmea(byte_align(self.encode(message))) | ||
|
||
def decode_nmea(self, body, pad=0): | ||
return self.decode(nmea_to_bits(body, pad)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from ais_tools import transcode | ||
from ais_tools.transcode import DecodeError | ||
from ais_tools.transcode import BitsTranscoder | ||
from ais_tools.transcode import UintTranscoder as Uint | ||
from ais_tools.transcode import Uint10Transcoder as Uint10 | ||
from ais_tools.transcode import LatLonTranscoder as LatLon | ||
|
||
|
||
class AIS18Transcoder(transcode.MessageTranscoder): | ||
def __init__(self): | ||
super().__init__(ais18_fields) | ||
|
||
|
||
class AIS18CommState(transcode.MessageTranscoder): | ||
def get_fields(self, message=None): | ||
unit_flag = message.get('unit_flag', 0) | ||
commstate_flag = message.get('commstate_flag', 0) | ||
|
||
if unit_flag == 0: | ||
if commstate_flag == 0: | ||
return ais18_commstate_SOTDMA | ||
else: | ||
return ais18_commstate_ITDMA | ||
else: | ||
return ais18_commstate_CS | ||
|
||
|
||
class AIS18CommStateSOTDMA(transcode.MessageTranscoder): | ||
def get_fields(self, message=None): | ||
slot_timeout = message.get('slot_timeout', 0) | ||
if slot_timeout == 0: | ||
return ais18_commstate_SOTDMA_timeout_0 | ||
elif slot_timeout == 1: | ||
return ais18_commstate_SOTDMA_timeout_1 | ||
elif slot_timeout in (2, 4, 6): | ||
return ais18_commstate_SOTDMA_timeout_2_4_6 | ||
elif slot_timeout in (3, 5, 7): | ||
return ais18_commstate_SOTDMA_timeout_3_5_7 | ||
else: | ||
raise DecodeError('AIS18: unknown slot_timeout value {}'.format(slot_timeout)) | ||
|
||
|
||
ais18_fields = [ | ||
Uint(name='repeat_indicator', nbits=2), | ||
Uint(name='mmsi', nbits=30), | ||
Uint(name='spare', nbits=8), | ||
Uint10(name='sog', nbits=10, default=102.3), | ||
Uint(name='position_accuracy', nbits=1), | ||
LatLon(name='x', nbits=28, default=181), | ||
LatLon(name='y', nbits=27, default=91), | ||
Uint10(name='cog', nbits=12, default=360), | ||
Uint(name='true_heading', nbits=9, default=511), | ||
Uint(name='timestamp', nbits=6, default=60), | ||
Uint(name='spare2', nbits=2), | ||
Uint(name='unit_flag', nbits=1), | ||
Uint(name='display_flag', nbits=1), | ||
Uint(name='dsc_flag', nbits=1), | ||
Uint(name='band_flag', nbits=1), | ||
Uint(name='m22_flag', nbits=1), | ||
Uint(name='mode_flag', nbits=1), | ||
Uint(name='raim', nbits=1), | ||
Uint(name='commstate_flag', nbits=1), | ||
AIS18CommState() | ||
] | ||
|
||
ais18_commstate_CS = [ | ||
BitsTranscoder(name='commstate', nbits=19, default='1100000000000000110'), | ||
] | ||
|
||
ais18_commstate_ITDMA = [ | ||
Uint(name='sync_state', nbits=2), | ||
Uint(name='slot_increment', nbits=13), | ||
Uint(name='slots_to_allocate', nbits=3), | ||
Uint(name='keep_flag', nbits=1), | ||
] | ||
|
||
ais18_commstate_SOTDMA = [ | ||
Uint(name='sync_state', nbits=2), | ||
Uint(name='slot_timeout', nbits=3), | ||
AIS18CommStateSOTDMA() | ||
] | ||
|
||
ais18_commstate_SOTDMA_timeout_0 = [ | ||
Uint(name='slot_offset', nbits=14), | ||
] | ||
|
||
ais18_commstate_SOTDMA_timeout_1 = [ | ||
Uint(name='utc_hour', nbits=5), | ||
Uint(name='utc_min', nbits=7), | ||
Uint(name='utc_spare', nbits=2), | ||
] | ||
|
||
ais18_commstate_SOTDMA_timeout_2_4_6 = [ | ||
Uint(name='slot_number', nbits=14), | ||
] | ||
|
||
ais18_commstate_SOTDMA_timeout_3_5_7 = [ | ||
Uint(name='received_stations', nbits=14), | ||
] | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from ais_tools import transcode | ||
from ais_tools.transcode import MessageTranscoder as Message | ||
from ais_tools.transcode import DynamicTranscoder | ||
from ais_tools.transcode import DecodeError | ||
from ais_tools.transcode import UintTranscoder as Uint | ||
from ais_tools.transcode import ASCII6Transcoder as ASCII6 | ||
|
||
|
||
class AIS24Transcoder(Message): | ||
def __init__(self): | ||
super().__init__(ais24_fields) | ||
|
||
|
||
class AIS24PartAB(Message): | ||
def get_fields(self, message=None): | ||
part_num = message.get('part_num', 0) | ||
if part_num == 0: | ||
return ais24_part_A_fields | ||
elif part_num == 1: | ||
return ais24_part_B_fields | ||
else: | ||
raise DecodeError('AIS24: unknown part number {}'.format(part_num)) | ||
|
||
|
||
class VendorID(DynamicTranscoder): | ||
def __init__(self): | ||
self.vendorid_1371_2 = Message(ais24_vendorid_ITU_R_1371_2) | ||
self.vendorid_1371_4 = Message(ais24_vendorid_ITU_R_1371_4) | ||
|
||
def encoder(self, message): | ||
if 'vendor_id' in message: | ||
return self.vendorid_1371_2 | ||
else: | ||
return self.vendorid_1371_4 | ||
|
||
def decoders(self, message): | ||
return [self.vendorid_1371_2, self.vendorid_1371_4] | ||
|
||
|
||
class DimensionOrMothership(Message): | ||
def __init__(self): | ||
super().__init__() | ||
self.shipDimension = Message(ais24_part_B_dimension_fields) | ||
self.mothershipMMSI = Message(ais24_part_B_mothership_fields) | ||
|
||
def get_fields(self, message=None): | ||
mmsi = message.get('id') | ||
if mmsi // 10000000 == 98: | ||
return [self.mothershipMMSI] | ||
else: | ||
return [self.shipDimension] | ||
|
||
|
||
# COMMON FIELDS | ||
ais24_fields = [ | ||
Uint(name='repeat_indicator', nbits=2), | ||
Uint(name='mmsi', nbits=30), | ||
Uint(name='part_num', nbits=2), | ||
AIS24PartAB() | ||
] | ||
|
||
# PART A | ||
ais24_part_A_fields = [ | ||
ASCII6(name='name', nbits=120), | ||
] | ||
|
||
# PART B | ||
ais24_vendorid_ITU_R_1371_2 =[ | ||
ASCII6(name='vendor_id', nbits=42, default='@@@@@@@'), | ||
] | ||
|
||
ais24_vendorid_ITU_R_1371_4 =[ | ||
ASCII6(name='vendor_id_1371_4', nbits=18, default='@@@'), | ||
Uint(name='vendor_model', nbits=4), | ||
Uint(name='vendor_serial', nbits=20), | ||
] | ||
|
||
ais24_part_B_dimension_fields = [ | ||
Uint(name='dim_a', nbits=9), | ||
Uint(name='dim_b', nbits=9), | ||
Uint(name='dim_c', nbits=6), | ||
Uint(name='dim_d', nbits=6), | ||
] | ||
|
||
ais24_part_B_mothership_fields = [ | ||
Uint(name='mothership_mmsi', nbits=30), | ||
] | ||
|
||
ais24_part_B_fields = [ | ||
Uint(name='type_and_cargo', nbits=8), | ||
VendorID(), | ||
ASCII6(name='callsign', nbits=42, default='@@@@@@@'), | ||
DimensionOrMothership(), | ||
Uint(name='gps_type', nbits=4), | ||
Uint(name='spare', nbits=2), | ||
] | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from ais_tools import transcode | ||
from ais_tools.transcode import DecodeError | ||
from ais_tools.transcode import UintTranscoder as Uint | ||
from ais_tools.transcode import ASCII6Transcoder as ASCII6 | ||
from ais_tools.transcode import VariableLengthASCII6Transcoder as VarASCII6 | ||
|
||
# Using this coding http://www.e-navigation.nl/content/text-using-6-bit-ascii-1 | ||
|
||
|
||
class AIS25Transcoder(transcode.MessageTranscoder): | ||
def __init__(self): | ||
super().__init__(ais25_fields) | ||
|
||
|
||
class AIS25Destination(transcode.MessageTranscoder): | ||
def get_fields(self, message=None): | ||
addressed = message.get('addressed', 0) | ||
if addressed: | ||
return ais25_destination_fields | ||
else: | ||
return [] | ||
|
||
|
||
ais25_fields = [ | ||
Uint(name='repeat_indicator', nbits=2), | ||
Uint(name='mmsi', nbits=30), | ||
Uint(name='part_num', nbits=2), | ||
Uint(name='addressed', nbits=1), | ||
Uint(name='use_app_id', nbits=1), | ||
AIS25Destination(), | ||
Uint(name='dac', nbits=10, default=1), | ||
Uint(name='fi', nbits=6), | ||
Uint(name='text_seq', nbits=11), | ||
VarASCII6(name='text', default='') | ||
] | ||
|
||
ais25_destination_fields = [ | ||
Uint(name='dest_mmsi', nbits=30), | ||
Uint(name='spare', nbits=2), | ||
] | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.