Message passing for an Autonomous Sailing vessel

Hi everyone, i’m from a group of honours students at Adelaide University and our Honours project involves building an autonomous sailing vessel.

Heres an example of an existing one roboat.at/en/home/

We’re using QNX neutrino as our main operating environment but none of us has any experience in it and our supervisors knowledge of it is very limited.
Ive come up with the message passing architecture based on how i think QNX works, but not entirely sure about it. Im just wondering if theres anyone on the forums nice enough to have a look over to see if im even on the right track.

The attached image shows a top-down hierarchy of processes with maneuver execution being the overall goal of the rest of the processes

A short run down of the little boxes are

Maneuver execution - The resultant commands which will move the vessel in the required direction. They are sent to a separate microcontroller which will control actuators
Short course path planning - Sets a short course which the vessel will follow. This includes the tacking and such for anyone who knows anything about sailing. Its will follow the general long term path given
Long term Path planning - The overall route which the vessel will take. Ie go from this port to this waypoint to this final destination
Localisation - Calculates the absolute position (latitude and longitude) and direction (yaw) of the vessel
GSM/Wifi comms - Any received data or data to be sent is from this process
And the others are fairly self explanatory.

Thanks in advance for any feedback

Chris

Sounds like an interesting project. Your diagram seems pretty well thought out. Some questions.

  1. What is Maneuver-Execution getting from Short-Course-PP, a desired location? If not, why is ME also asking Localization for (presumably) the current location? If so, why is Short-Course-PP asking for wind direction and not ME? I would think that ME would get current location, desired location and then need wind direction to turn the rudder/boat to head for desired location.

  2. What is IMU data.

  3. It seems that Localization is polling IMU, GPS and Compass data.
    For the presumably slow real-time requirements involved this is probably just fine, however did you consider having these programs wait for a change and then report this by sending to Localization?

  4. I don’t really understand what GSM and wifi communications is.
    I can see why it would send messages to Long-Term-PP but not Localization.

Having read this, I thought I might recount an educational tale that I was involved in.
I may be preaching to the choir but here goes.
About 2-3 years ago I met someone on this board who was building an autonomous
vehicle for entry in the Grand Darpa Challenge.
I ended up driving down to their development location and spending a week with them.
They had spent about 2-3 years developing the vehicle.
Developing the hardware for the vehicle that is.
My best guess is that they had spent maybe 2-3 months with the software before I got there,
and they had a week’s deadline to get the vehicle running around a track on its own.
Needless to say they had under-estimated the software development effort by a lot.
I’ve run into this phenomenon before with mechanical and electrical engineers.

The winning vehicle that year came from Sanford. They had contracted out the hardware
and spent all their time on the software. Let me repeat that in harsher words, the project
was the software.

Ok, off my pedestal for now.
Good luck.

Hi maschoen, i guess i didnt give enough information for you to get a clear picture, i just didnt want to post the whole document ive written.

1)Maneuver Execution is getting a set path from short course path planning. It then will calculate all the required actions needed to follow this path. It needs localisation data to know where it is relative to the short course path. As the short course path planning process will deal will creating a path and tacking patterns it needs the wind direction. The maneuver execution process just follows this path

2)The IMU data will be from accelerometers and gyros and interpreted in order to give a position relative to a previous position. This will be combined with GPS data using Kalman filters to give a more accurate absolute position

3)This is one part im not entirely sure about. What i want to happen is for the localisation process to give a position everytime we require it and to do that we would just pull data from certain buffers where the sensor data is located. One thing that cant be seen in the diagram is that the the IMU data will need to be taken multiple times for every GPS point, ie. 10 IMU values for every GPS value.

  1. The gsm/wifi communcations are just two ways were are communicate with the vessel. We require that the vessel sends it position to us so the comms will pull data from the localisation process but we also want to be able to change the course it is sailing on, thus we have to be able to send waypoints into the long term path planning section. The long term path planning section will stay constant unless we send it these waypoints.

