The Software...

by Dermot Tynan in Microtransat

Posted on Tuesday, March 19, 2013 at 08:00

72e2928d 8685 4e66 89e8 764c7fdaabf2
The FreeBSD Daemon

I've been asked recently, about the software platforms used on board Beoga Beag. This seems as good a time as any, to talk about the various layers. As mentioned previously, the lower layer is a custom board, running an ATmega8 Atmel processor. The software (Igor and Otto) is custom-written in C for the boat.

The upper layer (Mother) is an Alix board, running FreeBSD. Technically it's nanoBSD, which is a scaled-down, shrink-to-fit version of FreeBSD for embedded platforms. The system boots off an 8GB Compact Flash. As the file systems are mounted read-only, except for one partition used for logging and saving state, the machine boots quite quickly. The start-up code runs a set of Ruby scripts which perform the various actions on board. The most important of these (from a systems perspective) is the mother process. This is used to communicate with the low-level boards, and also to execute the various scripts. One script interrogates the GPS and begins accumulating time and position data, which is saved to the log. This is the gps-reader module. Another script uses the log to analyse the position data, and compute the best course to sail. This is the navigator module. Yet another module uses the log data to gather messages to be sent at every quantum (currently every six hours, unless an issue arises). This is the communicator module. Each module will perform its function, and notify mother when it would like to execute again. When all are done, mother will notify Igor when the machine should be powered on again, and will then shut down the main processor.

When Igor detects that the main processor power has dropped, he will pull the plug on Vcc2.

I had originally intended to do an elaborate message-passing system, with some components written in Ruby, and others in C, but it turns out that Ruby is sufficient for pretty much everything, and is a lot easier to debug. It also allows me to use distributed Ruby to communicate between the various modules. Using Drb with C isn't impossible, but it's not trivial either.

In order to debug the navigation system, I have written a Ruby module for the boat. It includes functions for computing distance and bearing to a lat/long (from a given position), computing a new position using a distance and bearing, calculating hull speed based on a true wind angle, and calculating the best course to get to the next mark. By writing this as a module with a number of Ruby classes, I can then write programs which import this module and exercise the functions. The simulator is one such script. It's only about 20 lines of Ruby. It reads a set of waypoints, and then calls the various instance methods to navigate the boat. It simulates the boat position by taking the computed course, and advancing the boat position accordingly. It also saves each position separately, so it can be used to generate a KML file for Google Earth. That allows me to view the track on Google Earth and try and figure out why the boat did what it did.

The communication system is relatively straightforward as well. It sends a 250 byte message every six hours. Messages are queued up based on their priority and type. Only one message of each type will be sent, starting with the most recent. If all of the priority-0 messages have been queued up for transmission, and there is space left in the buffer, priority-1 messages will be sent, and so on. Priority 0 messages are sent immediately, whereas the other message priorities are only sent during scheduled transmissions (at 00:10, 06:10, 12:10 and 18:10 each day). A priority 0 message isn't just for emergencies (like "we're sinking!!") it's also used when a waypoint is reached. The communicator scans the log directory for any P0 messages, and if one is found, it begins preparing a communication with Mission Control. Otherwise, it will wait for the scheduled time slot.

All log messages, from P0 through to P7 are logged on the CF card, for future reference. If the log partition fills up, older P7 logs are deleted up until the present day. After that, P6 logs are deleted, starting with the oldest. Hopefully we won't have to delete too many logs. There's an argument for deleting the P0 and P1 logs because they've most likely been sent out and received already.

If anyone has any questions about the upper-level systems (or indeed any of the systems!), feel free to ask in the comments.

Current Missions
Recent Posts
Blog Categories