Raspberry-Pi On Board for Embarked Research and Technology. Aka just ROB. |
If java is not there (or not in the right version), install JDK 11:
pi $ sudo apt-get update
pi $ sudo apt-get install openjdk-11-jdk
- See here (all OS's)
- See here (all operating systems)
The Raspberry Pi is a small, cheap, but fully featured Linux computer that consumes a ridiculous amount of energy. There is no need
to have a generator to fulfill its energy needs !
It can be installed on board, and run 24x7, reading and computing data (from your NMEA Station, GPS, external breakout boards, etc), and do whatever
is needed with them (log them, transform them, forward them to other softwares or clients, etc).
The code presented here is designed to run even of the smallest versions of the Raspberry Pi (Raspberry Pi Zero), that have 512Mb of RAM, and it works (it has been tested in the real world).
The scripts presented in this repo are written for bash
shell.
As such, they run on Linux, Mac OS, and Windows 10+ (I was told so, did not test).
And by the way, features that are not Raspberry Pi specific (like GPIO header management and access) will run on
any computer or OS that supports bash
, java
, and if needed, python3
. Installation of
external module and packages are done through apt-get
or so. This utility has equivalents on other OS's than RaspiOS.
In other words:
All the soft presented here will run on a Raspberry Pi, but also on other platforms, like Linux laptops, Mac, Windows, etc.
Read again the above π.
To keep this project compatible with as many Raspberry Pi models as possible, we kept the Java code compatible with
Java 8. Some syntax improvements would be possible, if Java 11 was the only one in the picture, but they're - for now - commented.
This is done intentionally.
The code presented in this repo is designed to be as flexible and customizable as possible.
The execution of your final product(s) will depend on the way you configure the builds and runtime configuration files.
Examples will be provided, but again, as examples.
There is no one-click definitive install in this repo, the packaging of what you will deploy and run depends on what you want.
You might want:
- A Multiplexer to read NMEA data from several sources (your NMEA station, several breakout boards), log them for replay or analysis, and forward a readable version of some of computed data to a small screen next to the chart table.
- The features above, plus a web interface, reachable from other devices (laptops, tablets, cell-phones) connected on the network emitted by the Raspberry Pi where the multiplexer is running.
- Have some astronomical, tide, routing, and fax processing features available from a web interface (Tide and astronomical almanac publication - in pdf, routing based on your polars, display GRIBs and weather faxes on the same canvas, etc).
- ... etc. Your imagination is the limit.
If anything is unclear about the way to customize your configuration, if more examples are needed, please use the issues page of this repo.
But pllllease, keep in mind that this is OpenSource..., not free consulting. You have to know what you're doing.
This being said, all comments, requirements, suggestions, ideas, etc, are most welcome.
- Get Started, fast
- Package for Prod example
- Sample implementation and demos, REST services, Web Interfaces, and more.
- Run from a Docker image (the fastest way for the impatients, with more demos).
There is in this repo a repository
branch, that can be used as a Maven repo. See here for details.
The goal here is to be able to fulfil the computing needs of a navigator with a Raspberry Pi (we'll discuss the different models later).
The Raspberry Pi (see https://www.raspberrypi.org/ and https://www.raspberrypi.com/) is a small and cheap single-board computer, running a clone of Linux, it's hard drive is an SD card, its power consumption is low, and
it comes with a GPIO header that can be used to read sensors, or feed actuators.
The more I use it, the more I like it.
One major requirement here is to be able to do everything at sea - that means with NO Internet access, nothing in the cloud.
There can be a network on board, emitted by one machine (...like the Raspberry Pi), with several other machines connected on it to visualize or manage the data going back and forth,
but definitely NO Internet access. We could call this "flake" βοΈ computing π
this requires no satellite, no 5G antenna,... nothing but a WiFi dongle. Veeeeery low β¬οΈ - if not null - carbon footprint, this may sound interesting to some.
There is indeed quite a difference between "network access" and "internet access".
A network can be a local one, like the one emitted by a Raspberry Pi, accessible to whoever is in the same boat.
Some operations (like the build of the project π...) would require an Internet connection. But definitely, we tried here to keep those requirements to a bare minimum. The runtime part can indeed happen offline (off-Internet).
NMEA Data management, routing calculation (based on GRIBs and faxes you can receive with an SSB), almanac publication, all this can be done with on-board resources only.
At sea, the Raspberry Pi can run 24x7, and its power consumption remains ridiculous.
This project is opening several possibilities, from simple data logging to celestial almanac computation and publication. Depending on what you want or what you need,
a Raspberry Pi Zero might be enough. I've tested it, the basic NMEA-multiplexer
runs fine on it.
Now, if you want to fully featured navigation server (as in the module RESTNavServer
), then you might want to beef-up your config, with a Raspberry Pi Model 4...
When we will be using extra components (like Atmospheric data sensors, small screens), you will find links to some providers of such devices, this will give an idea of the budget you'll need (it's usually ridiculous).
And another cool thing is that we will provide a Web interface for data rendering, as well as for the administration of the system.
Those will mostly rely on some REST services, illustrated by many examples.
As it is now, you might need to like playing with bits and pieces of code to get to where you want to be... I'm working on it, I'm trying to bring it to a wider audience.
We intend here to deal with the data provided by an NMEA Station (Boat Speed, Wind data, ...), a GPS, and maybe additional boards (like Atmospheric sensors like BME280, very cheap).
We want to be able to:
- Forward the read and calculated data to other software programs (like OpenCPN, SeaWi, ...)
- Calculate True Wind (Speed and Direction)
- Calculate current, in real time
- Calculate tides - and publish tide almanacs
- Calculate celestial data - and publish celestial almanacs
- Calculate routing - based on GRIB files (receivable at sea, yes. I did it)
- Log everything for future replay
- Provide all kinds of user interfaces, accessible from laptops, tablets, cell-phones...
- Provide the way to come up with your own extensions and custom User Interfaces.
- ...and all this kind of things.
All this, running on a Raspberry Pi.
Note: for now, we deal only with
NMEA0183
, as - as far as I know - no GPS deals (yet) withNMEA2000
. Working on it.
AIS Data are emitted usingNMEA0183
. There is some support for AIS sentences (work in progress).
This project came to light after Raspberry Coffee.
Raspberry Coffee
is mainly written in Java (and other JVM languages), and can communicate with sensors and actuators using PI4J, itself relying on WiringPi.
In a navigation environment, NMEA data usually come through a Serial Port, which does not require much in term of additional software (we use here
librxtx-java
, easy to install and to use, and it seems not to present restrictions regarding the JDK version). Sensors can be welcome on board though, to add atmospheric data to the existing NMEA flow, like Pressure, Air Temperature, Humidity, etc. This is where extra Java frameworks could be needed, to deal with the Raspberry Pi's GPIO header the sensors are connected on.
I have written many drivers for those boards (sensors and actuators), in Java, to enable native communication with the code.
And then, Wiring Pi became deprecated, and subsequently, PI4J V1 as well. Too bad.
Other frameworks are available for this kind of operations, PI4J V2 was released, diozero is also available...
But those guys have restrictions on the version of the JDK, they seem to need at least a JDK 11, not supported on small Raspberry Pis like the Raspberry Pi Zero W
. Too bad, again.
So, there is something smart to come up with here π€.
Here is a thing: for all the sensors and actuators, we usually have some code, written by the board provider - usually in Python. And this is the code that has been re-written in Java, to enable a native communication with those boards, based on the frameworks mentioned before.
If a framework becomes obsolete, or if it needs upgrades, then so does the Java code...
We want here to find a way to get rid of this kind of nasty occurrences.
So, an idea would be to keep this code as it is - it's working in Python, and the board provider will take care of updates, if needed - and find a way to establish a communication between this Python code and Java...
The reason why I originally went for Java is because Java is a programming language, as opposed to Python, which sounds more - to me - like a scripting language.
I suspect that this last sentence may cause some eyebrows to raise, but I still believe it.
Java is designed to scale, it has amazing debug capabilities (including remote debugging), it scales, it can be distributed, it is natively object-oriented, it's recursive (Java knows about Java), it's compiled - and not interpreted, it can deal with concurrent accesses, etc.
Python is great, and keeps getting more and more popular, for good reasons. One of them being that it may look simpler than Java, and closer to the mindset of a scientist (like a mathematician).
If you look at those charts ranking the different languages popularity, you would see Python's popularity keeping rising, and - for example - C's popularity stagnating at bottom of the scale... But still, at least 90% of the Operating Systems are written in C. There must be a reason.
Popularity and efficiency might not be always in sync... Riding a cab and building a car are two different things.
There is obviously a lot to say about that, but I'll stop here; this could turn into an endless conversation (ping me if you want).
But now, I want to bridge a gap between Java and Python. Let's be positive.
We will give TCP and REST a try, for this kind of Python-to-Java communication.
This will also minimize the amount of dependencies to deal with (and eventually, the size of the archives).
In short, we would wrap the Python code into some sort of TCP or REST server, which itself can be accessed from Java, natively.
TCP and REST are cool enough to be language agnostic.
And on top of that, several parts of the code deserved some cleanup, and this is also an opportunity to minimize and consolidate the number of dependencies to external libraries. For example, for the Java-to-JSON part, only Jackson is now used.
The web pages and scripts do not rely on any external framework (no JQuery, Underscore, etc). It's 100% organic. It's using vanilla ES6 features, like Promises.
Note: Those JavaScript frameworks (JQuery, Underscore, React.js, etc) are great tools. The goal here is to minimize the dependencies, as well as the final volume of the code and archives.
And we will try to implement Consumers, Forwarders and Computers as pluggable components, to facilitate the required customizations.
At the root, we have some generic building blocks, like
http-tiny-server
common-utils
and other similar modulesSerial-IO
andSerialRxTx
The Java-TCP-Python
module gathers the different experiments done to establish
a bridge between Java and Python. It's more like a playground.
In the astro-computer
directory, there are two modules for celestial calculations (in several
languages: Java, Scala, Python, C, go, ES6, and some Jupyter Notebooks).
All those things will come together in the directory raspberry-sailor
.
It contains REST wrappers (usable from and by the http-tiny-server
) around the features we will need, like NMEA Parser,
Tide calculations, Routing (and GRIB management), etc.
The main building block is the NMEA-multiplexer
. This one can run as it is, but it can also be enriched end extended.
Note: The
RaspberryPythonServer
contains "some" Python TCP and REST servers for sensors and actuators data access.
It provides REST access to the data it deals with, so all its features can be accessed through HTTP (from Services, and/or Web pages).
Illustrations of the ways to put it to work are available under MUX-implementations
.
Many languages can take care of back-end computing...
Front-end UI is more tricky. Swing is a Java option, Python has other possibilities, same for C..., but they're all different.
So, to make everyone happy, we will here do all the back-end computing in whatever language you want, and make it REST-accessible, with - when required - a JSON payload.
A web-enabled REST client (HTML5, ES6, CSS3) will be able to take care of displaying those data; all you need is a (recent) browser.
No need to deal with Android, iOS, Windows..., the goal here being to simplify the data access, maintenance and portability.
Note: We will see later what can be done with Docker.
Programming languages used here are Java, and in some cases Python. The Web UI is done in pure HTML5/ES6/CSS3, without any external framework.
The build is done using gradle
.
If you're not familiar with those tools and techniques, check out the GET_STARTED page.
When building on small boards, do not hesitate to exclude some demanding tasks, like
$ [...]/gradlew shadowJar -x :astro-computer:AstroComputer:compileScala
You might also want to exclude some tests (look into their code for details)
$ [...]/gradlew clean build -x :raspberry-sailor:NMEA-multiplexer:test
- Read NMEA data, log, forward, process
- Notebooks, how NMEA Parsers work
- Build your own deviation curve
- Build your own polars (in progress)
- Read and render GRIB files and faxes (in progress)
- Routing (in progress)
- Celestial Almanacs publication
- Tide Tables publication
- Navigation and Correction tables publication
- Implementation and customization examples:
- Basic
- RESTNavServer, with many examples
- https://saillogger.com/
- https://github.com/itemir/rpi_boat_utils
- https://gpsd.gitlab.io/gpsd/
- https://celnav.de/ (my favorite)
- http://www.tecepe.com.br/nav/
- http://navastro.free.fr/ (in French)
- Get Started: For dummies
- Hints and Tips here
This is a vast topic.
Again, we are targeting here all kinds of machines, from big ones, to the smallest Raspberry Pi Zero - which can indeed take care of the job.
The thing is that a Raspberry Pi Zero might not be abe to take care a routing, almanac publishing, and such demanding tasks.
This is why we do not provide here the biggest possible config with all possible options, as it might not be suitable for your targeted environment.
Each case is a particular case, there is no "one-size-fits-all" config here...
We will see later if Docker could be a way to approach this problem, by preparing several Docker images, suitable for different hardware configurations. More to come.
- WiP, look into to.prod.sh, for now, and the USE_CASE page.
Also, by using TCP and REST, all sensors and actuators using those protocols can be distributed, they do not have to be located on the same board. You can very well have the GPS and NMEA data read from one Raspberry Pi somewhere, the Magnetometer (like an LSM303) somewhere else, and all those guys feeding the NMEA-multiplexer, located on another board.
Wow! Vaaaast topic too...
- Docker Images ? For now, see here.
- Docker can run on a Raspberry Pi, this would simplify deployment and installation steps.
- Jupyter Notebooks to see how components work.
Jupyter Notebooks were originally developed for Python, but they're now also available for pretty much any language that comes with a REPL (Read Execute Print Loop), like Java (9+), Scala, NodeJS, ...
Some notebooks are available in the NMEA-Parser
project. More to come.
Check out the number of lines of code, per categories
$ ./line.counter.sh
And more to come... See you again soon.