PID controller in a robotic sailboat

Started by Scott Hemphill November 12, 2017
I'm a long time lurker, here because occasionally the math is
interesting.  But recently, I got a chance to do some embedded
programming.  I thank Tim Wescott for his intro to PID controllers.
I'll get to that bit, but first there's some background material.

There's a program at Community Boating in Boston, Mass. which since at
least 2013 has let high school students design software for controlling
robotic sailboats.  See the 3-minute YouTube video on the home page of
www.robosail.org for a quick overview of the program.

Last month, the organizers decided to hold a class for for adults.
There were a total of six two-hour evening sessions for programming,
plus a few Saturdays for sailing.  We were broken up into teams of three
people for each of four boats.  There was a fifth boat which wasn't
quite ready to go, and I sort of accidentally became my own team while
getting that boat fully equipped.

Each boat is one meter in hull length.  The height from the bottom of
the keel to the top of the mast is about two meters.  It was purchased
as an RC model sailboat, but then converted by putting an Arduino
between the onboard RC receiver and the servos for controlling the
rudder and the sails.

We're currently using an Arduino Mega, with a Grove shield.  The inputs
to the Arduino are:

  RC "throttle" control (PWM)
  RC "steering" control (PWM)
  Wind Vane on a magnetic encoder (PWM)
  Accelerometer/Magnetometer (I2C)
  GPS (UART)

The outputs are to two servos, one for the sails, and one for the
rudder.

I added an Adafruit MicroSD card breakout board to my hardware
configuration and wrote a logging module, which I used to record all the
data from the sensors, and all the info from the decision-making
functions.

I also wrote a PID controller class, which I used in two types of
circumstances.  The first was to control the angle at which the boat is
heeling over.  When you are sailing close to the direction the wind is
coming from, you have to pull the sails in all the way to make any
progress.  However, the wind tends to make the boat tip over, which you
can control by either changing the direction the boat is sailing, or
letting the sails out a bit.  I decided to use a PID controller which is
operative only when heeling over too far(*).  I picked a target heeling
angle of 30 degrees, although I'm actually using the raw Y-direction
acceleration of +/-4.9m/s.  The other place I use the PID controller
class is to control the rudder in attempting to set a heading.  The
heading can either be relative to the wind (which we can see with the
wind vane) or can be a compass direction.

The class, and the sailing season ended far too quickly.  We plan to
start again in the spring.  But here's a plot that shows the heeling
correction being applied (but not yet tuned!)

https://www.dropbox.com/s/53cadp5vtkih926/log0004.pdf?dl=0

The approximate location on the dock where I first powered on the
Arduino is (42.3592650N, 71.0734950W).  The background of the plot is
taken from Google Earth.  The large grey arrow is the average wind
direction during the trial, but during the first part of the trial, it
was more directly towards the dock.  The color of the track depends on
what command the boat code was executing(**).  It is green on the dock,
when the software is in manual mode, but it is light blue on the water,
when I switched into "sails follow wind" mode.  This is a mode where I
manually control the rudder, but the software has full control of the
sails.  The track would have been yellow if I had given it a command to
sail a given heading relative to the wind, or a compass heading.  Part
of the track is underlaid with red, indicating that the heeling
correction is being applied.  Then every 30 seconds, I added an orange
arrow giving the compass direction, corrected for magnetic variation.
This arrow doesn't always agree very well with the track, for two
reasons: first, the boat may be blown slightly sideways (which is called
"leeway"), and second, I didn't ever do a complete calibration of the
magnetometer.

