Fast forward a couple very long log entries: It works!
Setting up OpenPlotter using a Raspberry Pi 3B could not be much easier. Just download the ready made image with all necessary software already preinstalled and configured and connect PyPilot to localhost.
That's it. At least, that should have been it if the pypilot documentation would have been completed already. Unfortunately for me, I needed to read the pypilot motor Arduino code and understand AND rewrite it to be able to put all the necessary hardware together to make the "basic autopilot" work.
This is the a two part project: One is the very simple: How to install and configure OpenPlotter to be used with OpenCPN for charts with compass and GPS and PyPilot for basic autopilot functionality with waypoint tracking. The other is me re-engineering the motor.ino motor controller code to get it into a serviceable form. I also added a nice status display.
Nothing is more exciting than the first time a system comes to life and can be tested. The last two weekends, I was fortunate to have great weather to be able to run a few tests! Last week, I got course keeping to work, this week I got waypoint following to work!
The first time, things came to life I had the suspicion that my rudder command might go into the wrong direction. And sure enough, even though the the buttons for "go a little port" or "go a little starboard" were functioning at the dock, the moment I started using the automatic course keeper, the boat always steered in the wrong direction! Not sure why but my solution was simply to swap the direction on the H-bridge to get around this. Now, the "steer more starboard" doesn't work anymore but course keeping and waypoint driving works. So I don't care much. It looks like a bug in PyPilot to me because no one is using those buttons anyways. Usually everyone either steers manual or sets a course. So that's fine.
Today, I got the waypoint driving tested.
Above was the active route that I was driving at the time, below is a screen capture of the same, after the fact.
If we zoom in, you can see the boat is not following the course super accurately but it's definitely good enough to be on watch but not actively participating in the course correction of the boat:
It is really impressive how a 36 ton boat just drives from waypoint to waypoint without breaking a sweat or caring. The controller just does the job. Care must be taken, though, where to place those waypoints! DO NOT place the waypoints too close to land marks! Like buoys or similar. Since external factors will push the boat away from its desired path you will hit things if you're not careful. People have lost boats because of this! It's no joke! Watch the boat like a hawk and take over immediately the moment the slightest doubt comes up!
Here you can nicely see how my boat is still oscillating slightly and not actually going in a straight line:
I'm sure I can optimize this a little bit but I don't care much about this inconsistency right now.
I ran into a trouble when I tried to understand what was required to get the motor controller to PyPilot to work. I thought, it should be easy to just hook up an Arduino to an H-bridge that you can easily obtain from Amazon or Ebay and have the system communicate happily. However, I ran into documentation issues right from the start, couldn't find a part-list, couldn't find schematics and so on and so forth.
Turns out code and schematics are available but it took me the better part of a week to understand what's going on in the arduino code and I didn't like the schematics.
Please do not get me wrong: What the original author, Sean, put together is amazing overall! But the motor controller, which was specifically designed to run a bare metal H-bridge at 16khz by doing bit banging on the Arduino, left much to be desired in terms of ease of use and serviceability. So I rewrote major parts of it and restructured others and I hope, this version is a bit easier to understand and to get to work.
Yes, I am aware of the "not invented here" principle but I also strongly believe in opensource and feel like I did contribute to the overall scheme of things by putting this together and publishing what I have learned in the process.
Let's talk about parts:
IBT_2 fully integrated and protected H-Bridge I found to be very powerful and reliable so far
Arduino Nano Clone
160x128 pixel TFT display
Two NTC 100k thermocouples you would just order for your 3D printer
A 5Kohm potentiometer as a rudder sensor
Couple wired resistors to make a single sided board possible
Some pin headers
Several 3d printed parts
The parts above are for my rudder sensor. The gear on the left clamps around one of my two rudders, the gear on the right is bolted straight to my 5K poti.
This gives me a really nice rudder position feedback which is used for telemetry and to let PyPilot know that it shouldn't push into the MAX and MIN any longer using the rudder actuator.
As with many other projects, I usually start with a breadboard. I like having a display to be able to quickly debug the system. Like in this case, the uart port is already in use to communicate with PyPilot and cannot easily be repurposed for debugging. So I added the super high performance TFT library ST7735 to my sketch and added the display functionality.
Now I needed to put everything into one device instead of flying wires and bread boards since I wanted a more permanent installation.
I used KICad to create schematics for the board and created a layout for a single sided, easy to make at home PCB which I then milled out on me $200 PCB mill that I still love to death:
The motor controller code is located under Arduino/Motor/Motor.ino. Please let me know if you have any issues with the code. Please keep in mind that you will need the display library, unless you deactivate the display in the config.h header file.
On the Raspberry Pi 3 side, the implementation looks as follows. I integrated it into one of two helms using rubber dampeners that one would usually use for vibration isolation on camera gimbals and the like.
For a couple of weeks, I was in between jobs. I quit my old job and signed up for a new one. The time in between was a bit of an unpaid vacation and I used my time to pay myself. I always wanted to install a full blown autopilot on my boat because my girlfriend and I are boating in a nice area and either myself or her are required to be at the helm at all times. Even when there is absolutely no one around. The boat simply doesn't steer itself.
That needed to change, so I spend a couple days researching my options, initially bought an ArduPilot Rover kit and wanted to use that. However, it became clear, that ArduPilot kinda sorta uses google maps or similar to create missions but I needed something marine, like a chart plotter.
After some further googleing, I found OpenPlotter! An open source platform, compatible with the Raspberry Pi 3 - of which I have a bunch sitting on the self collecting dust. On top of the ecosystem this project created, they have an OpenCPNintegration and that has an PyPilot integration!
All together, this is a complete chart plotting, autopilot solution with the ability to integrate various sensors and other systems like AIS! Quite impressive, really, and supported by a large community - with varying success, as I will explain in a bit.
Installing OpenPlotter could not be easier as there is a NOOBS image available that contains everything needed to get things running. Just flash it to a microSD card like you would to install any Raspberry Pi OS and fire it up. Just follow the very good documentation.
I then started OpenCPN and installed some charts. I'm not entirely sure which ones I installed but there are several.
Once charts are installed and a GPS is plugged into the USB port, you need to configure it using the OpenPlotter application:
Please note, when you plug two of the same USB to Serial converters into the Raspberry Pi, you have to let the the system know to remember what port you plugged each one into. Otherwise, the system may wake up expecting the GPS to be where the PyPilot is connected.
I plugged each one in individually, configured it by giving it a name and an assignment and then hit apply. GPS will be detected automagically, PyPilot as well.
Next up is the IMU. I strongly recommend buying the suggested IMU:
I tried to get other ones to work but this one just works out of the box and need to further configuration. It's a whole $9 on Amazon so there is your big investment for this project!
It's a little funny that the IMU only shows up under PyPilot and not under I2C even though it is connected through I2C. However, if you go to I2C and then hit add, it will show it, once connected correctly, and it will also show the addresses:
There is no need to ADD the IMU to the I2C sensors. PyPilot will just take it once connected.
At this point, you have GPS and an IMU for the compass.
Now, we need to let OpenCPN know where to get all the sensor information. OpenPlotter uses an app/daemon called SignalK which is kinda like a hub apps can connect to to get access to all sensor data. This includes AIS, NMEA2k as well as NMEA0183 if all of that is actually connected to the Pi.
In OpenCPN, go into the settings and click Connections:
There are two things that you need to set up. The connection to port 10110 to gain access to the SignalK hub / multiplexer and the connection to PyPilot. In my case, everything runs on the same Raspberry Pi so localhost is the correct IP address.
Port 10110 supplies all the sensor data and needs to be configured as an input as we only want to receive information and 20220 is autopilot data (waypoints) going to PyPilot. Here, we should select the NMEA messages we want to send to PyPilot to reduce the amount of data that needs to be sent and processed:
That's kinda it! This is how I set my system up and so far it works like a charm.
What's really important is that you tune your PID controller. You probably only really need P and D and...
In order to be able to safely control the servo pump for the steering system, I need a sensor to measure the rudder position.
I modeled a simple representation of the steering system and them thought about how to add a sensor to the structure. I have seen multiple people adding potentiometers using some levers and joints but I concluded that this is too complex and non-linear.
So I selected and downloaded design files from my new favorite gear provider: KHKGears
I then modified those gears to my liking and through them onto my 3D printer. This is an amazingly simple way of getting compatible gears in almost all sizes and complexities.
The sensor is a simple 5KOhm potentiometer in a 3D printed bracket, bolted to a plywood board. If I want to, I can simply add another sensor 90degrees offset of the first one to get a differential, redundant sensor signal. This might be necessary to really be able to trust this in the long run.
Currently, these gears and brackets are printing. Unfortunately, my Chinese supplier for the potentiometer has not managed to send me the parts since FEBRUARY! So I just ordered new ones, shipped from the US.