jvde-github / AIS-catcher

AIS receiver for RTL SDR dongles, Airspy R2, Airspy Mini, Airspy HF+, HackRF, SDRplay and SoapySDR
https://aiscatcher.org
GNU General Public License v3.0
474 stars 76 forks source link

NMEA0183->NMEA2000 by plugin #213

Closed mpuz closed 8 months ago

mpuz commented 8 months ago

Is this task feasible using plugin or we should code cpp converter and pipe std output there and to cansend?

jvde-github commented 8 months ago

Needs to be done on the server side so embedded in the C++ code. I think others send the output to SignalK and then forward as NMEA2000. If we have a description we can add to the code I guess.

Jasper

mpuz commented 8 months ago

as of today this is one of the most complete AIS 183->2000 code i have met https://github.com/AK-Homberger/NMEA2000-AIS-Gateway/tree/main

jvde-github commented 8 months ago

Which seems to be based on this library: https://github.com/ttlappalainen/NMEA2000

Let me add to the list

jvde-github commented 8 months ago

I had a first look, but since I do not have a NMEA2000 network struggle a bit to test and implement.

mpuz commented 8 months ago

if you have a raspberry pi of any model i can order and send you Can bus controller-trancsiever and post here simple set of command which will populate your own nmea2000 network with imitation data. what i use for modelling is this controller - https://www.amazon.com/FainWan-MCP2515-Receiver-Compatible-Ard-uino/dp/B09V3C7ZBQ/ref=sr_1_1?keywords=MCP2512&qid=1704118669&sr=8-1 connected to raspberry pi gpio , this link is a sample, you need only one. it can be sourced from another online shop.

jvde-github commented 8 months ago

Can it also be tested with a virtual network like https://www.pragmaticlinux.com/2021/10/how-to-create-a-virtual-can-interface-on-linux/ ?

mpuz commented 8 months ago

yep - it works Screenshot from 2024-01-01 18-35-26

jvde-github commented 8 months ago

Let me toy around a bit...

jvde-github commented 8 months ago

Cannot see your screenshot btw

mpuz commented 8 months ago

install can-utils: sudo apt install can-utils

install canboat from github, git clone https://github.com/canboat/canboat.git build with make and make-install

Load the vcan kernel module:

sudo modprobe vcan

Create the virtual CAN interface: 

sudo ip link add dev vcan0 type vcan

Bring the virtual CAN interface online: 

sudo ip link set up vcan0

then from one terminal window: canplayer -I candump-2022-06-28_084210Part1.log -g 100

from another terminal window: candump vcan0 | candump2analyzer | analyzer

mpuz commented 8 months ago

take the dump from here: https://github.com/canboat/canboat/blob/master/samples/candumpSample3.txt

in the text editor replace slcan or whatever to the vcan0 before feeding to canplayer

jvde-github commented 8 months ago

That works. Thanks, saved me some time. For OpenCPN, are you using a plugin for NMEA2000 input?

mpuz commented 8 months ago

Nope, no plugins needed, it's internals, just go to Settings->Connections->Add connection, canSocket...choose vcan0 from dropdown, nmea2000 data type, choose show nmea debug window higher in this menu, after starting canplayer opencpn should reflect the boat position, dashboard should show gps and sog heading etc, this dump also contains AIS messages, so you should see and able to query surrounding ships

jvde-github commented 8 months ago

Problem solved, I had to upgrade my OpenCPN.... Managed to get my first messages from AIS-catcher to OpenCPN and CANboat but some discrepancies still, but conceptually seems to work thanks to your pointers on CABboat. To be continued....

jvde-github commented 8 months ago

Ok, so I have added a swith -E that sends some stuff to vcan0 (only msg 1,2,3 position report). It starts to look ok in the analyzer but opencpn seems to be struggling with it (actually also with other sources):