Of the most interest to me is the leftmost part of the track.  After
putting the boat in the water, I set it into "sails follow wind" mode
and pushed the boat into the water.  The winds were about 12knots, which
is a lot of wind for these boats.  That part of the track has periodic
red segments, where heeling correction was being applied.  What was
happening is that the boat was heeling excessively, and the sails were
being let out.  Then the boat was standing up again, and the sails were
being pulled back in.  From the plot, it looks like there was an
oscillation with a period of about three seconds.  The PID controller
was in P-only mode, until I could gauge how much correction needed to be
applied.  Having now seen the oscillation (although evident in the plot,
I didn't notice it while sailing) I can start using the I component in
future sails.

Anyway, I just wanted to give a report on my intoduction to embedded
programming and PID controllers.

Scott

(*) Actually, I always send the heel angle info the PID controller, but
I ignore it if it calls for a negative correction, and keep the sum in
the "I" part of the calculation zero.

(**) Under manual mode, the RC "throttle" control is used to control the
sails.  When pushed forward, it lets the sails out, and when pulled
back, it pulls the sails in.  If the control is fully forward, however,
that is a signal to the microcontroller that the boat is under software
control.  The RC "steering" control is held in the center by springs.
If moved fully to the left, my software rotates a "zero" bit into a
command input register.  If moved fully to the right, my software
rotates a "one" bit into the command input register.  However, if it has
been over a second since the last bit has been received, the register is
cleared first, and this bit is the first one in the register.  If four
bits have been received, then this is interpreted as a new command to
the boat, giving me a menu of 16 different things that the boat can do.
This command will be executed whenever the boat is not under manual
control.
-- 
Scott Hemphill	hemphill@alumni.caltech.edu
"This isn't flying.  This is falling, with style."  -- Buzz Lightyear
On 11/11/2017 19:10, Scott Hemphill wrote:
> I'm a long time lurker, here because occasionally the math is > interesting. But recently, I got a chance to do some embedded > programming. I thank Tim Wescott for his intro to PID controllers. > I'll get to that bit, but first there's some background material. > > There's a program at Community Boating in Boston, Mass. which since at > least 2013 has let high school students design software for controlling > robotic sailboats. See the 3-minute YouTube video on the home page of > www.robosail.org for a quick overview of the program.
Thanks for the interesting post, Scott. I'm also a lurker here and an alumnus of Community Boating in Boston. I mentor a FIRST Robotics team in Melrose, MA and "stole" Tim's PID controller demo to help explain the concept to the students. Thanks, Tim! Best wishes, --Phil Martel
> > Last month, the organizers decided to hold a class for for adults. > There were a total of six two-hour evening sessions for programming, > plus a few Saturdays for sailing. We were broken up into teams of three > people for each of four boats. There was a fifth boat which wasn't > quite ready to go, and I sort of accidentally became my own team while > getting that boat fully equipped. > > Each boat is one meter in hull length. The height from the bottom of > the keel to the top of the mast is about two meters. It was purchased > as an RC model sailboat, but then converted by putting an Arduino > between the onboard RC receiver and the servos for controlling the > rudder and the sails. > > We're currently using an Arduino Mega, with a Grove shield. The inputs > to the Arduino are: > > RC "throttle" control (PWM) > RC "steering" control (PWM) > Wind Vane on a magnetic encoder (PWM) > Accelerometer/Magnetometer (I2C) > GPS (UART) > > The outputs are to two servos, one for the sails, and one for the > rudder. > > I added an Adafruit MicroSD card breakout board to my hardware > configuration and wrote a logging module, which I used to record all the > data from the sensors, and all the info from the decision-making > functions. > > I also wrote a PID controller class, which I used in two types of > circumstances. The first was to control the angle at which the boat is > heeling over. When you are sailing close to the direction the wind is > coming from, you have to pull the sails in all the way to make any > progress. However, the wind tends to make the boat tip over, which you > can control by either changing the direction the boat is sailing, or > letting the sails out a bit. I decided to use a PID controller which is > operative only when heeling over too far(*). I picked a target heeling > angle of 30 degrees, although I'm actually using the raw Y-direction > acceleration of +/-4.9m/s. The other place I use the PID controller > class is to control the rudder in attempting to set a heading. The > heading can either be relative to the wind (which we can see with the > wind vane) or can be a compass direction. > > The class, and the sailing season ended far too quickly. We plan to > start again in the spring. But here's a plot that shows the heeling > correction being applied (but not yet tuned!) > > https://www.dropbox.com/s/53cadp5vtkih926/log0004.pdf?dl=0 > > The approximate location on the dock where I first powered on the > Arduino is (42.3592650N, 71.0734950W). The background of the plot is > taken from Google Earth. The large grey arrow is the average wind > direction during the trial, but during the first part of the trial, it > was more directly towards the dock. The color of the track depends on > what command the boat code was executing(**). It is green on the dock, > when the software is in manual mode, but it is light blue on the water, > when I switched into "sails follow wind" mode. This is a mode where I > manually control the rudder, but the software has full control of the > sails. The track would have been yellow if I had given it a command to > sail a given heading relative to the wind, or a compass heading. Part > of the track is underlaid with red, indicating that the heeling > correction is being applied. Then every 30 seconds, I added an orange > arrow giving the compass direction, corrected for magnetic variation. > This arrow doesn't always agree very well with the track, for two > reasons: first, the boat may be blown slightly sideways (which is called > "leeway"), and second, I didn't ever do a complete calibration of the > magnetometer. > > Of the most interest to me is the leftmost part of the track. After > putting the boat in the water, I set it into "sails follow wind" mode > and pushed the boat into the water. The winds were about 12knots, which > is a lot of wind for these boats. That part of the track has periodic > red segments, where heeling correction was being applied. What was > happening is that the boat was heeling excessively, and the sails were > being let out. Then the boat was standing up again, and the sails were > being pulled back in. From the plot, it looks like there was an > oscillation with a period of about three seconds. The PID controller > was in P-only mode, until I could gauge how much correction needed to be > applied. Having now seen the oscillation (although evident in the plot, > I didn't notice it while sailing) I can start using the I component in > future sails. > > Anyway, I just wanted to give a report on my intoduction to embedded > programming and PID controllers. > > Scott > > (*) Actually, I always send the heel angle info the PID controller, but > I ignore it if it calls for a negative correction, and keep the sum in > the "I" part of the calculation zero. > > (**) Under manual mode, the RC "throttle" control is used to control the > sails. When pushed forward, it lets the sails out, and when pulled > back, it pulls the sails in. If the control is fully forward, however, > that is a signal to the microcontroller that the boat is under software > control. The RC "steering" control is held in the center by springs. > If moved fully to the left, my software rotates a "zero" bit into a > command input register. If moved fully to the right, my software > rotates a "one" bit into the command input register. However, if it has > been over a second since the last bit has been received, the register is > cleared first, and this bit is the first one in the register. If four > bits have been received, then this is interpreted as a new command to > the boat, giving me a menu of 16 different things that the boat can do. > This command will be executed whenever the boat is not under manual > control. >