Over the past few weeks, we, the software team, have designed and begun implementing a new software architecture. The reason for this is that, during the past two years, we have learned that the previous architecture for our code had numerous shortcomings. The emergent behavior paradigm, while allowing for greater flexibility on a short time scale, made it very difficult to plan ahead; for example, making intelligent tacking decisions was very difficult. Time crunches and team member turnover prevented us from resolving this and other problems in an elegant fashion, and solutions often took the form of poorly documented hacks.
This year, we have a more experienced and larger software team, as well as a testing platform and more time to test. We also have a functional codebase to fall back on if worst comes to worst. As a result, we are taking the chance to learn from our past issues and start over from scratch with code that is cleaner, more understandable, more modular, and more suited for making dynamic sailing decisions. The old code was built around relatively little data. We only had an AIRMAR sensor, which gave us averaged wind velocity, GPS location, and tilt data. This year, we will have all of that plus information about a variety of forces on the boat, including those on the mast, sails, stays, and rudder, to help us properly tune our sails and react to emergency situations.
The architecture we have created is heavily influenced by other work on robotics at Olin, with the goal of utilizing institutional experience. The architecture is loosely modeled after the organization of an organic brain.
We have more divisions within the code to allow for easier organization as well as greater modularity – ideally, this will make it easier to drop in different behaviors and different sensors without breaking what we already have. In addition, this allows us to break the data flow down, reducing the chances for race conditions, where variables are read from and written to simultaneously and other problems with accessing data all over the place. This will also allow parts of the code that need to run more quickly to do so by isolating parts of the code that do not need to run constantly or take a lot of processing time in their own loops.
While this gives us a good idea of how it works on a large scale, in order to check whether it would achieve our goals, we need to have a better understanding of how it would actually decide what to do with the rudder and sails.
We looked more specifically at what factors needed to go into our decision making and how the decisions are assessed and adjusted. We decided on a sail arbiter and a rudder arbiter, with main and jib sail sub-arbiters within the sail arbiter. Each takes in multiple sensor inputs and combines their determinations in some fashion we have not yet decided. The sails’ behaviors, however, are slightly more complicated than depicted in the image. There are three steps to set and tune the sails. 1) set the sails to the theoretically ideal angle based on the wind speed/direction. 2) Wait a couple seconds for the system to settle and use the arbiter (as depicted above) to tune the sails. 3) check to see if the boat is tilting too much and adjust the sails accordingly. This process will continue to repeat while the boat is not taking and going in a relatively consistent direction.
When we tack, we have found that the combining process does not work as well, causing many smaller tacks or half-hearted attempts instead of full tacks at logical times. It can also cause the rudder and sail to be uncoordinated, which is not the best when tacking. As a result, when a higher-level process decides that we need to tack, we have a tracking behavior that overrides both arbiters.
If you have any feedback or suggestions for us we would love to hear them! I would also be happy to answer any questions you many have. You can email us at email@example.com. Thanks in advance!