ARDUINO MARINE AUTOPILOT DOCUMENTATION
PROJECT: WILE E COYOTE AUTOPILOT (WECA) (Wile E Coyote is my boats name)
OBJECTIVE: Build an Arduino based autopilot that will steer my 40 foot sailboat. Steering a compass course, a GPS course or a wind angle course.
STATUS: I recently completed a 40 mile course using the GPS mode with the course laid out in commercial navigation software (Nobeltec) on my PC. It also steers a compass course.
WECA uses a 9 degree of freedom gyro compass (MinIMU9 from Pololu) for the heading sensor. It reads GPS data from a couple of sources. The rudder is operated with a small DC motor driving a hydraulic pump and piston (already existed).
WECA uses two Arduinos. The main processing is on a MEGA 2560 and the GPS is done on an UNO. Two boards are used because MinIMU9 runs at 50 Hz and the GPS at 1 Hz. The GPS was significantly degrading the IMU9 processing. The GPS data is transmitted from the UNO to the MEGA once a second but the transfer is handled in a few milliseconds and within the 50 Hz structure of the IMU9. The transfer is done using Bill Porter’s Easy Transfer library.
WECA has an LCD (4 lines of 20 characters) and a telephone keypad for input and output.
The code uses the following simple PID.
PID_Output = Gain1 *( Gain2 * Heading_Error – Gain 3*Bearing_Rate)
Heading_Error = Heading_to_Steer – Heading (from the IMU9) (proportional term).
Bearing_Rate is the horizontal plane component of the three axis bearing rate from IMU9 (differential term). No integral term is used.
In Mode 1 the WECA steers a compass course. Line the boat up in the desired direction and press the “1” button to steer that heading. This captures the current heading as the Heading_to_Steer. Note that attempts to get an absolute calibration of the IMU9 compass have not been very successful. So WECA is going where it is pointed. The Keypad can be used to increment the course 1 or 10 degrees left or right.
Mode “2” is GPS. The concept used is to use to get a Course to Steer (CTS) to the next waypoint and the actual Course Over Ground (COG) to generate a Heading_to_Steer (HTS) and then use the PID to steer that heading. Note that Heading to Steer is not equal to Course to Steer because of compass error and cross currents. The idea is to adjust the Heading to Steer so the Course Over Ground is equal to the GPS generated Course to Steer. The following form is used.
Define tracking error as the difference between the heading the boat is pointing and the actual course the boat is traveling.
tracking_error = HDG – COG.
The tracking error is a fairly constant term, it changes as currents change or compass error varies on different headings. One problem with this is that when the boat changes course to a new waypoint the heading changes quickly whereas the course over ground changes slowly so the constant nature of the tracking error is not preserved. To correct this a low pass filter is used to get heading that responds about the same rate as the course over ground.
Low Pass Filtered Heading,
HDG_LPF = .999 * HDG_LPF + .001 * HDG
tracking_error = HDG_LPF – COG, note the whole tracking error could be low pass filtered also.
Finally, the GPS heading to steer is:
HTS = CTS + tracking_error
Note, WECA does not yet have a cross track error correction. I erroneously assumed that the Nobeltec PC navigation software output a course to steer (CTS) that included a course correction to get back on the original track. So this is the next area for development. There is no easy solution because the cross track error transmitted by Nobeltec ($GPAPB sentence) is only reported to 0.1 nautical miles (600 feet). The alternative approach is to capture the next waypoint position and then do all of the navigation calculations in the Arduino. The difficulty with this approach is that in NEMA 0183 protocol the waypoint information is only sent once when the waypoint is activated and it will be hard to be certain the data is captured.
Mode “3” is sailboat TACK mode and the keypad will initiate a 90 degree (adjustable) turn left or right.
Mode “4” will be wind angle but has not been implemented yet. It will use an approach similar to the GPS approach where the wind angle will provide a reference for a heading to steer but a heading error term will be needed. The main challenge will be to read the Raymarine Seatalk data to get the wind angle.
The boat already has a hydraulic steering autopilot. This is a DC 12V motor driving a small hydraulic pump connected to a piston. To change directions the motor is reversed. There is a solenoid (12V) valve between the two hydraulic lines. It is open when the autopilot is off. This allows the hydraulic cylinder to move when steering manually. When the autopilot is placed in the steering mode the solenoid is closed. The autopilot is a Wagner, built in Vancouver in 1983. It steers a compass course but not a GPS route. The pump motor has a built in controller. WECA taps into the control wires and has switches to select either autopilot as the control source.
The GPS uses RS232 serial output at 4800 baud. RS 232 is a +/- 5 V signal. The Arduino uses TTL which is 0 V, +3.3V. Therefore the GPS input needs to be converted which is done using a Sipex SP232E chip. This was an easy straight forward activity. Get the IC chip add 5 capacitors, plug the RS 232 and GPS into one side and the Arduino into the other.
MinIMU9 heading sensor:
The Pololu MinIMU9 has nine degrees of freedom, three axis fluxgate compass sensors, three axis accelerometers, and three axis gyro angular rate sensors. All of the coding is provided in the Pololu library. I added coding to extract the horizontal bearing rate, (regardless of sensor orientation).
PS If there is interest I can post the code but I don’t know the best way to do this.