Sailboat Support

@rhys @iampete . I have added a skin friction parameter to the liftDragModel plugin, which solves the reversing issue, as shown in the video (0:42 secs) and again at (3:02)

Note that I am sailing the boat manually here, TODO , get the algorithm coded and tested.

Hi @skyscraper - looks good. Another way to introduce bluff body type drag on any model or link is to add the <enable_wind> to the model or link element and add the wind effect system in the world using:

    <plugin filename="gz-sim-wind-effects-system"

This is a fairly blunt instrument though.

For some reason the changing the wind via the wind service plugin is not affecting the wind used in the wind-effect plugin. I’ll look into that. It can be set initially using the world element:

      <linear_velocity>5 5 0</linear_velocity>

but not updated at run-time.

@iampete - I’m sure this has come up before, but I’m wondering whether the main sheeting behaviour can be changed so that throttle low (rc 3 1000) corresponds to fully sheeted out and full throttle (rc 3 2000) is fully sheeted in? The reason is that on initialisation the vehicle starts with the sail fully sheeted in, where I think it may be better to initialise sheeted out. Perhaps the sheeting with throttle direction could be flipped using a param if it’s not practical or desirable to change the current behaviour for everyone?

I’m not keen to change the throttle direction unilaterally. We might be able to fix it in another way.

  • Set INITIAL_MODE to one that does not take pilot input. Hold for example. However, as soon as your RC comes online it will change mode to the one set by your mode switch.

  • The safety button functionality to disable the sail servo output. However, the only way to get out of the safe state is to press a physical button or via GCS.

  • Switch the stick to the dedicated RCx_OPTION “MainSail” for sail control, you can then reverse the stick how ever you like and use another channel for throttle. You could probably even use a transmitter switch, on a pure sailing vehicle throttle is really just stop/go. You could even map the one throttle stick to two RC channels and use one as throttle and the other for sail.

  • As you suggest we could add a “SAIL_OPTIONS” to give the option to invert sail control.

I should probably add that in the video state were changed a lot of parameters in the SITL_Models catamaran and the ASVWaves wave xml as follows.

catamaran model

  • move fins back by 90 mm
  • sail position controller plugin
    • p_gain from 0.3 to 0.75
    • i_gain from 0.1 to 0.0
  • sail lift drag plugin
    • change alpha_stall from 0.1592 to 0.4

ASVWaves waves model

  • cell_count changed to 4
  • windspeed changed to 0

TODO: I will try to document why I changed things and get back…

Still playing with the ardupilot gazebo cat sim.

Before the critique I should say that I love the Gazebo catamaran sim, but feel it needs work to get it working nicely for me anyway

For my old low end system I found that I could get a sim rate of around 95 % of real time eventually. (In the video below I think that the screen recorder takes off another 15% of realtime)

I had to make several changes.
First set the asv_wave_sim/gz-waves-models/world_models/waves/model.sdf file was modified to


Second the SITL_Models/Gazebo/worlds/catamaran_waves.sdf file was modified to


This reduces the update rate from 1 ms to 5 ms. I would have liked to try even lower rate
but something went boink in the gazebo startup output, so I left it there.

Next I modified the SITL_Models/Gazebo/config/catamaran.params file to set the default SCHED_LOOP_RATE of 50. The Ardupilot loop rate needs to be less than the sim loop rate AFAIK. Lower loop rate means potentially less power used anyway ( maybe can run it on a stm32L4 etc eventually)

I connected my Taranis RC Transmitter as a joystick and used the mavproxy joystick module.

I found that the sail controller is unusable in MANUAL mode with the default settings in the Gazebo/models/catamaran/model.sdf. The integral term means that Integral windup - Wikipedia is a real problem and makes it unusable. It takes around 30 secs to unwind at startup. I set the values to P:1 I:0 D:0 and that makes it work ok for me. Is there any need for a PID in the Gazebo sim? My feeling is that Ardupilot should control the sail position, not the sim.

For the sim itself. The boat currently travels too fast. I think ideally it would be good to model hull skin friction and wave drag, but in some ways the high speed works well since it highlights problems in control, since Gazebo models the effect of rudder throws well, so that if the model is travelling fast slight movements of the rudder have a large effect. This then throws up issues about how the Ardupilot::Sailboat handles turns for example. The direction controller probably need to take account of boatspeed? for a particular rudder angle, the torque is approx proportional to speed^2 after all.