2024-01-01-21:53:16.121 4 240 255 129038 AIS Class A Position Report:  Message ID = Interrogated Class A position report; Repeat Indicator = Initial; User ID = "244850565"; Longitude =  4.2643980; Latitude = 52.0998268; Position Accuracy = High; RAIM = not in use; Time Stamp = 13; COG = 26.6 deg; SOG = 0.05 m/s; Communication State = 00 00 00; AIS Transceiver information = Channel A VDL reception; Heading = 40.0 deg; Rate of Turn = 0.000 deg/s; Nav Status = Restricted maneuverability; Special Maneuver Indicator = Reserved; Reserved = F0; Sequence ID = Unknown
2024-01-01-21:53:19.089 4 240 255 129038 AIS Class A Position Report:  Message ID = Scheduled Class A position report; Repeat Indicator = Initial; User ID = "246003000"; Longitude =  4.2639665; Latitude = 52.0993614; Position Accuracy = High; RAIM = in use; Time Stamp = 18; COG = 187.7 deg; SOG = 0.00 m/s; Communication State = 00 00 00; AIS Transceiver information = Channel A VDL reception; Heading = 187.7 deg; Rate of Turn = 0.000 deg/s; Nav Status = Under way using engine; Special Maneuver Indicator = Reserved; Reserved = F0; Sequence ID = Unknown
mpuz commented 8 months ago

i would take from here https://github.com/AK-Homberger/NMEA2000-AIS-Gateway/tree/main/MyAISToN2k, as it supports the following types of messages:

1-3: Class A position report -> PGN 129038.
5: Class A static and voyage related data -> PGN 129794.
14: Safety related broadcast message -> PGN 129802. This is needed for AIS SART devices!
18: Class B standard position report -> PGN 129039.
19: Class B extended position report -> PGN 129040.
24A: Class B static data part A -> PGN 129809.
24B: Class B static data part B -> PGN 129810.
jvde-github commented 8 months ago

Yes, thanks. I have done that, and first line is implemented with -E.

mpuz commented 8 months ago

Thanks, You have made the great piece of software!

jvde-github commented 8 months ago

I switched to using the NMEA2000 library but it required some fiddling to get it to work. These are the steps to test NMEA2000 output to vcan0 (or any other bus).

git clone https://github.com/jvde-github/NMEA2000_AC.git
cd NMEA2000_AC/
scripts/cmake.sh 

Now we can build AIS-catcher

git clone https://github.com/jvde-github/AIS-catcher.git
mkdir build; cd build

Now we need to specify where the NMEA2000 library (with modifications) is:

cmake .. -DNMEA2000_PATH=/home/jasper/NMEA2000_AC

You should see: -- NMEA2000: found /home/jasper/NMEA2000_AC/src/libnmea2000.a /home/jasper/NMEA2000_AC/src in the output of cmake.

make

And you can run AIS-catcher like this:

./AIS-catcher -E

or

./AIS-catcher -E vcan0

In another terminal, you can read NMEA2000 messages:

candump vcan0 | candump2analyzer | analyzer
2024-01-02-20:11:04.827 6  23 255  60928 ISO Address Claim:  Unique Number = 1; Manufacturer Code = ERROR; Device Instance Lower = 0; Device Instance Upper = 0; Device Function = 195; Device Class = Communication; System Instance = 0; Industry Group = Marine; Arbitrary address capable = 1
2024-01-02-20:11:05.094 4  23 255 129038 AIS Class A Position Report:  Message ID = Scheduled Class A position report; Repeat Indicator = Initial; User ID = "255915649"; Longitude =  4.2447681; Latitude = 52.2598648; Position Accuracy = Low; RAIM = not in use; Time Stamp = 3; COG = 11.5 deg; SOG = 0.06 m/s; Communication State = 00 00 00; AIS Transceiver information = Channel A VDL reception; Heading = 237.0 deg; Rate of Turn = 0.000 deg/s; Nav Status = Under way using engine; Special Maneuver Indicator = Reserved; Spare = 07; Sequence ID = Unknown
2024-01-02-20:11:05.295 4  23 255 129038 AIS Class A Position Report:  Message ID = Interrogated Class A position report; Repeat Indicator = Initial; User ID = "244850565"; Longitude =  4.2647567; Latitude = 52.1001015; Position Accuracy = High; RAIM = not in use; Time Stamp = 3; COG = 12.6 deg; SOG = 0.01 m/s; Communication State = 00 00 00; AIS Transceiver information = Channel B VDL reception; Heading = 40.0 deg; Rate of Turn = 0.000 deg/s; Nav Status = Restricted maneuverability; Special Maneuver Indicator = Reserved; Spare = 07; Sequence ID = Unknown