Just one thing. I was wondering if my thought process is correct in saying that as the overall output we want is the Maneuver execution, we can run that program, and it will request data from the short course path planning process. As the short course path planning needs other data before it has an output it will then request the data from the localisation and long term path planning blocks, which in turn need to request data from other blocks?
Ive got a nagging feeling in the back of my head saying i should be doing things the other way around but i dont know if thats just because im new to QNX.

Oh and weve been told a few times by our supervisors that the software for this project is going to make or break it haha. We do have 4 mechatronic engineers working on it over the year so hopefully we can get some decent results.

Thanks

Chris

Hello,

This look ok to me. I seach for dead lock but you did a good job there. Overall the design seems QNX friendly, as the S/R/R concept is present.

As maschoen said you might consider having the “driver” program ( GPS, etc) use notification, either though the io_notify mecanism or through your own custom message. Personnaly I use custom message go give more flexibility. That is my “register” message will say, please update me every second or please update me when this or that data changes.

What your diagram does not show is if you will be using raw messages or use the POSIX interfaces. The POSIX interfaces takes a little more planning but can give extra tools. For example for the GPS module the GPS interface can live under /dev/GPS (for example) this from the shell you could do cat </dev/GPS and it will output the coordinates. Or you can get more fancy and have the GPS driver support multiple path /dev/GPS/time /dev/GPS/coordinates /dev/GPS/stratum etc…

One thing also to note is that because you’ve modularized everything it will make development much easier, it will also allow for simulation. For example the GPS module could run without a real GPS and instead take a file as input. Or you can programaticaly make it send @impossible@ path to really test your system and make it crash proof.

If by “pull from buffers” you mean read shared memory, I recommend against it. Using message passing here makes things much more robust, along with removing any need for mutex’s in the shared memory.

If the concern is that waiting for Localization to get all the data is time consuming and you don’t want to lockup the requesting program, then do the MsgSend() in a separate thread.

Well it sounds good to me. One thing you didn’t mention is collision detection. Do you do any of that?

Anyway, the issue im having is deciding which way the flow of messages should flow. Ive put a brief description of each message send in the diagram and the advantages and disadvantages ive thought of for each method, but it comes down to responsiveness vs efficiency.

It would be great if anyone can give me an opinion on whether one way is better than the other or its fairly arbitary as im finding it hard to find any documentation on this sort of thing from other projects.

Feel free to ask me any questions about the diagram or my project in general.

Thanks

Chris

Wasn`t the same question asked a few weeks ago?

Well that was more confirming that the concept would work where as now its refining the ideas and picking the best once. It would be good just to get an expert opinion on how most systems are set up to justify my choice in my final report.

I get the feeling from your diagrams that method one uses polling while method two is “new data” driven.

In most real time systems I would generally prefer the non-polling method.
In your system I think things might be otherwise.
I imagine that your system could re-calculate the next action thousands of times a second. But a sail boat probably needs at least tenths, if not actual seconds to meaningfully respond to any changes.
That being the case, I would use other considerations as to the decision.

I guess I also have to add that your diagram has some ambiguity involved. I’m not sure what is a thread or a single threaded process vs. what is a process. The distinction is that a thread sending a message can be blocked, whereas a multi-threaded process can send messages but as a whole, not be blocked.

Thanks for the reply.
So would you recommend using method 2 then? Even though there isnt much point of having a 100Hz refresh rate do you think it still be the better way to do it?

With the diagram, each block is represented as a different process. The maneuver execution process is single threaded but im not sure about path planning and localisation as they’re still in the design stage.

Also, about the multi threaded process, as multi-threaded processes wont block would you recommend making all the processes multi-threaded with all message sends in seperate threads from any calculations/actions?

Well I’m being intentionally a little vague since I don’t really have much to work with. To clarify,

  1. Yes I do recommend method 2
  2. Normally I would recommend against 1 because it seems to poll
  3. Because of the slow poll rate In your particular application I would not rule out method 1. You might have other reasons for you preferring it that I don’t know about.

Okay thanks for your help.
The reason we were considering the first method was as it seemed to most efficient in terms of processing and thus overall power consumption and also as it would make sure that the execution of movement never gets blocked.
I do see that using the data driven structure would be more meaningful in a Real-time operating system so we will go with that.

Thanks again