There is a similar situation with the Heel controller. The apparent wind speed has a dramatic effect so the heel controller probably needs to have apparent wind speed as a parameter?

What is clear so far is that a catamaran is a lot more complicated than a keelboat! Anyway I plan to continue to play around with it and see if I can affect some of the issues. With the sim performance acceptable on my system, I now plan to see what I can do to the ardupilot Sailboat code
to make it work better with the sim catamaran

Here is a video of the current status, bearing in mind it is sensitive to windspeed.

1 Like

Thanks for the analysis @skyscraper.

<cell_count>4</cell_count> effectively disables the wave model which makes a big difference as wave generation involves a FFT each update step for both physics and visuals.

Is there any need for a PID in the Gazebo sim?

Yes - think of the joint controllers (which have the PIDs) as digital servos, which require a MCU onboard to ensure the servo holds at the commanded setpoint. ArduPilots various control loop controllers issue the setpoints to the servos (and these have their own PIDs that also require tuning). An autotune for the Gazebo joint position and velocity controllers would be very handy and it’s tedious to adjust them at present.

I think ideally it would be good to model hull skin friction and wave drag

There are some drag coefficients you can adjust in the hydrodynamics plugin. Try increasing these to see if you can better match expected speeds.

HydrodynamicsPlugin · srmainwaring/asv_wave_sim Wiki · GitHub (the services may not be working for Gazebo Garden - I’ll have to review if they were ported from Gazebo 11)

The apparent wind speed has a dramatic effect so the heel controller probably needs to have apparent wind speed as a parameter?

The apparent wind determines the applied sail lift, so it’s incorporated via the Gazebo physics engine and manifests as a heeling force. The apparent wind is also passed to the flight controller from the anemometer sensor and the true wind is calculated for navigation and tack angle purposes. For faster vehicles this angle has to be larger (but is not dynamic with increase wind speed - we’d need polars and dynamic PIDs for that).

@rhys, I finally got hang of the physics coefficients in ASVwave.

In the video I probably adjusted them too high, but this allows to see the effect.
lee bow is getting low as the boat is powered up at 0:25
Bearing away when powered up eventually results in a pitchpole as shown at 2:17.

Eventually there probably needs to be a pitch algorithm to complement the heel algorithm.

1 Like

Hi! What sorts of mechanisms are you all using to secure the control the rudder via a servo? Push rods? Any parts (rods, servo attachments) that help! Thank you! I’m using a Kayak rudder, and have some standard form factor servos of various sizes, but am not sure how to hook them up in a reliable way.

Maybe it will be useful to someone. I made a device to measure the speed of the boat, the data is output to the COM port.
Speed through water (STW) sensor. Boat speed measurement - ArduRover / ArduBoat - ArduPilot Discourse

I got the “Get out of Irons in Auto” algorithm working.

Code is grungy. I found it incredibly hard to actually stop the rudders moving and eventually hacked the AR_MotorsUGV class, so will have to figure out a nicer way to do it. Anyway, the algorithm works ( with the addition of some skin friction drag to the asv-sim Lift drag plugin as outlined above)

Hi, has support for any rotary encoder wind vane been added yet? Or is there any documentation for it? I’m hoping to use the AS5048B or AS5600 but am not set up to build my own code.
Also, it it not possible to just set the AS5600 in analog output mode and connect that directly to an analog input on the flight controller? It seems no one is doing this so I must be missing something.

I made a fork with AS4045 and AS5048B support forever ago – there is a comment in this thread or you can find it here: GitHub - playertr/ardupilot: ArduPlane, ArduCopter, ArduRover source

Hope that helps!

BTW I’m in Seattle and interested to help with testing and whatnot!

We have a PR for AS5048B, Add AP_AngleSensor Driver with AS5048B Support, Integrate with Windvane by DavidIngraham · Pull Request #25749 · ArduPilot/ardupilot · GitHub

I see no reason why the analog output would not work in the mean time.

I am using the standard Ardupilot analog windvane setup on this sailboat with a AS5600 board off ebay.

The only consideration is if you are using a longish wire (say more than 0.5m or so), then it is best to make sure that the impedance of the signal is low and relatively well matched, which sounds more technical than it is.

The AS5600 datasheet states that the minimum output resistive load to get a full range output, is 100,000 (100 k) ohms, which is quite a high value Search through the datasheet for ROUT_FD for the details

To make a matched impedance at each end of the wire you can use a similar circuit to this old rssi to analog circuit.

