Skip to content

Commit

Permalink
Merge pull request #18 from afischerdev/master
Browse files Browse the repository at this point in the history
Add ais msg 9,14,19
  • Loading branch information
fulup-bzh committed Feb 23, 2017
2 parents 78689b6 + 3757fbd commit 18ac413
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 36 deletions.
132 changes: 110 additions & 22 deletions encoder/lib/GG-AisDecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ function AisDecode (input, session) {
case 3: // class A position report
this.class = 'A';
this.navstatus = this.GetInt( 38, 4);

var lon = this.GetInt(61, 28);
if (lon & 0x08000000 ) lon |= 0xf0000000;
lon = parseFloat (lon / 600000);
Expand All @@ -276,12 +277,13 @@ function AisDecode (input, session) {
this.valid = true;
} else this.valid = false;

this.rot = this.GetInt( 42, 8, true ) // Rate of turn
this.sog = parseFloat (0.1 * this.GetInt( 50, 10 )); // speed over ground
this.cog = parseFloat (0.1 * this.GetInt( 116, 12)); // course over ground
this.hdg = parseFloat (this.GetInt( 128, 9)); // magnetic heading
this.rot = this.GetInt( 42, 8, true ) // Rate of turn
this.sog = this.GetInt( 50, 10) / 10; //speed over ground
this.cog = this.GetInt( 116, 12) / 10; //course over ground
this.hdg = parseFloat (this.GetInt( 128, 9)); //magnetic heading
this.utc = this.GetInt( 137, 6 );
this.smi = this.GetInt( 143, 2 ); // special maneuvre indicator
this.smi = this.GetInt( 143, 2 );


break;
case 18: // class B position report
Expand All @@ -301,11 +303,45 @@ function AisDecode (input, session) {
this.valid = true;
} else this.valid = false;

this.sog = parseFloat (0.1 * this.GetInt( 46, 10 )); //speed over ground
this.cog = parseFloat (0.1 * this.GetInt( 112, 12)); //course over ground
this.hdg = parseFloat (this.GetInt( 124, 9)); //magnetic heading
this.sog = this.GetInt( 46, 10 ) / 10; //speed over ground
this.cog = this.GetInt( 112, 12) / 10; //course over ground
this.hdg = parseFloat (this.GetInt( 124, 9)); //magnetic heading
this.utc = this.GetInt( 134, 6 );

break;
case 19: // Extended class B position report
this.class = 'B';
this.status = -1; // Class B targets have no status. Enforce this...

var lon = this.GetInt(57, 28 );
if (lon & 0x08000000 ) lon |= 0xf0000000;
lon = parseFloat (lon / 600000);

var lat = this.GetInt(85, 27 );
if( lat & 0x04000000 ) lat |= 0xf8000000;
lat = parseFloat (lat / 600000);

if( ( lon <= 180. ) && ( lat <= 90. ) ) {
this.lon = lon;
this.lat = lat;
this.valid = true;
} else this.valid = false;

this.sog = this.GetInt( 46, 10 ) / 10; //speed over ground
this.cog = this.GetInt( 112, 12) / 10; //course over ground
this.hdg = parseFloat (this.GetInt( 124, 9)); //magnetic heading
this.utc = this.GetInt( 133, 6 );

this.shipname = this.GetStr(143,120).trim();
this.cargo = this.GetInt(263,8);

this.dimA = this.GetInt(271, 9 );
this.dimB = this.GetInt(280, 9 );
this.dimC = this.GetInt(289, 6 );
this.dimD = this.GetInt(295, 6 );
this.length = this.dimA + this.dimB;
this.width = this.dimC + this.dimD;

break;
case 5:
this.class = 'A';
Expand All @@ -317,7 +353,7 @@ function AisDecode (input, session) {
if( AIS_version_indicator < 2 ) {
this.imo = this.GetInt(40,30);
this.callsign = this.GetStr(70,42);
this.shipname = this.GetStr(112,120);
this.shipname = this.GetStr(112,120).trim();
this.cargo = this.GetInt(232,8);
this.dimA = this.GetInt(240,9);
this.dimB = this.GetInt(249,9);
Expand All @@ -327,8 +363,8 @@ function AisDecode (input, session) {
this.etaDay = this.GetInt(278,5);
this.etaHr = this.GetInt(283,5);
this.etaMin = this.GetInt(288,6);
this.draught = parseFloat (this.GetInt(294, 8 ) / 10.0);
this.destination = this.GetStr(302, 120);
this.draught = this.GetInt(294, 8 ) / 10.0;
this.destination = this.GetStr(302, 120).trim();
this.length = this.dimA + this.dimB;
this.width = this.dimC + this.dimD;
this.valid = true;
Expand All @@ -339,18 +375,24 @@ function AisDecode (input, session) {
this.class='B';
this.part = this.GetInt(38, 2 );
if (0 === this.part ) {
this.shipname = this.GetStr(40, 120);
this.shipname = this.GetStr(40, 120).trim();
this.valid = true;
} else if ( this.part === 1) {
this.cargo = this.GetInt(40, 8 );
this.callsign = this.GetStr(90, 42);

this.dimA = this.GetInt(132, 9 );
this.dimB = this.GetInt(141, 9 );
this.dimC = this.GetInt(150, 6 );
this.dimD = this.GetInt(156, 6 );
this.length = this.dimA + this.dimB;
this.width = this.dimC + this.dimD;
this.callsign = this.GetStr(90, 42).trim();

// 98 = auxiliary craft
if (parseInt(immsi/10000000) === 98) {
var mothership = this.GetInt (132, 30);
this.mothership = ("000000000" + mothership).slice(-9);
} else {
this.dimA = this.GetInt(132, 9 );
this.dimB = this.GetInt(141, 9 );
this.dimC = this.GetInt(150, 6 );
this.dimD = this.GetInt(156, 6 );
this.length = this.dimA + this.dimB;
this.width = this.dimC + this.dimD;
}
this.valid = true;
}
break;
Expand All @@ -370,12 +412,35 @@ function AisDecode (input, session) {
this.lat = lat;
this.valid = true;
} else this.valid = false;
break;
case 9: // sar aircraft
this.class = '-';

this.alt = this.GetInt(38, 12);

var lon = this.GetInt(61, 28);
if (lon & 0x08000000 ) lon |= 0xf0000000;
lon = parseFloat (lon / 600000);

var lat = this.GetInt(89, 27);
if( lat & 0x04000000 ) lat |= 0xf8000000;
lat = parseFloat (lat / 600000);

if( ( lon <= 180. ) && ( lat <= 90. ) ) {
this.lon = lon;
this.lat = lat;
this.valid = true;
} else this.valid = false;

this.sog = parseFloat (this.GetInt( 50, 10 )); //speed over ground
this.cog = this.GetInt( 116, 12) / 10; //course over ground

break;
case 21: // aid to navigation
this.class = '-';

this.aidtype = this.GetInt(38, 5);
this.shipname = this.GetStr(43, 120);
this.shipname = this.GetStr(43, 120).trim();

var lon = this.GetInt(164, 28);
if (lon & 0x08000000 ) lon |= 0xf0000000;
Expand All @@ -390,6 +455,28 @@ function AisDecode (input, session) {
this.lat = lat;
this.valid = true;
} else this.valid = false;

this.dimA = this.GetInt(219, 9 );
this.dimB = this.GetInt(228, 9 );
this.dimC = this.GetInt(237, 6 );
this.dimD = this.GetInt(243, 6 );
this.length = this.dimA + this.dimB;
this.width = this.dimC + this.dimD;

this.utc = this.GetInt(253, 6);
this.offpos = this.GetInt(259, 1);

var len = parseInt(( ( this.bitarray.length - 272 /6 ) / 6 ) * 6)*6;
this.txt = this.GetStr(272 , len).trim();

break;
case 14: // text msg
this.class = '-';
if (this.bitarray.length > 40/6) {
var len = parseInt(( ( this.bitarray.length - 40/6 ) / 6 ) * 6)*6;
this.txt = this.GetStr(40, len).trim();
this.valid = true;
}
break;
default:
}
Expand All @@ -407,6 +494,7 @@ AisDecode.prototype.GetInt= function (start, len, signed) {
cx = this.bitarray[cp];
cs = 5 - ((start + i) % 6);
c0 = (cx >> cs) & 1;

if (i === 0 && signed && c0) { // if signed value and first bit is 1, pad with 1's
acc = ~acc;
}
Expand All @@ -429,7 +517,7 @@ AisDecode.prototype.GetStr= function(start, len) {
}

//char temp_str[85];
var buffer = new Buffer(20);
var buffer = new Buffer(len/6);
var cp, cx, cs,c0;
var acc = 0;
var k = 0;
Expand Down
2 changes: 1 addition & 1 deletion encoder/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name" : "ggencoder",
"description" : "GEOGATE-geojson handles AIS/NMEA encoding/decoding for GEOgate GPS/AIS/GTS framework",
"version" : "0.1.12",
"version" : "0.1.13",
"author" : {
"name" : "Fulup Ar Foll",
"email" : "fulup@breizhme.net",
Expand Down
96 changes: 83 additions & 13 deletions encoder/test/AisEncodeDecodeTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function AisEncodeDecodeTest (args) {
aistype : 18,
nmea : '!AIVDM,1,1,,A,B69>7mh0?B<:>05B0`0e8TN000000,0*72',
cog : 72.2,
sog : 6.1000000000000005,
sog : 6.1,
dsc : false,
repeat : false,
accuracy : true,
Expand All @@ -70,20 +70,33 @@ function AisEncodeDecodeTest (args) {
second : 50,
mmsi : "412321751"
}
,msg19: { // Extended class B Position report
aistype : 19,
nmea : ['!AIVDM,2,1,9,B,C43NbT0008VGWDVHNs0000N10PHb`NL00000,0*6D',
'!AIVDM,2,2,9,B,00000000N0`90RPP,0*59'],
mmsi : "272083600",
cog : 0,
sog : 0,
lon : 33.527321666666666,
lat : 44.61725333333333,
second : 60,
shipname : "PLUTON"
}
,msg5: { // class A static info
aistype : 5,
nmea : "!AIVDM,1,1,,A,55?MbV42;H;s<HtKR20EHE:0@T4@Dn2222222216L961O0000i000000000000000000000,0*2D",
// ,"!AIVDM,2,2,1,A,88888888880,2*25"], [extentions for destination not implemented]
//"!AIVDM,2,2,1,A,88888888880,2*25"], // [extentions for destination not implemented]
mmsi : "351759000",
imo : 9134270,
callsign : "3FOF8 ",
shipname : "EVER DIADEM ",
shipname : "EVER DIADEM",
destination: "",
cargo : 70,
dimA : 225,
dimB : 70,
dimC : 1,
dimD : 31,
fixaistype : 1,
fixaistype : 1,
etamn : 0,
etaho : 0,
etaday : 0,
Expand Down Expand Up @@ -125,7 +138,55 @@ function AisEncodeDecodeTest (args) {
shipname : "SG3",
aidtype : 1,
lon : 144.88636666666667,
lat : -38.03993166666667
lat : -38.03993166666667,
txt : ""
}
,msg21a: { // aid of navigation with extra text
aistype : 21,
nmea : "!AIVDM,1,1,,B,EvjO`>C2qHtq@8:W:0h9PW@1Pb0Paq`g;STu`10888N00313p12H31@hi@,4*0E,22.02.2017 15:57:02",
mmsi : "992471097",
shipname : "E2192 PUNTA SAN CATA",
aidtype : 6,
lon : 18.306638333333332,
lat : 40.390795,
txt : "LDO DI LECCE"
}
,msg9: { // sar aircraft
aistype : 9,
nmea : "!AIVDM,1,1,,B,900048wwTiJamA6Eu>B7Pd@20<6M,0*66",
mmsi : "000001059",
lon : -74.747675,
lat : 38.37196,
alt : 4094,
sog : 305,
cog : 192.2
}
,msg1: { // position with rot
aistype : 1,
nmea : "!AIVDM,1,1,,A,13mM6l0uAGG8oR<JKRg3D2f20<0?,0*45",
mmsi : "257378000",
lon : -123.89193666666667,
lat : 46.19039333333333,
sog : 8.7,
cog : 84.8,
navstatus : 0,
rot : -11
}
,msg1_1: { // position for mob
aistype : 1,
nmea : "!AIVDM,1,1,,B,1>O5`4wP01:F?39b6mD>4?w81P00,0*0D",
mmsi : "972122131",
lon : 144.66747333333333,
lat : -38.2612,
sog : 0.1,
cog : 360,
navstatus : 15
}
,msg14: { // text msg
aistype : 14,
nmea : "!AIVDM,1,1,,A,>>O5`4tlt:1@E=@,2*15",
mmsi : "972122131",
txt : "MOB TEST"
}
,msg1: {
aistype : 1,
Expand Down Expand Up @@ -191,30 +252,39 @@ AisEncodeDecodeTest.prototype.CheckDecode = function () {
} else {
switch (aisTest.aistype) {
case 1:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'lon', 'lat', 'rot', 'smi']);
break;
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'lon', 'lat', 'sog', 'cog']);

case 4:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'lon', 'lat']);
break;
case 21:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'shipname', 'aidtype', 'lat', 'lon']);
case 5:
this.CheckResult (test, aisTest, aisDecoded, ["shipname", 'callsign', 'destination', 'cargo', 'draught', 'dimA', 'dimB', "dimC", 'dimD']);
break;
case 9:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'lon', 'lat', 'alt', 'sog', 'cog']);
break;
case 14:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'txt']);
break;
case 18:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'lon', 'lat', 'cog', "sog"]);
break;
case 19:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'lon', 'lat', 'cog', "sog", 'shipname']);
break;
case 21:
this.CheckResult (test, aisTest, aisDecoded, ["mmsi", 'shipname', 'aidtype', 'lat', 'lon', 'txt']);
break;
case 24:
switch (aisTest.part) {
case 0: this.CheckResult(test, aisTest, aisDecoded, ["shipname"]); break;
case 1: this.CheckResult(test, aisTest, aisDecoded, ['callsign', 'cargo', 'dimA', 'dimB', "dimC", 'dimD']); break;
default: console.log ("hoop test=[%s] message type=[%d] invalid part number [%s]", test, aisTest.type, aisDecoded.part);
}
break;
case 5:
this.CheckResult (test, aisTest, aisDecoded, ["shipname", 'callsign', 'destination', 'cargo', 'draught', 'dimA', 'dimB', "dimC", 'dimD']);
break;
default:
console.log ("hoop test=[%s] message type=[%d] not implemented", test, aisTest.type);
}
}
}
}
};
Expand Down

0 comments on commit 18ac413

Please sign in to comment.