Done: msg types 1,2,3,4,5, to be done msg > 5. Feedback welcome.

mpuz commented 8 months ago

thanks, i will try tomorrow as soon as i get to my setup thing....what branch do you use for testing?

jvde-github commented 8 months ago

I included the support in the Docker build as well. Details are here the -net=host is needed to pass on the network interfaces from the host to the docker. Not ideal, but avoids that you have to do a more complicated build like above.

jvde-github commented 8 months ago

thanks, i will try tomorrow as soon as i get to my setup thing....what branch do you use for testing?

Sorry, you can use the edge of the main branche. So normal installation as per above extended instructions to include NMEA2000 support.

jvde-github commented 8 months ago

Ok, so if you are in the AIS-catcher directory after the clone (or pull) you can also build with NMEA2000 support as follows:

./build.NMEA2000 

This will first download the necessary library and then builds AIS-catcher with the library included

mpuz commented 8 months ago

built on armbian with no errors (./build.NMEA2000), started with -E and did not find vcan0 ... i would recommend to set default cansocket as can0 as any hardware CAN bus adapter connected appears as can0 in the system while anyone can run "-E vcan0" for self feeding going to leave for several hours running as at winter our pond has few actors crushing ice, will report tomorrow, running hardware bus model with two raspis - one with aiscatcher+rtlsdr usb dongle feeding and second with canboat analyzer receiving

jvde-github commented 8 months ago

Thanks. Hope we are on the right track!

In the meantime I have also implemented NMEA2000 input for messages 1-3, 5 (others not yet). So, running in one terminal:

canplayer -I candumpSample3.txt 

and in another:

AIS-catcher -i vcan0 
AIS-catcher (build Jan  8 2024) v0.55-275-g69c71243
(C) Copyright 2021-2023 jvde-github and other contributors
This is free software; see the source for copying conditions.There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Opening NMEA2000 network "vcan0"...
opening socket
NMEA2000: Connected
!AIVDM,1,1,,A,13flrH0000OrIFdJJ2n=M7e80000,0*04 ( MSG: 1, REPEAT: 0, MMSI: 250428000)
!AIVDM,1,1,,A,14SeST000IOqUOfJHHAkqC3d0000,0*2C ( MSG: 1, REPEAT: 0, MMSI: 305882000)
!AIVDM,1,1,,A,13flrH0000OrIFdJJ2nMbWeH0000,0*4B ( MSG: 1, REPEAT: 0, MMSI: 250428000)
!AIVDM,1,1,,A,33P;n8A000Or7MrJGLhqPD<60000,0*19 ( MSG: 3, REPEAT: 0, MMSI: 235075105)
!AIVDM,2,1,0,A,53Jsir02=tfcTP7?C7@p5HTu>1@5E9E>2222221?H@OF:6MU0ND1@Qh`,0*1F ( MSG: 5, REPEAT: 0, MMSI: 229569000)
!AIVDM,2,2,0,A,888888888888880,4*22 ( MSG: 5, REPEAT: 0, MMSI: 229569000)

If this all works and is useful we can expand on it. Cheers, Jasper

jvde-github commented 8 months ago

Ok, uploaded a new experimental version which directly uses the NMEA2000 library without tweaks. I need to put some effort in coding/decoding the PGNs but slowly getting there.

To build on Linux including NMEA2000 support:

./build.NMEA2000

To read AIS messages from vcan0:

AIS-catcher -i vcan0 

And to put messages on the bus:

AIS-catcher -I vcan0

Was an interesting experiment. Thanks for raising the concept and pointing me in the right direction.

jvde-github commented 8 months ago

And they are at least received by OpenCPN :-) Screenshot from 2024-01-11 19-58-09

mpuz commented 8 months ago

I have it in the opencpn as well, even with old commit - this is a real can bus and my own bluetooth esp32 gateway with opencpn getting nmea2000 over air

<GREEN>14:43:19 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 100  Desc: AIS Class A position report

<GREEN>14:43:42 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:46:39 (N2000) ...Repeated 2 times

<GREEN>14:46:39 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: AIS Class A position report

<GREEN>14:46:42 (N2000) ...Repeated 2 times

<GREEN>14:46:42 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:47:19 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: AIS Class A position report

<GREEN>14:47:41 (N2000) ...Repeated 3 times

<GREEN>14:47:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:48:00 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: AIS Class A position report

<GREEN>14:48:42 (N2000) ...Repeated 4 times

<GREEN>14:48:42 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:48:51 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: AIS Class A position report

<GREEN>14:49:41 (N2000) ...Repeated 6 times

<GREEN>14:49:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:49:59 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: AIS Class A position report

<GREEN>14:50:41 (N2000) ...Repeated 7 times

<GREEN>14:50:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:51:00 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 100  Desc: AIS Class A position report

<GREEN>14:51:41 (N2000) ...Repeated 6 times

<GREEN>14:51:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:51:59 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 100  Desc: AIS Class A position report

<GREEN>14:52:41 (N2000) ...Repeated 4 times

<GREEN>14:52:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:52:59 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 100  Desc: AIS Class A position report

<GREEN>14:53:38 (N2000) ...Repeated 3 times

<GREEN>14:53:38 (N2000) PGN: 129794 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: AIS static data class A

<GREEN>14:53:41 (N2000) ...Repeated 2 times

<GREEN>14:53:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:54:00 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 100  Desc: AIS Class A position report

<GREEN>14:54:42 (N2000) ...Repeated 4 times

<GREEN>14:54:42 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins

<GREEN>14:56:40 (N2000) ...Repeated 1 times

<GREEN>14:56:40 (N2000) PGN: 129038 Source: nmea2000 /dev/rfcomm0 ID: 100  Desc: AIS Class A position report

<GREEN>14:56:41 (N2000) PGN: 126993 Source: nmea2000 /dev/rfcomm0 ID: 23  Desc: No description. Not used by OCPN, maybe passed to plugins
mpuz commented 8 months ago

thanks to your great project - now everyone with old raspberry and cheap can controller can have his own nmea2000 compat receiver feeding ais data to boat network. Kudos!

jvde-github commented 8 months ago

I learned something, thanks for that. Did some more tweaking of the PGN definitions (proper dealing of undefined numbers) and added support for some more input PGNs. I will leave it at that, unless there is more feedback from folks.

I will close this issue, many thanks for the testing and the pointers. Jasper

mpuz commented 4 months ago

Hello Jasper! I have just bumped onto this repo - https://github.com/kvhnuke/esp32-rtl-sdr/tree/main, does that mean demodulation is possible on the esp32?

jvde-github commented 4 months ago

I have no experience with the esp32. Computational wise do you know how it compares with the raspberries? To get a sense.

mpuz commented 4 months ago

you cant compare directly, the chip by itself is not as mighty as the rpi, but it does not carry the burden of OS, gui and all other stuff, it's just Xtensa dual-core (or single-core) 32-bit LX6 microprocessor, operating at 160 or 240 MHz and performing at up to 600 [DMIPS] and has some (from 2 to 4, some even 16) megabytes of flash memory

jvde-github commented 4 months ago

Perhaps that should be just enough. Seems to be a bit of a hassle to get it to work and build on such a device?