Ignore the fact it is pwm to analog, it is still basically good for this application.

Starting from the left in the diagram, for this circuit you would change the value of R1 to 100,000 ohms to conform to the AS5600 spec. R2 and R3 perform the impedance matching. You don’t need a coax cable. If you have a 3 core ( Power, ground, signal) cable then you can reckon on the wire impedance being around 100 ohms so values of R1 and R2 should match that → 100 ohms. Alternatively if you have some FPV video cable ( which would be a good choice), then its impedance is 75 ohms so that is the value to use. The capacitors C2 and C3 act to divert dynamic noise ( such as wireless pickup) to ground through the resistors. They can stay at 0.1 uF (microfarads) and you don’t need C1 since this is an analog input circuit so doesnt need that at all. R1 and C1 act as a low pass filter for the AS5600 DAC output and with values of 100,000 ohms and 0.1 microfarads I think R1,C1 gives you a cut off frequency of 16 Hz or so, which should be a lively enough response to get you started

Cool boat Skyscraper! I like the uni-rig, how do you like it?

I tried a couple of vanes using the AS5600 with analog output. I eventually went to a P3022 encoder because I couldn’t reliably/easily make the bearings and shaft part myself in the small size I wanted.

More details here

Here’s a picture of a vane with AS5600 (hooked to an arduino sending NMEA to my PC, not ardupilot)


Hi @meholden ,

I am a great fan of your Sailboat works too, especially sailing around SailDrone and your intro to Sailboat on SITL video, and sailing in strong winds. Have watched them all!

The balanced una rig works very well. The balanced nature of the rig means it is fast to repond and doesn’t use much power, so you can use a sail arm servo rather than a winch. It is also very simple to rig. I want to try it on a real life version of the Ardupilot SITL Gazebo catamaran model, mentioned above, where basically the same rig is used. Only downside is that it really needs a lathe, milling machine etc, to make the torsion bar, but that is not a problem if you have access to a makerspace near you. I have access to a fantastic set of tools at my local makerspace Swindon Makerspace as well as amazing tech support from them.

The P3022 encoder is a great solution and would definitely recommend it for a keelboat, but I opted to try and make something that is rated to IP68 , since I am working on a Catamaran which once it flips stays upside down, so I have to pay more attention to waterproofing everything.

1 Like

Thanks for the help, skyscraper, Tim, and Pete.
I managed to get the AS5600 working with its analog output. I’m using the common white AS5600 boards you see all over Amazon. Analog out only works if you remove the R4 resistor. Also, the specs don’t say it but these boards seem to work well at 5V. I’m running mine at 3.3V tho, as my FC analog rssi input is 3.3V. Using a simple RC filter with non-shielded wires and don’t seem to have any impedance matching issues yet. Will see how it goes


Tested out the new AS5600 wind vane at the lake today with @playertr and it seemed to works great!

Made some modifications to my boat including a super long bulb keel and larger rudder. Now sailing at 45 degrees off the wind seems like no problem. And its decently fast!

With pretty much all default parameters it seems to do a pretty good job running waypoint missions. Although its tough to say, because I have no experience with what a well tuned ArduPilot sailboat looks like. Moving forward, I have a few questions:

In the documentation I read “The servo min (SERVOx_MIN ) and max (SERVOx_MAX ) end points should be set such that the main wing is held in a maximum lift angle of attack on both tacks.” Is there a good way to find these values? I would assume it’s just manually sailing around and figuring out what elevator angle results in the highest speed? Would too much elevator angle result in the wing sail stalling?

Also, in high winds my boat has trouble carrying speed through a tack and sometimes starts to go backwards. Is there a feature that makes it do a 270 degree downwind turn (jibe?) instead of turning into the wind?


Nice work!

The key thing here is that lower elevator always means less lift so the heal controller does not get into positive feedback where reducing the elevator un-stalls the wing and actually heals over the more. If your after performance then yeah some manual testing would show how far you could push it before stall.

This is not currently supported, although we do have a open PR (which I need to review) for some tacking improvements. I see you have a motor setup, this should kick on automatically and help get it going again if it does get stuck in a tack.

@rctestflight The Sailboat “Get out of irons” PR is here. It is currently only designed to work for a traditional sail. Getting it to work for a wing sail shouldn’t be too difficult. Instead of sheeting out, maybe it should set the trim tab to max one way or another to get maximum drag and also use the wing to turn the boat.